Skip to content

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

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.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to 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