Unverified Commit 37f6d55a authored by Hong Minhee's avatar Hong Minhee
Browse files

Rename and document firstKnock option for HTTP signature spec



Rename FederationOptions.defaultHttpMessageSignaturesSpec to firstKnock
and add comprehensive documentation for the double-knocking mechanism
when communicating with unknown servers.

- Rename defaultHttpMessageSignaturesSpec to firstKnock throughout codebase
- Add JSDoc documentation to FederationOptions.firstKnock
- Document firstKnock option in docs/manual/federation.md
- Update CHANGES.md with detailed description of the feature

Co-Authored-By: default avatarClaude <noreply@anthropic.com>
parent 7e656903
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -19,8 +19,17 @@ To be released.
     -  `InProcessMessageQueue.nativeRetrial` is `false`.
     -  `ParallelMessageQueue.nativeRetrial` inherits from the wrapped queue.

 -  Added `FederationOptions.firstKnock` option to configure the HTTP
    Signatures specification used for the first signature attempt when
    communicating with unknown servers.  This implements the [double-knocking]
    mechanism for better compatibility across different ActivityPub servers.
    Defaults to `"rfc9421"` (RFC 9421: HTTP Message Signatures), with fallback
    to `"draft-cavage-http-signatures-12"` if the first attempt fails.
    [[#252] by Fabien O'Carroll]

[#250]: https://github.com/fedify-dev/fedify/issues/250
[#251]: https://github.com/fedify-dev/fedify/pull/251
[#252]: https://github.com/fedify-dev/fedify/pull/252


Version 1.6.1
+1 −1
Original line number Diff line number Diff line
@@ -746,7 +746,7 @@ Available options are:
`rfc9421` (default)
:   [RFC 9421]: HTTP Message Signatures, which is the final revision of
    the specification and is recommended, but not yet widely adopted
    in the fediverse as of May 2025.
    in the fediverse as of June 2025.

If the first signature attempt fails, Fedify will automatically try the other
specification format, implementing the [double-knocking] technique described in
+30 −0
Original line number Diff line number Diff line
@@ -310,6 +310,36 @@ an object for options.
>
> However, `Context.lookupObject()` method is affected by this settings.

### `firstKnock`

*This API is available since Fedify 1.7.0.*

The HTTP Signatures specification to use for the first signature attempt
when communicating with unknown servers. This option affects the
[double-knocking] mechanism.

When making HTTP requests to servers that haven't been encountered before,
Fedify will first attempt to sign the request using the specified
signature specification. If the request fails, it will retry with the
alternative specification.

Available options are:

`"draft-cavage-http-signatures-12"`
:   [HTTP Signatures], which is obsolete but still widely adopted in
    the fediverse as of May 2025.

`"rfc9421"` (default)
:   [RFC 9421]: HTTP Message Signatures, which is the final revision of
    the specification and is recommended, but not yet widely adopted
    in the fediverse as of May 2025.

Defaults to `"rfc9421"`.

[double-knocking]: https://swicg.github.io/activitypub-http-signature/#how-to-upgrade-supported-versions
[HTTP Signatures]: https://datatracker.ietf.org/doc/html/draft-cavage-http-signatures-12
[RFC 9421]: https://www.rfc-editor.org/rfc/rfc9421

### `outboxRetryPolicy`

*This API is available since Fedify 0.12.0.*
+18 −1
Original line number Diff line number Diff line
@@ -679,7 +679,24 @@ export interface FederationOptions<TContextData> {
   */
  skipSignatureVerification?: boolean;

  defaultHttpMessageSignaturesSpec?: HttpMessageSignaturesSpec;
  /**
   * The HTTP Signatures specification to use for the first signature
   * attempt when communicating with unknown servers. This option affects
   * the "double-knocking" mechanism as described in the ActivityPub HTTP
   * Signature documentation.
   *
   * When making HTTP requests to servers that haven't been encountered before,
   * Fedify will first attempt to sign the request using the specified
   * signature specification. If the request fails, it will retry with the
   * alternative specification.
   *
   * Defaults to `"rfc9421"` (HTTP Message Signatures).
   *
   * @see {@link https://swicg.github.io/activitypub-http-signature/#how-to-upgrade-supported-versions}
   * @default `"rfc9421"`
   * @since 1.7.0
   */
  firstKnock?: HttpMessageSignaturesSpec;

  /**
   * The retry policy for sending activities to recipients' inboxes.
+6 −7
Original line number Diff line number Diff line
@@ -231,7 +231,7 @@ export class FederationImpl<TContextData>
  inboxRetryPolicy: RetryPolicy;
  activityTransformers: readonly ActivityTransformer<TContextData>[];
  tracerProvider: TracerProvider;
  defaultHttpMessageSignaturesSpec?: HttpMessageSignaturesSpec;
  firstKnock?: HttpMessageSignaturesSpec;

  constructor(options: FederationOptions<TContextData>) {
    super();
@@ -385,7 +385,7 @@ export class FederationImpl<TContextData>
            specDeterminer: new KvSpecDeterminer(
              this.kv,
              this.kvPrefixes.httpMessageSignaturesSpec,
              options.defaultHttpMessageSignaturesSpec,
              options.firstKnock,
            ),
            tracerProvider: this.tracerProvider,
          }));
@@ -400,8 +400,7 @@ export class FederationImpl<TContextData>
    this.activityTransformers = options.activityTransformers ??
      getDefaultActivityTransformers<TContextData>();
    this.tracerProvider = options.tracerProvider ?? trace.getTracerProvider();
    this.defaultHttpMessageSignaturesSpec =
      options.defaultHttpMessageSignaturesSpec;
    this.firstKnock = options.firstKnock;
  }

  _initializeRouter() {
@@ -647,7 +646,7 @@ export class FederationImpl<TContextData>
        specDeterminer: new KvSpecDeterminer(
          this.kv,
          this.kvPrefixes.httpMessageSignaturesSpec,
          this.defaultHttpMessageSignaturesSpec,
          this.firstKnock,
        ),
        tracerProvider: this.tracerProvider,
      });
@@ -1102,7 +1101,7 @@ export class FederationImpl<TContextData>
            specDeterminer: new KvSpecDeterminer(
              this.kv,
              this.kvPrefixes.httpMessageSignaturesSpec,
              this.defaultHttpMessageSignaturesSpec,
              this.firstKnock,
            ),
            tracerProvider: this.tracerProvider,
          }),
@@ -2845,7 +2844,7 @@ export class InboxContextImpl<TContextData> extends ContextImpl<TContextData>
            specDeterminer: new KvSpecDeterminer(
              this.federation.kv,
              this.federation.kvPrefixes.httpMessageSignaturesSpec,
              this.federation.defaultHttpMessageSignaturesSpec,
              this.federation.firstKnock,
            ),
          }),
        );