Skip to content

BearerTokenAuthMiddleware does not construct AuthInfo — ctx.auth_info.kind unusable for bearer flows #576

@bokelley

Description

@bokelley

What

BearerTokenAuthMiddleware (`src/adcp/server/auth.py`) authenticates requests, sets the framework-private `current_principal` ContextVar with the validated principal id, and short-circuits on auth failure. What it does not do: construct an `AuthInfo` object and thread it into the request context.

Net effect for bearer adopters reading `RequestContext`:

  • `ctx.auth_info` is `None` (or default-stub) — adopters can't read `auth_info.kind`, `auth_info.key_id`, `auth_info.credential`, etc.
  • Adopters who want to branch on "is this a bearer or signed-request flow?" have no typed read.
  • After #574, `ctx.auth_principal` is correctly populated for bearer flows — but the surrounding typed auth surface (`auth_info.*`) is still unusable.

Why it matters

The triage security-reviewer flagged this as a structural gap during the issue #571 review. PR #574 addressed the immediate `auth_principal is None` papercut; this issue tracks the deeper fix so it doesn't only live in PR-body prose.

For adopters writing transport-agnostic handlers, `ctx.auth_info` is meant to be the typed identity surface. Today bearer adopters either (a) read `ctx.auth_principal` (post-#574) and ignore everything else, or (b) reach into framework-private contextvars to reconstruct what they need.

Possible direction

Have `BearerTokenAuthMiddleware` construct an `AuthInfo` after `validate_token` succeeds, populate `AuthInfo.kind = "bearer"` (or similar), `AuthInfo.principal = principal.caller_identity`, and thread it into the request context alongside the ContextVar. Then `_build_request_context` already does the right thing for both flows, and adopters can read `ctx.auth_info.kind` to discriminate.

Open questions:

  • What goes into `AuthInfo.credential` for a bearer flow? Per CLAUDE.md, the typed credential classes (`ApiKeyCredential`, `OAuthCredential`, `HttpSigCredential`) are for upstream propagation. Bearer adopters typically don't propagate the inbound bearer token outward — what's the right shape?
  • `AuthInfo.kind` enum: does "bearer" exist today, or do we extend it?
  • Backward compatibility: any consumer that assumes `auth_info` is `None` for bearer flows will break. Worth auditing before shipping.

Surfaced by

PR #574 (closes #571). Security-reviewer notes captured in the issue #571 triage comment.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions