Skip to content

feat: register public clients without a secret - #28046

Draft
BobbyHo wants to merge 1 commit into
oauth2-public-clients-vocabularyfrom
oauth2-public-clients-registration
Draft

feat: register public clients without a secret#28046
BobbyHo wants to merge 1 commit into
oauth2-public-clients-vocabularyfrom
oauth2-public-clients-registration

Conversation

@BobbyHo

@BobbyHo BobbyHo commented Aug 11, 2026

Copy link
Copy Markdown
Contributor

Split out of #27873 to make that PR smaller to review. Third in the stack (on top of #28043); this is the point where dynamic client registration actually produces a public client.

An RFC 7591 registration requesting token_endpoint_auth_method: "none" now skips secret generation entirely: no secret is minted, and the app is persisted with the client_type the previous PR in the stack derives from that auth method. Discovery advertises "none" as a supported method so a client can find out Coder will accept it.

Registration now writes the app and its secret in one transaction. They were two independently committed inserts, so a failure of the second left a permanently committed app that can never authenticate while still holding a registration access token. Pre-existing, but making a public client's "no secret row" a legitimate state removes the ability to spot the orphaned confidential case by inspection later, so it's fixed here alongside the rest of this change.

registration_client_uri now uses url.JoinPath instead of fmt.Sprintf, fixing a latent bug where an access URL configured with a trailing slash would mint //oauth2/clients/{id} as the client's management endpoint.

The token endpoint does not yet accept a public client's PKCE-only exchange; that follows in the next PR in the stack, so a client registered here cannot yet obtain a token. Dynamic client registration itself is off by default (GetOAuth2DCREnabled), so this is not user-visible until the next PR lands.

Refs https://linear.app/codercom/issue/ENG-3029/oauth2-support-public-client

@github-actions

Copy link
Copy Markdown

Docs preview

Check off each page once it's been reviewed. If a page changes in a later push, its checkbox clears automatically so it gets a fresh look. Pages not yet wired into the docs navigation aren't listed here.

@BobbyHo BobbyHo changed the title feat(coderd/oauth2provider): register public clients without a secret feat: register public clients without a secret Aug 11, 2026
Split out of #27873 to make that PR smaller to review. Third in the
stack; this is the point where dynamic client registration actually
produces a public client.

An RFC 7591 registration requesting token_endpoint_auth_method: "none"
now skips secret generation entirely: no secret is minted, and the app
is persisted with the client_type the previous PR in the stack derives
from that auth method. Discovery advertises "none" as a supported
method so a client can find out Coder will accept it.

Registration now writes the app and its secret in one transaction. They
were two independently committed inserts, so a failure of the second
left a permanently committed app that can never authenticate while
still holding a registration access token. Pre-existing, but making a
public client's "no secret row" a legitimate state removes the ability
to spot the orphaned confidential case by inspection later, so it is
fixed here alongside the rest of this change.

The registration_client_uri now uses url.JoinPath instead of
fmt.Sprintf, fixing a latent bug where an access URL configured with a
trailing slash would mint "//oauth2/clients/{id}" as the client's
management endpoint.

The token endpoint does not yet accept a public client's PKCE-only
exchange; that follows in the next PR in the stack, so a client
registered here cannot yet obtain a token.
@BobbyHo
BobbyHo force-pushed the oauth2-public-clients-vocabulary branch from 0d8a377 to 01ec6b3 Compare August 12, 2026 00:18
@BobbyHo
BobbyHo force-pushed the oauth2-public-clients-registration branch from 872b5e3 to 7c8d3e5 Compare August 12, 2026 00:18
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.

1 participant