Skip to content

Phase 7c: auth hooks (@httpBearerAuth / @httpApiKeyAuth) + generated paginators - #17

Merged
aaylward merged 1 commit into
mainfrom
claude/smithy-cpp-generator-plan-fpeqzt
Jul 7, 2026
Merged

aaylward merged 1 commit into
mainfrom
claude/smithy-cpp-generator-plan-fpeqzt

Conversation

@aaylward

@aaylward aaylward commented Jul 7, 2026

Copy link
Copy Markdown
Collaborator

Third Phase 7 hardening slice: credential wiring from the model's auth traits, matching server-side guards, and generated paginators from @paginated.

Client auth (//runtime:client + codegen)

  • ClientConfig gains bearer_token and api_key providers (std::function<std::string()>, called per request so credential rotation just works; null providers leave requests anonymous).
  • Generated clients wire them per the service's traits: @httpBearerAuth sends authorization: Bearer <token>; @httpApiKeyAuth sends the key where the model binds it — named header with the trait's optional scheme prefix, or percent-encoded query parameter.
  • Fixture coverage of all three shapes: weather (@httpBearerAuth), cafe (@httpApiKeyAuth header), roundtrip REST (@httpApiKeyAuth query).

Server auth middleware (//runtime:server)

RequireBearerAuth(validator) (RFC 6750 scheme matched case-insensitively) and RequireApiKeyHeader(name, scheme, validator), both rejecting with 401 before the router runs — built on the Phase 7b middleware seam. Vendor-specific signing schemes (SigV4 etc.) stay out of scope per the vendor-neutrality rule; the interceptor seam is the extension point.

Generated paginators

@paginated operations with top-level string tokens get a <Op>Paginator: client.Paginate<Op>(input) → Next() yields one page at a time, feeds the output token back into the input, and returns std::nullopt once the token is absent or empty (defensive: never loops on a server echoing empty tokens; a failed call stops pagination and returns the error). The paginator owns a copy of the client and input, so it outlives both. Nested output-token paths and non-string tokens are skipped.

Tests

  • Weather e2e: bearer token flows from config.bearer_token through the generated client into RequireBearerAuth on the generated server (anonymous call rejected, authorized call round-trips); the paginator walks both pages, reports exhaustion, and stays exhausted.
  • Cafe wire test pins the x-api-key header on captured requests (and its absence without a provider).
  • Middleware unit tests: bearer scheme case-insensitivity, wrong-scheme/empty-credential rejection, api-key with and without scheme prefix.

Docs

Production guide gains Auth and Pagination sections with worked examples; runtime overview and README updated.

Validation

  • bazel test //... — 44/44 green locally, plus ASan+UBSan (Beast targets CI-verified as usual)
  • out-of-tree consumer module green against the updated generator
  • regeneration byte-stable; clang-format/clang-tidy/buildifier clean

🤖 Generated with Claude Code

https://claude.ai/code/session_01WjaNFwBZxoHdqagvq8ycQf


Generated by Claude Code

…ginators

- ClientConfig gains bearer_token and api_key credential providers
  (called per request, so rotation just works). Generated clients wire
  them per the service's auth traits: @httpBearerAuth sends
  "authorization: Bearer <token>"; @httpApiKeyAuth sends the key where
  the model binds it — named header with the trait's optional scheme
  prefix, or query parameter (percent-encoded). Null providers leave
  requests anonymous. Fixtures cover all three shapes: weather (bearer),
  cafe (header api key), roundtrip REST (query api key).

- Server-side guards ship as middleware: RequireBearerAuth (RFC 6750
  scheme matched case-insensitively) and RequireApiKeyHeader (optional
  scheme prefix), both 401 on failure.

- @paginated operations with top-level string tokens get a generated
  paginator: client.Paginate<Op>(input) returns <Op>Paginator whose
  Next() yields one page at a time, feeds the output token back into
  the input, and returns nullopt once the token is absent or empty
  (never loops on an echoing server; errors stop pagination). The
  paginator owns a copy of the client and input. Nested token paths
  and non-string tokens are skipped.

- Weather e2e: bearer token flows from config through the generated
  client into RequireBearerAuth middleware; the paginator walks both
  pages and stays exhausted. Cafe wire test pins the x-api-key header.

- docs: production-guide auth + pagination sections; runtime overview,
  README status updates.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WjaNFwBZxoHdqagvq8ycQf
@aaylward
aaylward merged commit 3ece73e into main Jul 7, 2026
10 checks passed
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.

2 participants