Skip to content

Implement RFC 9421 §5 Accept-Signature challenge-response negotiation#626

Open
2chanhaeng wants to merge 19 commits intofedify-dev:mainfrom
2chanhaeng:main
Open

Implement RFC 9421 §5 Accept-Signature challenge-response negotiation#626
2chanhaeng wants to merge 19 commits intofedify-dev:mainfrom
2chanhaeng:main

Conversation

@2chanhaeng
Copy link
Contributor

Summary

Implement Accept-Signature challenge-response negotiation (RFC 9421 §5)
for both inbound and outbound sides of Fedify's federation layer.

Related issue

Changes

  • Added RFC 9421 §5 Accept-Signature negotiation for both outbound and inbound paths. On the outbound side, doubleKnock() now parses Accept-Signature challenges from 401 responses and retries with a compatible RFC 9421 signature before falling back to legacy spec-swap.
  • On the inbound side, a new InboxChallengePolicy option in FederationOptions enables emitting Accept-Signature headers on inbox 401 responses, with optional one-time nonce support for replay protection.

Benefits

  • Enables standards-based signature negotiation with servers that
    require specific RFC 9421 parameters
  • Provides inbox operators an opt-in mechanism to enforce signature
    requirements and replay protection
  • Maintains full backward compatibility — opt-in on inbound,
    transparent on outbound

@issues-auto-labeler issues-auto-labeler bot added activitypub/interop Interoperability issues component/federation Federation object related component/inbox Inbox related component/signatures OIP or HTTP/LD Signatures related labels Mar 16, 2026
@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request significantly upgrades Fedify's HTTP signature handling by integrating RFC 9421 §5 Accept-Signature challenge-response negotiation. This enhancement improves interoperability with servers requiring specific signature parameters and provides a robust mechanism for inbox operators to enforce signature requirements and replay protection. The changes ensure full backward compatibility while enabling modern, standards-based federation.

Highlights

  • RFC 9421 §5 Accept-Signature Negotiation: Implemented RFC 9421 §5 Accept-Signature challenge-response negotiation for both inbound and outbound federation, enhancing interoperability and security.
  • Enhanced Outbound doubleKnock(): The doubleKnock() function now parses Accept-Signature challenges from 401 responses and retries with a compatible RFC 9421 signature before falling back to legacy spec-swap.
  • New Inbound InboxChallengePolicy: Introduced an InboxChallengePolicy option in FederationOptions to enable emitting Accept-Signature headers on inbox 401 responses, with optional one-time nonce support for replay protection.
Changelog
  • CHANGES.md
    • Documented the addition of RFC 9421 §5 Accept-Signature negotiation for both outbound and inbound paths, including doubleKnock() enhancements and the new InboxChallengePolicy.
  • docs/manual/inbox.md
    • Added documentation for enabling Accept-Signature challenge emission on inbox 401 responses via inboxChallengePolicy, detailing nonce support.
  • docs/manual/send.md
    • Documented the outbound Accept-Signature negotiation process, including how doubleKnock() handles challenges and its fallback mechanisms.
  • packages/fedify/src/federation/federation.ts
    • Defined the InboxChallengePolicy interface and integrated it into FederationOptions to configure inbound challenge behavior.
  • packages/fedify/src/federation/handler.ts
    • Implemented the logic for emitting Accept-Signature headers in 401 responses and added nonce verification for replay protection in the inbox handler.
  • packages/fedify/src/federation/middleware.ts
    • Updated FederationKvPrefixes to include acceptSignatureNonce and integrated the inboxChallengePolicy into the FederationImpl class.
  • packages/fedify/src/sig/accept.ts
    • Added new utilities for parsing, formatting, validating, and fulfilling Accept-Signature headers, including interfaces for members and parameters.
  • packages/fedify/src/sig/http.ts
    • Modified signRequest to support RFC 9421-specific options and updated doubleKnock to perform Accept-Signature challenge-response negotiation.
Activity
  • The author, 2chanhaeng, implemented the RFC 9421 §5 Accept-Signature negotiation.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request implements RFC 9421 §5 Accept-Signature challenge-response negotiation for both inbound and outbound federation. The changes are comprehensive, touching on the federation handler, HTTP signature utilities, and adding new modules for Accept-Signature header processing. The implementation includes robust handling of 401 challenges, nonce-based replay protection, and maintains backward compatibility with legacy spec-swapping. The addition of extensive unit and integration tests ensures the new functionality is well-covered. My main feedback is a suggestion to improve the robustness of the nonce generation logic, specifically regarding base64 encoding.

@codecov
Copy link

codecov bot commented Mar 16, 2026

Codecov Report

❌ Patch coverage is 90.95745% with 34 lines in your changes missing coverage. Please review.
✅ All tests successful. No failed tests found.

Files with missing lines Patch % Lines
packages/fedify/src/sig/http.ts 80.46% 20 Missing and 5 partials ⚠️
packages/fedify/src/sig/accept.ts 95.90% 3 Missing and 2 partials ⚠️
packages/fedify/src/federation/handler.ts 96.55% 0 Missing and 4 partials ⚠️
Files with missing lines Coverage Δ
packages/fedify/src/federation/middleware.ts 95.53% <100.00%> (+<0.01%) ⬆️
packages/fedify/src/sig/mod.ts 100.00% <100.00%> (ø)
packages/fedify/src/federation/handler.ts 81.99% <96.55%> (+1.68%) ⬆️
packages/fedify/src/sig/accept.ts 95.90% <95.90%> (ø)
packages/fedify/src/sig/http.ts 77.10% <80.46%> (+1.69%) ⬆️

... and 1 file with indirect coverage changes

🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@2chanhaeng
Copy link
Contributor Author

@claude review

@2chanhaeng
Copy link
Contributor Author

@codex review

@chatgpt-codex-connector
Copy link

To use Codex here, create a Codex account and connect to github.

@dahlia
Copy link
Member

dahlia commented Mar 16, 2026

@codex review

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds RFC 9421 §5 Accept-Signature challenge/response negotiation support to Fedify, both for outbound delivery retries (client side) and for inbox 401 challenge emission with optional nonce-based replay protection (server side).

Changes:

  • Added Accept-Signature parsing/formatting/validation + challenge fulfillment utilities and exported them from @fedify/fedify/sig.
  • Extended RFC 9421 signing to support custom label/components and optional nonce/tag, plus implemented outbound doubleKnock() challenge-driven retry.
  • Added inbound InboxChallengePolicy to emit Accept-Signature challenges and (optionally) store/verify one-time nonces in KV.

Reviewed changes

Copilot reviewed 13 out of 13 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
packages/fedify/src/sig/mod.ts Re-exports new Accept-Signature helpers and RFC 9421 signing options type.
packages/fedify/src/sig/http.ts Adds RFC 9421 signing options (label, components, nonce, tag) and implements Accept-Signature-driven retry in doubleKnock().
packages/fedify/src/sig/http.test.ts Adds tests for RFC 9421 signing options and doubleKnock() Accept-Signature retry behavior.
packages/fedify/src/sig/accept.ts New module implementing Accept-Signature parsing/formatting/validation and challenge fulfillment.
packages/fedify/src/sig/accept.test.ts New tests covering Accept-Signature utilities.
packages/fedify/src/federation/middleware.ts Wires InboxChallengePolicy and KV prefix into federation plumbing.
packages/fedify/src/federation/handler.ts Emits Accept-Signature challenges on inbox 401s and adds nonce issuance/verification logic.
packages/fedify/src/federation/handler.test.ts Adds tests for inbox challenge emission and nonce lifecycle (issue, consume, replay).
packages/fedify/src/federation/federation.ts Introduces the InboxChallengePolicy public API in federation options.
examples/astro/deno.json Adjusts TS module resolution for the Astro example.
docs/manual/send.md Documents outbound Accept-Signature negotiation behavior.
docs/manual/inbox.md Documents inbound inbox challenge emission and nonce replay protection.
CHANGES.md Changelog entry for the new Accept-Signature negotiation features.

Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 0bc621b0bb

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@dahlia dahlia requested a review from Copilot March 17, 2026 05:28
@dahlia
Copy link
Member

dahlia commented Mar 17, 2026

@codex review

@dahlia
Copy link
Member

dahlia commented Mar 17, 2026

/gemini review

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request implements RFC 9421 §5 Accept-Signature challenge-response negotiation for both inbound and outbound federation. It introduces a new inboxChallengePolicy option to enable emitting challenges on 401 responses. On the outbound side, it handles these challenges by retrying requests with the required signature parameters. The implementation is robust, with comprehensive tests covering various scenarios, including security considerations like nonce replay and bypass attacks. The documentation has also been updated accordingly. My review includes one medium-severity suggestion to remove potentially unsafe fallback logic in the nonce verification function to improve security and clarity.

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds RFC 9421 §5 Accept-Signature challenge/response negotiation support across both outbound delivery (doubleKnock) and inbound inbox verification, including optional one-time nonce replay protection backed by KV storage.

Changes:

  • Added Accept-Signature parsing/formatting/validation helpers and exported them from the sig module surface.
  • Extended RFC 9421 signing to support configurable signature label, covered components, and metadata parameters (nonce, tag), and taught doubleKnock() to honor Accept-Signature challenges before legacy spec-swap.
  • Added InboxChallengePolicy to optionally emit Accept-Signature challenges on inbox 401 responses, with optional nonce issuance + verification, and documented the feature.

Reviewed changes

Copilot reviewed 13 out of 13 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
packages/fedify/src/sig/mod.ts Re-exports new accept.ts utilities and Rfc9421SignRequestOptions for public API access.
packages/fedify/src/sig/http.ts Adds RFC 9421 signing options (label/components/nonce/tag) and implements outbound Accept-Signature-driven retry in doubleKnock().
packages/fedify/src/sig/http.test.ts Adds tests for RFC 9421 signing options and doubleKnock() challenge handling/fallback behavior.
packages/fedify/src/sig/accept.ts New module for Accept-Signature structured field parsing, formatting, request validation, and fulfillment logic.
packages/fedify/src/sig/accept.test.ts Unit tests for parsing/formatting/validation/fulfillment of Accept-Signature.
packages/fedify/src/federation/middleware.ts Wires InboxChallengePolicy + KV prefix into federation plumbing.
packages/fedify/src/federation/handler.ts Emits inbox Accept-Signature challenges on signature-verification 401s and adds nonce issuance/verification logic.
packages/fedify/src/federation/handler.test.ts Adds inbox challenge/nonce issuance, consumption, replay-prevention, and bypass-regression tests.
packages/fedify/src/federation/federation.ts Introduces InboxChallengePolicy in public federation options/types.
examples/astro/deno.json Adjusts TypeScript module resolution to nodenext for the Astro example.
docs/manual/send.md Documents outbound Accept-Signature negotiation behavior in doubleKnock().
docs/manual/inbox.md Documents inbound inbox Accept-Signature challenge emission + nonce option.
CHANGES.md Changelog entry for new inbound/outbound Accept-Signature negotiation support.

When deno check processes the full workspace, examples/astro's
tsconfig.json (extending astro/tsconfigs/strict) sets moduleResolution
to "Bundler".  Since the Astro example imports @fedify/fedify, this
setting leaks into the compilation context of accept.ts, causing
@fxts/core's internal ReturnPipeType to incorrectly resolve pipe's
return type.
Override moduleResolution to "nodenext" in examples/astro/deno.json so
the Astro tsconfig no longer affects how @fxts/core's types resolve.
- Remove unsafe fallback in `verifySignatureNonce` that scanned all
  Signature-Input entries when verifiedLabel is absent; non-RFC 9421
  signatures do not support nonces so the check is skipped entirely
- Defer nonce consumption until after `doesActorOwnKey` to avoid burning
  nonces on requests that will be rejected due to actor/key mismatch
- Enforce a minimum component set (method, target-uri, authority) in `buildAcceptSignatureHeader` regardless of caller-supplied components
@dahlia
Copy link
Member

dahlia commented Mar 17, 2026

@codex review

@dahlia dahlia requested a review from Copilot March 17, 2026 11:43
@dahlia
Copy link
Member

dahlia commented Mar 17, 2026

/gemini review

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request implements RFC 9421 §5 Accept-Signature challenge-response negotiation for both inbound and outbound federation, which is a significant enhancement for interoperability. The changes are well-structured, with new functionality encapsulated in dedicated modules and helper functions. The implementation correctly handles security considerations, such as deferring nonce verification to prevent replay attacks and misuse. The addition of comprehensive tests, including those for potential security vulnerabilities, is excellent and ensures the robustness of the new features. The documentation has also been updated clearly. Overall, this is a high-quality contribution.

Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 4660cbba35

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds RFC 9421 §5 Accept-Signature challenge/response negotiation to improve HTTP Signatures interoperability: outbound deliveries can retry using server-provided signature requirements, and inbound inboxes can optionally emit Accept-Signature challenges (including one-time nonces) on signature-verification 401s.

Changes:

  • Added Accept-Signature parsing/formatting/fulfillment utilities and re-exported them from the sig module.
  • Extended RFC 9421 request signing to support custom signature label, covered components, and nonce/tag parameters; outbound doubleKnock() now performs a challenge-driven retry before legacy spec-swap.
  • Added inbound InboxChallengePolicy to emit Accept-Signature challenges and (optionally) verify/consume replay-protection nonces stored in KV; updated docs and changelog.

Reviewed changes

Copilot reviewed 13 out of 13 changed files in this pull request and generated 7 comments.

Show a summary per file
File Description
packages/fedify/src/sig/mod.ts Re-exports new Accept-Signature utilities and RFC 9421 signing options as public API.
packages/fedify/src/sig/http.ts Implements RFC 9421 signing options (label/components/nonce/tag), exposes verified signature label, and adds outbound Accept-Signature negotiation in doubleKnock().
packages/fedify/src/sig/http.test.ts Adds tests for RFC 9421 signing options and outbound Accept-Signature negotiation behavior.
packages/fedify/src/sig/accept.ts New module to parse/format/validate Accept-Signature and fulfill challenges safely.
packages/fedify/src/sig/accept.test.ts Unit tests for Accept-Signature parsing/formatting/validation/fulfillment.
packages/fedify/src/federation/middleware.ts Threads new KV prefix and inbox challenge policy option through federation implementation.
packages/fedify/src/federation/handler.ts Emits Accept-Signature on selected 401s and adds nonce issuance/verification using KV storage.
packages/fedify/src/federation/handler.test.ts Adds tests for challenge emission and nonce issuance/consumption/replay behavior.
packages/fedify/src/federation/federation.ts Introduces InboxChallengePolicy in federation configuration API.
examples/astro/deno.json Updates TS module resolution setting for the Astro example.
docs/manual/send.md Documents outbound Accept-Signature negotiation behavior.
docs/manual/inbox.md Documents enabling inbound Accept-Signature challenges and optional nonce enforcement.
CHANGES.md Changelog entry for Accept-Signature negotiation (inbound and outbound).

2chanhaeng and others added 3 commits March 18, 2026 16:55
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

activitypub/interop Interoperability issues component/federation Federation object related component/inbox Inbox related component/signatures OIP or HTTP/LD Signatures related

Projects

None yet

3 participants