feat(auth): header_name + bearer_prefix_required on BearerTokenAuthMiddleware#545
feat(auth): header_name + bearer_prefix_required on BearerTokenAuthMiddleware#545
Conversation
…ddleware Adds two additive kwargs to support adopters using non-standard header schemes — most notably salesagent's legacy ``x-adcp-auth: <raw-token>`` layout, which has no ``Authorization`` header and no ``Bearer`` prefix. Surface: - header_name: str = "authorization" — which HTTP header carries the credential. Adopters with custom-header schemes (X-Api-Key, x-adcp-auth, x-proxied-auth) override this. - bearer_prefix_required: bool = True — when False, the raw header value is passed verbatim to validate_token (no Bearer strip). Whitespace is trimmed off the credential to handle copy-pasted tokens with trailing newlines. Defaults preserve the spec-canonical Authorization Bearer behavior — existing adopters not setting the new params see zero change. Closes salesagent SDK_FEEDBACK round 2 #18 (the request was for a TokenAuthMiddleware bridging x-adcp-auth → caller_identity; the existing BearerTokenAuthMiddleware already covers most of this surface, but couldn't read non-Authorization headers without subclassing). Memory profile: zero new state. Same per-request ContextVar pattern as before (set in dispatch, reset in finally) — request-scoped, no cross-request leak. Tests: 5 new tests in test_auth_middleware.py: - x-adcp-auth raw-token scheme (salesagent shape) - whitespace stripping on custom-header tokens - 401 when configured header is absent - bearer_prefix_required still enforced when True with custom header - defaults unchanged (regression guard) 35 total auth-middleware tests pass. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
|
Tight, additive change — defaults preserve canonical behavior, salesagent's footgun closes with two kwargs. Worth a docstring note (security-adjacent):
Looks fine:
Ready to merge once the docstring nits land (or punt them — they're not load-bearing). |
…TokenAuthMiddleware Addresses @bokelley's review on PR #545: - bearer_prefix_required=False docstring now notes that the prefix pre-filter is removed and validate_token must be defensive about unexpected input shapes and unbounded lengths. - New test confirms header_name is exclusive: when both Authorization and x-adcp-auth are present and header_name="x-adcp-auth", only the configured header reaches the validator — no silent fallback. https://claude.ai/code/session_01T2aXRPyJmjGEQu98iia9sg
|
Both items addressed in the follow-up commit:
36/36 auth-middleware tests pass. Generated by Claude Code |
|
Acknowledged — both items landed, 36/36 passing. No further action from triage side. Generated by Claude Code |
Summary
Two additive kwargs on
BearerTokenAuthMiddlewareto support adopters with non-standard header schemes:header_name: str = "authorization"— which HTTP header carries the credentialbearer_prefix_required: bool = True— whenFalse, the raw header value is passed verbatim tovalidate_token(noBearerstrip). Whitespace stripped to tolerate copy-pasted tokens.Defaults preserve the spec-canonical
Authorization: Bearer <token>behavior — existing adopters see zero change.Closes the actionable part of salesagent SDK_FEEDBACK round-2 #18. The existing
BearerTokenAuthMiddlewarealready covers most of the "TokenAuthMiddleware" ask in that doc —Principal,TokenValidator,current_principalcontextvar,auth_context_factoryare all here. The one gap was that salesagent's legacy server usesx-adcp-auth: <raw-token>with noAuthorizationheader and noBearerprefix; without these two kwargs, an adopter has to subclass the middleware and overridedispatch().Salesagent example
Before this PR, salesagent's migration would require:
After this PR:
5 LOC, no subclassing, no fork-of-dispatch maintenance.
Memory profile
Zero new request state. The two new fields are construction-time scalars on
self. Same per-request ContextVarset()/reset()discipline infinally:— request-scoped, no cross-request leak. Designed with the salesagent slow-leak investigation lens.Tests
5 new tests in
test_auth_middleware.py:x-adcp-auth: <raw-token>salesagent shape — token passes through verbatimAuthorizationis present)bearer_prefix_required=Truestill enforced on custom headers (proxy-stripped scenarios)35 auth-middleware tests pass total. Full suite (
tests/) passes.Test plan
test_auth_middleware.pytests pass🤖 Generated with Claude Code