Skip to content

fix(signing): register vector 027 + skip in verifier conformance#682

Merged
bokelley merged 4 commits into
mainfrom
bokelley/vector-027-passthrough
Apr 21, 2026
Merged

fix(signing): register vector 027 + skip in verifier conformance#682
bokelley merged 4 commits into
mainfrom
bokelley/vector-027-passthrough

Conversation

@bokelley

Copy link
Copy Markdown
Contributor

Summary

Upstream compliance cache (compliance/cache/latest/test-vectors/request-signing/negative/) added vector 027-webhook-registration-authentication-unsigned, breaking CI on any open PR. Vector 027 tests the #webhook-security downgrade resistance rule: a webhook registration whose body carries push_notification_config.authentication MUST require RFC 9421 signing even when the operation is absent from the verifier's required_for list.

The fixture ships its adversarial shape verbatim (unsigned bearer request with authentication in the body), so the builder only needs a passthrough mutation — no programmatic mutation required. The verifier does not yet inspect request bodies for this rule, so vector 027 is added to the unimplemented-verifier skip lists alongside 021–026.

Changes

  • src/lib/testing/storyboard/request-signing/builder.ts — passthrough mutation for 027-webhook-registration-authentication-unsigned.
  • test/request-signing-vectors.test.js — add 027-webhook-registration-authentication-unsigned.json to NEGATIVE_VECTORS_UNIMPLEMENTED (skips the conformance check until the verifier learns the rule).
  • test/request-signing-grader-e2e.test.js + test/request-signing-grader-mcp.test.js — add a UNIMPLEMENTED_VERIFIER_RULE_VECTORS constant and fold it into SKIPPED_VECTORS (alongside CAPABILITY_PROFILE_VECTORS). Count assertions move 26 → 27.
  • test/request-signing-grader-vectors.test.js + test/request-signing-runner-integration.test.js — count assertions move 26 → 27 (and 25 → 26 for the skipVectors subtest).

Scope

CI-unblocking patch only. Implementing the body-inspection rule in the verifier is a separate follow-up; once that lands, vector 027 moves off the skip lists.

Test plan

  • node --test test/request-signing-*.test.js — 54/54 pass locally
  • npm test — 4476 pass / 0 fail / 13 skipped (27's conformance + the existing 6 from 021–026)
  • tsc --noEmit — clean (pre-push hook)
  • CI full suite

🤖 Generated with Claude Code

bokelley and others added 4 commits April 20, 2026 21:42
Upstream compliance cache added vector
027-webhook-registration-authentication-unsigned, which tests the
webhook-security downgrade rule: a webhook registration whose body
carries push_notification_config.authentication MUST require RFC 9421
signing even when the operation is not in the verifier's required_for
list. The fixture ships the adversarial shape verbatim (unsigned bearer
request with authentication in the body), so the builder just needs a
passthrough mutation. The verifier does not yet inspect request bodies
for this rule, so vector 027 joins 021-026 on the unimplemented-verifier
skip lists; the conformance suite skips it, the grader e2e/mcp tests
skip it, and count assertions move from 26 to 27 negatives.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…us export

Upstream schema bundle regenerated ListCreativesRequest,
CheckGovernanceResponse, and related types as open-indexed intersection
types; CatalogAction and CatalogItemStatus moved from tools.generated to
core.generated. Regen is mechanical; index.ts re-exports move to match.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@bokelley bokelley merged commit d2f1021 into main Apr 21, 2026
14 checks passed
bokelley added a commit that referenced this pull request Apr 21, 2026
…1-027 (#687)

* feat(signing): implement verifier conformance for negative vectors 021-027

Closes #683. The RFC 9421 reference verifier now enforces the full
#verifier-checklist-requests + #webhook-security profile against the seven
negative conformance vectors that had been skipped since #631.

Vectors 021-026 were already implemented library-side (duplicate
Signature-Input labels, multi-valued content-type / content-digest,
unquoted string params, JWK alg/crv consistency, non-ASCII @authority);
the conformance suite was skipping them via `NEGATIVE_VECTORS_UNIMPLEMENTED`.
Removing that skip-list surfaced one harness bug: the test runner's
eager `canonicalTargetUri(vector.request.url)` threw on vector 026's
U-label authority before the verifier's own parse-time check could fire.
Deferred the precompute until a `replay_cache_entries` preload actually
needs it.

Vector 027 (webhook-authentication downgrade resistance) required new
verifier logic and builder registration:

- `verifyRequestSignature` on the unsigned branch now rejects any request
  whose JSON body carries a non-empty `push_notification_config.authentication`
  anywhere in the tree — inside nested arrays, under any parent key, and
  regardless of `Content-Type`. Closes the captured-bearer-token ->
  hostile webhook callback redirect path; `required_for` precedence is
  preserved so an operation already on the always-sign list still gets
  the more specific error message.
- DoS hardened: body size capped at 1 MB (oversized unsigned bodies fail
  closed with `request_signature_required` since we can't prove absence
  of webhook auth within the pre-crypto budget), traversal capped at
  depth 64 so pathologically nested JSON can't blow the stack.
- Builder registers 027 as a passthrough mutator since the adversarial
  shape lives in the fixture body, not a programmatic mutation.

Test coverage: nine new unit tests in `request-signing-verifier-api.test.js`
lock the surface around the conformance vector — present-without-auth,
empty auth, null auth, string-typed auth, array-nested auth, non-JSON
body, oversized body, and signed requests carrying auth material (must
reach the crypto path, not re-reject at step 0). Grader e2e + MCP tests
drop the upstream-added `UNIMPLEMENTED_VERIFIER_RULE_VECTORS` skip
introduced in #682; full suite 4502 pass / 0 fail / 6 skipped.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* chore: prettier on new webhook-auth verifier tests

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* chore: trigger CI on formatting-fixed head

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
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