Skip to content

fix(signing): use only the directory keys with a valid signature - #1544

Open
KonstantinMirin wants to merge 2 commits into
adcontextprotocol:nextfrom
KonstantinMirin:fix/wba-directory-keys-follow-draft
Open

KonstantinMirin wants to merge 2 commits into
adcontextprotocol:nextfrom
KonstantinMirin:fix/wba-directory-keys-follow-draft

Conversation

@KonstantinMirin

Copy link
Copy Markdown
Collaborator

This pull request changes how the Web Bot Auth (WBA) verifier selects keys from a signed key directory, so that it follows the profile as revised in adcontextprotocol/adcp#7894. It also moves the interop harness pin to the head of adcontextprotocol/adcp#8298, which grades the change.

Refs #1500.

What changed

  • Keys without a valid signature are ignored. verify_directory_response and directory discovery use each Ed25519 key that has a valid signature on the directory response, and ignore every other key and its signatures. Before this change, a directory failed when any usable Ed25519 key did not sign it. A key whose signature does not verify, falls outside its window, uses another tag, or does not cover "@authority";req and "content-digest" is ignored in the same way. A directory with no validly signed Ed25519 key is still refused, so a request that names one of its keys still gets 403.
  • Malformed keys stay ignored. A key that does not import, such as an Ed25519 key with no x or a 31-byte x, is skipped and does not refuse the directory. The SDK already did this; a new test now grades it.
  • Private members still refuse the directory. The check runs on every key before any key is skipped, as before.
  • Publishers omit alg. public_directory_key and sign_key_directory already omit alg on Ed25519 keys, so nothing changes there.
  • Harness pin. ADCP_REF in the wba-interop job and the vendored tests/conformance/vectors/wba-profile/ vectors move to adcontextprotocol/adcp@f44785a, the head of #8298, which carries #7894's profile text and vectors. UPSTREAM.json records the new commit and checksums. The migration guide describes the new rule.
  • Adapter refusals. In a separate commit, tests/wba_interop/adapter.py reports only WbaVerificationError as a refusal. Any other exception, a plain ValueError included, now crashes the adapter, as tests/wba-interop/PROTOCOL.md requires. Before, the adapter read any ValueError as a refusal, which the harness would grade as a correct one.

Why

docs/building/by-layer/L1/wba-profile.mdx, section "Key directories", at #7894's head (9f472d63) says: "A verifier uses each Ed25519 key that has a valid signature on the directory response, and ignores every other key and its signatures." The basis is draft-ietf-webbotauth-httpsig-protocol-00 Appendix B.1 and section 5 of the directory draft: "Clients SHOULD ignore keys from a directory response that do not have a corresponding valid signature". Keys that cannot be imported are ignored per RFC 7517 section 5.

How it was verified

  • The harness on Node 24, from adcontextprotocol/adcp at f44785a5, run with node tests/wba-interop/run.mjs --adapter "python tests/wba_interop/adapter.py" --vectors static/compliance/source/test-vectors/wba-profile: 69 of 69 checks pass, including D11 (a second Ed25519 key that does not sign) and D15 (malformed Ed25519 keys next to a signed one). Before the change, D11 and its request signed with the signed key failed.
  • New unit tests in tests/test_identity_3_3_alignment.py: test_a_directory_key_without_a_valid_signature_is_ignored (with no signature and with an invalid one) and test_a_malformed_directory_key_is_ignored. Each was checked by inverting its rule once: requiring every usable key to sign fails the first test, refusing on an invalid signature fails its invalid case, and refusing a malformed Ed25519 key fails the second test.
  • test_the_interop_adapter_reports_only_sdk_refusals now expects a plain ValueError to crash the adapter. Restoring the old except ValueError fails it.
  • The signing tests (tests/conformance/signing, tests/test_identity_3_3_alignment.py, tests/test_wba_*.py, and the other identity and signed-request tests) pass on Python 3.12 with .[dev], fastapi, and svix.

A Web Bot Auth key directory no longer fails when one of its Ed25519 keys
has no valid signature. The verifier uses each Ed25519 key whose signature
on the directory response is valid, and ignores every other key and its
signatures, as wba-profile.mdx (Key directories) at adcontextprotocol/adcp#7894
now requires, per draft-ietf-webbotauth-httpsig-protocol-00 Appendix B.1 and
section 5 of the directory draft. A directory with no such key is still
refused, and a private member in any key still refuses the directory before
keys are skipped. A key that does not import, such as an Ed25519 key with
no x or a 31-byte x, stays ignored (RFC 7517 section 5).

Move the harness pin (ADCP_REF) and the vendored wba-profile vectors to
adcontextprotocol/adcp#8298 at f44785a5, whose D11 and D15 scenarios grade
the rule.
…pter

The harness adapter read any ValueError as a refusal, so a defect that
raised one was graded as a correct refusal. It now reports only
WbaVerificationError, the SDK's verification refusal, and any other
exception crashes the adapter, as tests/wba-interop/PROTOCOL.md requires.

@aao-secretariat aao-secretariat Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Ladon verdict: Approve

Approve — clean review, no blocking or medium findings.

Checked:

  • src/adcp/signing/wba.py (high-risk path, modified): the WBA directory verification change now uses each Ed25519 key with a valid signature and ignores the rest, instead of failing the whole directory when any usable key fails to sign. Change is fail-closed at the per-key trust level (only validly-signed keys returned), spec-aligned (adcp#7894/#8298, DR-0023, directory draft §5).
  • _window/_verify_crypto raise only WbaVerificationError, so the new try/except isolates per-key failures without swallowing defects; private-member and key-count invariants still run before any skip.
  • Adapter's direct .status/.reason access is safe since WbaVerificationError always sets them.
  • Tests cover the new branch (interop + profile conformance vectors, alignment tests).

Decision path: no critical/high/medium findings (rows 1, 4–8 N/A). gated_paths false (row 2 N/A). high_risk is true but only on a (modified) file with no medium-or-higher finding — row 3 (deleted) and row 5 (modified + medium) do not fire. No author team gate (row 7 N/A). No prior decision. Falls through to row 9 → approve.

This branch has not been deployed

No deployments
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.

1 participant