Skip to content

fix(platform): prefer client_secret_post for OIDC token exchange - #582

Merged
cpojer merged 1 commit into
voidzero-dev:mainfrom
kulterryan:fix/oidc-client-secret-post
Oct 26, 2026
Merged

cpojer merged 1 commit into
voidzero-dev:mainfrom
kulterryan:fix/oidc-client-secret-post

Conversation

@kulterryan

Copy link
Copy Markdown
Contributor

Summary

Google sign-in through configured login methods fails at the token exchange. oauth4webapi's ClientSecretBasic form-encodes the client ID and secret before Base64 (RFC 6749 §2.3.1), turning every -, . and _ into %2D, %2E, %5F. Google compares the raw values without decoding, so 761060634857-….apps.googleusercontent.com / GOCSPX-… never match.

Google advertises both methods, and Basic was picked first. Prefer the form body, which providers always decode:

 exchange()
   methods = token_endpoint_auth_methods_supported ?? ['client_secret_basic']
-  if methods has client_secret_basic → ClientSecretBasic
-  elif methods has client_secret_post → ClientSecretPost
+  if methods has client_secret_post → ClientSecretPost
+  elif methods has client_secret_basic → ClientSecretBasic
   else → reject

Basic-only providers keep the existing behavior. The legacy auth/google.ts path already posts credentials in the body and is unaffected.

Evidence

New unit test: Google connection, client ID 761060634857-abc_def.apps.googleusercontent.com, discovery listing ['client_secret_post', 'client_secret_basic']. Expects the raw client_id in the token request body and no Authorization header.

  • Before: platform-oidc.test.ts: 1 failed | 24 passed
  • After: platform-oidc.test.ts: 25 passed

platform-login and platform-bootstrap integration tests: 42 passed. The 2 browser cases didn't run locally because Playwright's Chromium isn't installed. @voidcloud/api typecheck passes.

Merge Danger

Door: two-way

Blast Radius: OIDC login

Providers that advertise both methods now receive client_secret_post instead of Basic. Both are standard and advertised by the provider itself.

oauth4webapi form-encodes Basic credentials per RFC 6749 §2.3.1, escaping
`-`, `.` and `_`. Google compares them without decoding, so Google
client IDs and secrets were rejected at the token endpoint.

@cpojer cpojer left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you!

@cpojer
cpojer merged commit ce3b8e4 into voidzero-dev:main Oct 26, 2026
3 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