Repository navigation
feat(oauth): remember consent, skip it for first-party apps, enforce it on prompt=none - #204
Merged
Merged
Conversation
…it on prompt=none Every interactive sign-in ended on the consent screen, for every application, every time: nothing recorded what the person had approved. A customer going from one INITE product to pay in another had to confirm again. And prompt=none issued a code to any client for anyone with a session, without checking consent at all (OIDC core 3.1.2.6 says answer consent_required). - oauth_consents records the scopes a person approved per client; the screen is shown again only for scopes not yet approved. Requests with RFC 9396 authorization_details are always asked — they are specific to the request. - oauth_clients.firstParty: INITE's own applications need no consent. Set at boot from OAUTH_FIRST_PARTY_CLIENTS (the whole list when set; unset leaves the column alone); dcr_* clients are never first-party. The prod compose lists the manually registered INITE clients. - /authorize with a session and nothing to ask returns the code directly; prompt=none answers consent_required when there is. The consent screen asks GET /oauth/consent-check on load and approves by itself when not needed, since password/passkey/wallet sign-in land on it directly. - create-code records the approval. The account page gains "Connected apps": GET /oauth/consents, DELETE /oauth/consents/:clientId forgets the consent and revokes that client's refresh tokens. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015G5qmCWXaguo6yxvfBMPTt
The first-party list lived in OAUTH_FIRST_PARTY_CLIENTS and was applied at boot, so marking an app meant a config change and a redeploy. It is now a switch in the admin (create and edit panels, shown as a badge in the list and details), sent as `firstParty` to POST/PUT /admin/oauth-clients. - New admin-registered clients default to first-party; untick for a partner. - A dcr_* (self-registered) client cannot be made first-party (400). - Migration 0026 backfills: every existing client not named dcr_* is first-party. The env variable, the boot step and the compose entry go. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015G5qmCWXaguo6yxvfBMPTt
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Consent is remembered per (user, client, scopes); first-party clients skip the screen — a switch per client in the admin (new admin-registered clients default to on; dcr_* can never be first-party; migration 0026 backfills every existing non-dcr client as first-party). prompt=none now answers consent_required instead of minting a code without consent. The account page gains Connected apps with disconnect. Migration 0026 is additive plus that backfill.
🤖 Generated with Claude Code
https://claude.ai/code/session_015G5qmCWXaguo6yxvfBMPTt