Skip to content

docs(security): formalize required_for + fallback-authenticator composition#2591

Merged
bokelley merged 3 commits into
mainfrom
bokelley/required-for-fallback
Apr 20, 2026
Merged

docs(security): formalize required_for + fallback-authenticator composition#2591
bokelley merged 3 commits into
mainfrom
bokelley/required-for-fallback

Conversation

@bokelley

Copy link
Copy Markdown
Contributor

Summary

Formalizes how required_for (9421 signing requirement) composes with bearer/API-key/mTLS fallback authenticators. Clarifies the normative rule that the training-agent migration (#2582) hit head-on:

  • Unauthenticated caller on required_for op → reject (unchanged).
  • Unsigned but bearer/API-key/mTLS-authed caller → accept. The fallback is what the verifier advertised as sufficient; required_for doesn't retroactively invalidate the verifier's own authenticator config.
  • Malformed signature → still blocks fallback (downgrade defense, unchanged).
  • Sellers that want unconditional signing MUST disable their fallback authenticators for that operation — required_for is one lever in the auth chain, not an override.

What changed

  • docs/building/implementation/security.mdx:
    • Verifier-checklist preamble: clarifies the rejection branch requires both "no signature" AND "no other valid credential."
    • New subsection "Composition with fallback authenticators" with the full normative rule and a "why this composition, not strict" explanation.
    • required_for capability definition: cross-reference and inline clarification.

No wire / schema changes. Pure spec clarification.

Test plan

  • npm run test:unit passes
  • npm run typecheck passes
  • Mintlify renders the new subsection and anchor resolves correctly
  • Anchor #composition-with-fallback-authenticators works from the two cross-reference sites

Closes #2586.

🤖 Generated with Claude Code

…sition

`required_for` governs the signature requirement relative to a caller's
credential path, not absolutely. Adds explicit rules for:

- Unauthenticated callers on required_for ops: reject (unchanged).
- Unsigned but bearer/API-key/mTLS-authenticated callers: accept. The
  fallback is what the verifier advertised as sufficient.
- Malformed signatures: still block fallback (downgrade defense, unchanged).
- Sellers wanting unconditional signing MUST disable fallback authenticators
  for the operation — required_for does not override a verifier's own
  authenticator config.

Updates the verifier-checklist preamble, adds a "Composition with fallback
authenticators" subsection, and cross-references from the required_for
capability definition. No wire/schema changes.

Closes #2586.
@github-actions

github-actions Bot commented Apr 20, 2026

Copy link
Copy Markdown
Contributor

Schema Link Check Results

Commit: 85f1324 - docs(security): promote signing-enforcement postures to admonition block

⚠️ Warnings (schema not yet released)

These schemas exist in source but haven't been released yet. The links will be broken until the next version is published:

  • https://adcontextprotocol.org/schemas/v3/enums/specialism.json
    • Schema exists in latest (source) but not yet released in v3
    • Action: This link will work after next 3.x release is published

To fix: Either:

  1. Wait for the next release and merge this PR after the release is published
  2. Use latest instead of a version alias if you need the link to work immediately (note: latest is the development version and may change)
  3. Coordinate with maintainers to cut a new release before merging

- Restructure verifier-checklist preamble bullet with explicit THEN +
  Oxford comma in credential list (resolves parsing ambiguity on the
  three-part conjunction).
- Lift the "unauthenticated" definition into a lead-in paragraph before
  the normative bullets so the term scope is unambiguous.
- Add a worked per-caller-flag example ("signing_onboarded" flag on
  agents[] entries) so sellers know how to implement strict enforcement
  per-tenant without global required_for.
- Rephrase "forces signing" → "rejects bearer-only requests from" to
  match what the verifier actually does.
- Rephrase "unsigned unauthenticated callers" (read as typo) to
  "callers presenting no credential at all."
- Add one sentence clarifying warn_for semantics unchanged — preempts
  the "does warn_for now mean required_for?" question.

No normative change; review feedback on PR #2591.
@bokelley

Copy link
Copy Markdown
Contributor Author

Reviewed against upstream issue #2586 and against adcp-client PR #669's requireSignatureWhenPresent({ requiredFor }) semantics. The docs text matches the SDK encoding — specifically the unsigned-bearer-authed-passes / unsigned-unauthenticated-rejects-with-request_signature_required / malformed-sig-blocks-fallback rules. No spec↔SDK drift. Ship it.

One phrasing nit worth a follow-up commit:

Promote the "signing-unconditional" callout. The paragraph currently covers three composition modes in flowing prose. The operative rule for sellers who want enforcement — "configure the fallback authenticator to reject all other credentials" — is the one most likely to be skimmed past on a first read, and it's the rule whose violation turns the whole required_for declaration into security theater. A bold admonition block or a three-bullet list ("to enforce signing unconditionally, do X; to prefer signing but accept bearer, do Y; to treat signing as advisory, do Z") would prevent the "I declared required_for but bearer-authed callers pass — is that correct?" bug report.

Not blocking — the information is all present and accurate. Just reorder for skimmability.

Migration note for our training agent

Our buildAuthenticator already matches the spec (unsigned-bearer-authed passes, credentials-absent throws request_signature_required). No behavior change needed on adoption of adcp-client 5.7. We just replace the hand-composed fallback-with-required_for-check with requireSignatureWhenPresent({ requiredFor, resolveOperation }) once adcp-client PR #669's Blocker 2 is fixed (the pre-check not firing on fallback-throws path).

Reviewer nit: the operative rule for sellers who want enforcement was
buried in flowing prose. Promoted to a Warning admonition with three
explicit postures (strict / prefer-signing / advisory) so implementers
can't skim past it.

No normative change.
@bokelley bokelley merged commit 128840d into main Apr 20, 2026
16 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Spec: formalize required_for + credential-fallback composition semantics

1 participant