feat(oauth-server): store and enforce token_endpoint_auth_method#2300
Conversation
cemalkilic
left a comment
There was a problem hiding this comment.
Great work @dulacp, thank you for the contribution!
I'll double check if the migration is idempotent
fa3a91b to
9235e2a
Compare
|
Hi again @dulacp, sorry for the delay. We’re back to this now. CI is failing on a couple of tests; could you take a look and push a fix when you get a chance? Happy to jump in if you don't. |
08583ec to
0e65eea
Compare
|
Thank @cemalkilic for your message. I found the fix and was able to make the tests pass locally! |
Pull Request Test Coverage Report for Build 21178873618Details
💛 - Coveralls |
|
Thanks @dulacp ! Tested and confirmed everything is working fine! One last request (I can't push changes to your fork), can you add the annotation -- Add token_endpoint_auth_method column to oauth_clients table
-- Per RFC 7591: "If unspecified or omitted, the default is 'client_secret_basic'"
-- For public clients, the default is 'none' since they don't have a client secret
/* auth_migration: 20251216000000 */
alter table {{ index .Options "Namespace" }}.oauth_clients
add column if not exists token_endpoint_auth_method text check (token_endpoint_auth_method in ('client_secret_basic', 'client_secret_post', 'none'));
-- Set default values for existing clients based on their client_type
/* auth_migration: 20251216000000 */
update {{ index .Options "Namespace" }}.oauth_clients
set token_endpoint_auth_method = case
when client_type = 'public' then 'none'
else 'client_secret_basic'
end
where token_endpoint_auth_method is null;
-- Now make the column not null
/* auth_migration: 20251216000000 */
alter table {{ index .Options "Namespace" }}.oauth_clients
alter column token_endpoint_auth_method set not null; |
|
@cemalkilic annotations added 👍, thanks for guiding me through this I wasn't sure how and where to add these. |
- Add database migration for token_endpoint_auth_method column (nullable text) - Store and enforce token_endpoint_auth_method during client registration - Refactor ExtractClientCredentials to identify which auth method was used - Add ValidateClientAuthMethod to compare used vs registered method - Update middleware to enforce auth method matching - Legacy clients (NULL) remain permissive for backward compatibility - New clients get strict enforcement per OAuth 2.0 spec Signed-off-by: Pierre Dulac <[email protected]> Signed-off-by: Pierre Dulac <[email protected]>
Adjust the indendation and use `slices.Contains` to stay consistent with the codebase. Signed-off-by: Pierre Dulac <[email protected]> Signed-off-by: Pierre Dulac <[email protected]>
d20d85a to
2f54d9f
Compare
|
I've made a rebase on master to fix a small conflict. |
|
Sorry @dulacp , we couldn't get merged last week due to internal priorities. I'll do the final review and get it merged as soon as the CI is green! |
|
No worries :) I believe I've fixed the issue with the |
## Summary This migration was added in #2300, however we couldn't merge in time. Now updating the migration version (hence filename) to prevent any possible issues.
🤖 I have created a release *beep* *boop* --- ## [2.186.0](v2.185.0...v2.186.0) (2026-01-28) ### Features * Add email send operation metrics ([#2311](#2311)) ([0096575](0096575)) * add Supabase Auth identifier to OAuth redirect URLs ([#2299](#2299)) ([2d3dbc6](2d3dbc6)) * log sb-auth-user-id, sb-auth-session-id, ... on sign in not just refresh token ([#2342](#2342)) ([a486ada](a486ada)) * **oauth-server:** store and enforce token_endpoint_auth_method ([#2300](#2300)) ([bcd6cd5](bcd6cd5)) * replace JWT OAuth state with `flow_state.id` UUID ([#2331](#2331)) ([645654d](645654d)) * upgrade existing sessions to v2 refresh tokens though config value ([#2356](#2356)) ([6fb0e8a](6fb0e8a)) ### Bug Fixes * reloader unittest races on writeWg ([#2352](#2352)) ([088b714](088b714)) * update migration version ([#2343](#2343)) ([61ef4db](61ef4db)) --- This PR was generated with [Release Please](https://github.com/googleapis/release-please). See [documentation](https://github.com/googleapis/release-please#release-please). Co-authored-by: supabase-releaser[bot] <223506987+supabase-releaser[bot]@users.noreply.github.com>
Problem
I noticed there was a TODO for storing the
token_endpoint_auth_methodvalue. While integrating with Claude.ai's OAuth flow, we discovered that returningclient_secret_basicfor all clients (regardless of their actual registration) was breaking the authentication flow. Claude.ai strictly validates the auth method returned during client registration, so it was critical for us to return the correct value.Per RFC 7591 Section 2:
For public clients, the default is
nonesince they don't have a client secret.Solution
Added proper storage and enforcement of
token_endpoint_auth_method:Database Changes
token_endpoint_auth_methodTEXT column (NOT NULL) tooauth_clientstableclient_type:confidential→client_secret_basicpublic→noneBehavior
token_endpoint_auth_methodpersisted during registrationtoken_endpoint_auth_methodin client registration responses