Skip to content

Support OAuth client_secret_basic#1448

Open
MisterJimson wants to merge 3 commits into
UsefulSoftwareCo:mainfrom
MisterJimson:jason/codex/oauth-client-secret-basic
Open

Support OAuth client_secret_basic#1448
MisterJimson wants to merge 3 commits into
UsefulSoftwareCo:mainfrom
MisterJimson:jason/codex/oauth-client-secret-basic

Conversation

@MisterJimson

@MisterJimson MisterJimson commented Jul 21, 2026

Copy link
Copy Markdown

Summary

Add configurable OAuth token-endpoint client authentication so registered clients can use either client_secret_post or client_secret_basic. The selected method is persisted and reused across authorization-code exchange, client-credentials minting, refresh, and re-minting.

client_secret_basic uses the interoperable HTTP Basic representation expected by common providers: Base64 of the literal UTF-8 client_id:client_secret pair.

Closes #1447

Changes

  • Persist the token-endpoint authentication method on OAuth clients in PostgreSQL, SQLite, and Cloudflare D1.
  • Expose client_secret_post and client_secret_basic through the OAuth client API and registration form.
  • Thread the selected method through authorization-code exchange, client-credentials minting, refresh, and client-credentials re-minting.
  • Preserve client_secret_post as the default for existing clients.
  • Encode client_secret_basic as the literal credential pair instead of form-encoding each component before Base64 encoding.
  • Add regression coverage for Basic credentials containing underscores and punctuation.

Interoperability example: Aikido

Aikido's OAuth documentation requires client credentials in an HTTP Basic authorization header for its token endpoint.

The strict RFC 6749 representation form-encodes each credential component before Base64 encoding. For example, an Aikido client ID beginning with AIK_CLIENT_ is transmitted as AIK%5FCLIENT%5F.... Aikido compares the decoded Basic username and password literally, so it rejects that representation as invalid credentials even though the same pair succeeds with conventional Basic clients such as curl --user.

Using Base64 of the literal credential pair makes this real provider work while retaining the expected client_secret_basic request shape. See RFC 6749 §2.3.1 for the strict encoding rule and the note that HTTP Basic is not otherwise recommended outside this client-authentication profile.

Testing

  • bun run format:check
  • bun run lint
  • SDK typecheck
  • OAuth helper and flow tests (76 tests)
  • Production Cloudflare build
  • Manual client-credentials connection against Aikido

Notes for reviewers

The Basic encoding is intentionally interoperable rather than RFC-strict. Exposing separate “strict” and “raw” Basic choices would require users to understand a wire-level distinction that OAuth provider documentation generally does not surface. If a provider requiring strict component encoding is identified, that can be added later as an advanced compatibility mode with a concrete test case.

@MisterJimson
MisterJimson marked this pull request as ready for review July 21, 2026 20:23
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.

Support client_secret_basic for OAuth client credentials

1 participant