Skip to content

test(training-agent): omit bearer in create_media_buy 401 assertion (#3080)#3096

Merged
bokelley merged 2 commits into
mainfrom
claude/issue-3080-mcp-strict-bearer-bypass
Apr 25, 2026
Merged

test(training-agent): omit bearer in create_media_buy 401 assertion (#3080)#3096
bokelley merged 2 commits into
mainfrom
claude/issue-3080-mcp-strict-bearer-bypass

Conversation

@bokelley

@bokelley bokelley commented Apr 25, 2026

Copy link
Copy Markdown
Contributor

Closes #3080

Summary

Two-part fix for the /mcp-strict 401 test that was failing even after PR #3082 merged.

Root cause: callTool sends Authorization: Bearer test-token-for-strict by default. The SDK's requireAuthenticatedOrSigned short-circuits on a successful bearer result before the required_for gate runs (auth-signature.js:146-147: if (fallbackResult !== null) return fallbackResult). This is intentional SDK behavior per #2586 — a valid credential is sufficient even when signing is required for unauthenticated callers. PR #3082's resolveOperation rawBody fix only helps when bearer returns null; with a valid bearer present, resolveOperation is never reached in the required_for code path.

Fix 1 — omit bearer: Pass { auth: false } on the failing test call to suppress the bearer token. This models the actual grader scenario: compliance graders don't carry bearer tokens — they authenticate via RFC 9421 signature credentials only. With no bearer and no signature on a required_for op, the gate fires and returns 401 request_signature_required.

Fix 2 — correct www-authenticate assertion: The test was asserting /^Bearer / on the WWW-Authenticate header. Per index.ts:207 and static/compliance/source/universal/signed-requests.yaml:52/188, respondUnauthorized({ signatureError }) emits WWW-Authenticate: Signature error="<code>", not a Bearer challenge. Fixed to /Signature error="request_signature_required"/, pinning exactly what the compliance grader reads.

Non-breaking justification: Server integration tests only. No schema, task definition, wire protocol, or public API surface changed.

Aside — CI gap: Vitest integration tests don't run in CI for this repo, which is why #3082, #3079, and the original regression all reported clean CI with a failing test. Wiring vitest into the CI pipeline needs a separate human-authored PR touching .github/workflows/.

Pre-PR review (two iterations)

Iteration 1:

  • code-reviewer: approved — { auth: false } is type-safe per callTool's signature; no test overlap with existing POST /mcp-strict without auth assertion (different tool, different rejection reason).
  • ad-tech-protocol-expert: blockerwww-authenticate assertion /^Bearer / is wrong for the signatureError code path; grader reads Signature error="..." scheme, not Bearer.

Iteration 2 (after fixing blocker):

  • ad-tech-protocol-expert: signed off — blocker resolved; both commits logically complete; assertion now matches the actual wire format from respondUnauthorized({ signatureError }); regex correctly non-anchored to tolerate additional challenge parameters.

Session: https://claude.ai/code/session_01S7aDiMrwhfYPr7FzYQdn9C

claude added 2 commits April 25, 2026 09:47
The /mcp-strict 401 test sent a valid bearer token by default. The SDK's
requireAuthenticatedOrSigned short-circuits on a successful bearer result
before the required_for gate runs (bearer bypass, per SDK #2586), so the
test got 200 instead of 401.

Fix: pass { auth: false } to simulate the grader scenario — compliance
graders carry no bearer token and authenticate via RFC 9421 signatures
only. With no bearer and no signature on a required_for op, the gate
fires and returns 401 request_signature_required.

Closes #3080

https://claude.ai/code/session_01S7aDiMrwhfYPr7FzYQdn9C
…scheme

The test was asserting /^Bearer / on the WWW-Authenticate header for the
request_signature_required path. Per index.ts:207 and signed-requests.yaml:52,
respondUnauthorized({ signatureError }) emits:

  WWW-Authenticate: Signature error="<code>"

not a Bearer challenge. Bearer challenges come from the no-credentials /
invalid-token paths. Pinning to the Signature scheme catches regressions
where the SDK emits the wrong challenge type — the compliance grader reads
the error code off this header.

https://claude.ai/code/session_01S7aDiMrwhfYPr7FzYQdn9C
@bokelley bokelley marked this pull request as ready for review April 25, 2026 23:50
@bokelley bokelley merged commit cc9d077 into main Apr 25, 2026
12 checks passed
@bokelley bokelley deleted the claude/issue-3080-mcp-strict-bearer-bypass branch April 25, 2026 23:51
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.

training-agent: /mcp-strict no longer rejects unsigned create_media_buy with 401

2 participants