add oauth oidc - #2074
Merged
Merged
Conversation
Contributor
There was a problem hiding this comment.
Pull request overview
Adds OpenID Connect (OIDC) support on top of the existing Doorkeeper OAuth provider, enabling Yeti to act as an OIDC issuer (id_token, discovery, JWKS, userinfo) and introducing an ActiveAdmin UI + policy for managing confidential OAuth/OIDC client applications.
Changes:
- Integrates
doorkeeper-openid_connect, adds OIDC configuration/claims, and mounts OIDC discovery/JWKS/userinfo routes when enabled. - Adds persistence for OIDC
nonceviaoauth_openid_requestsand updates OAuth discovery metadata to advertise OIDC endpoints. - Introduces an ActiveAdmin “OAuth Applications” page with a dedicated policy, plus request/feature specs covering OIDC flows and client management.
Reviewed changes
Copilot reviewed 25 out of 27 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| spec/requests/oauth/well_known_spec.rb | Extends OAuth discovery request specs to pin route/controller selection and advertise OIDC metadata. |
| spec/requests/oauth/userinfo_spec.rb | Adds request specs for the OIDC userinfo endpoint behavior. |
| spec/requests/oauth/openid_connect_flow_spec.rb | Adds an authorization-code OIDC flow spec validating id_token contents and signature via JWKS. |
| spec/requests/oauth/openid_configuration_spec.rb | Adds specs for OIDC discovery (/.well-known/openid-configuration) and JWKS publishing. |
| spec/policies/oauth_application_policy_spec.rb | Adds policy specs for role-gated access to OAuth application management actions. |
| spec/fixtures/oidc_test_signing_key.pem | Adds a committed test signing key for CI/specs. |
| spec/features/system/oauth_applications_spec.rb | Adds system specs for OAuth Applications ActiveAdmin UI (create/show/rotate/delete and access gating). |
| lib/tasks/oauth.rake | Adds a rake task to generate an RSA signing key for id_tokens. |
| Gemfile.lock | Locks the new OIDC gem dependency and bumps httpx. |
| Gemfile | Adds doorkeeper-openid_connect dependency with configuration notes. |
| db/structure.sql | Adds the gui.oauth_openid_requests table and related constraints/indexes to schema dump. |
| db/migrate/20260729120000_create_doorkeeper_openid_connect_tables.rb | Introduces migration creating storage for OIDC nonces. |
| config/yeti_web.yml.distr | Documents OIDC configuration options (issuer + signing key path). |
| config/yeti_web.yml.development | Adds commented OIDC config guidance for local development. |
| config/yeti_web.yml.ci | Enables OIDC in CI and points to the test signing key fixture. |
| config/routes.rb | Skips Doorkeeper applications controller and conditionally mounts OIDC routes with ordering constraints. |
| config/policy_roles.yml_ | Updates the policy roles template (includes an unrelated Billing permission change). |
| config/locales/en.yml | Adds i18n model names for OAuth models to improve ActiveAdmin labeling. |
| config/initializers/doorkeeper.rb | Tightens PKCE to S256-only and conditionally exposes OIDC scopes when enabled. |
| config/initializers/doorkeeper_openid_connect.rb | Adds Doorkeeper OpenID Connect configuration: issuer, signing key, subject, userinfo behavior, and claim definitions. |
| config/initializers/config.rb | Extends typed config schema to include oauth.oidc settings. |
| app/policies/oauth_application_policy.rb | Adds role-based policy for OAuth Applications ActiveAdmin page/actions. |
| app/models/oauth_openid_request.rb | Adds custom OpenID request model targeting gui.oauth_openid_requests. |
| app/models/oauth_access_token.rb | Revokes token accessibility immediately when the admin user is disabled. |
| app/controllers/well_known/oauth_authorization_server_controller.rb | Merges OIDC endpoint metadata into the OAuth authorization server discovery doc when enabled. |
| app/admin/system/oauth_applications.rb | Adds ActiveAdmin CRUD UI for OAuth applications plus secret rotation action. |
| .gitignore | Ignores the default on-disk OIDC signing key path (config/oidc_signing_key.pem). |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comment on lines
+1
to
+3
| -----BEGIN PRIVATE KEY----- | ||
| MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCsKcSZQw2Bcqw1 | ||
| NIHqImgv2b1fGAAxOnSrGi0aTHJPQFpbisvAkE5Q2PJWIj1OvqDWVEQFVKS7cEb9 |
Comment on lines
60
to
+63
| perform: true | ||
| Billing/NotificationTemplate: | ||
| read: true | ||
| change: true |
Comment on lines
+20
to
+24
| raise ArgumentError, "refusing to overwrite existing key at #{path}" if File.exist?(path) | ||
|
|
||
| key = OpenSSL::PKey::RSA.new(2048) | ||
| File.write(path, key.to_pem) | ||
| File.chmod(0o400, path) |
Comment on lines
+102
to
+106
| claim(:email, response: %i[id_token user_info]) { |resource_owner, _scopes| resource_owner.email } | ||
| # Set by another admin on the billing contact, never self-asserted — so an | ||
| # address that exists is as verified as this provider can make it. | ||
| claim(:email_verified, response: %i[id_token user_info]) { |resource_owner, _scopes| resource_owner.email.present? } | ||
|
|
Comment on lines
+95
to
+97
| claim(:name, response: %i[id_token user_info]) { |resource_owner, _scopes| resource_owner.display_name } | ||
| claim(:preferred_username, response: %i[id_token user_info]) { |resource_owner, _scopes| resource_owner.username } | ||
|
|
Contributor
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 31 out of 33 changed files in this pull request and generated no new comments.
Suppressed comments (2)
config/policy_roles.yml_:63
config/policy_roles.yml_does not appear to be loaded by the application (policy roles are read fromconfig/policy_roles.ymlinconfig/initializers/policy_roles.rb). Updating this file won’t affect runtime behavior and is likely an accidental change; if you meant to adjust default role templates, updateconfig/policy_roles.yml.distr(and/or docs) instead, or remove this file to avoid confusion.
Billing/NotificationTemplate:
read: true
change: true
OIDC.md:181
- This section describes an overlap-based key rotation strategy, but the current implementation/specs expect JWKS to publish exactly one key (e.g.
spec/requests/oauth/openid_configuration_spec.rbassertskeys.size == 1). With a single published key, swapping the signing key will invalidate previously issued id_tokens, so the doc should either describe that limitation or explain how to publish multiple keys during rotation.
**Key rotation.** Publish the new key in JWKS *before* signing with it, keep the
old one published until every issued token has expired, then drop the old one.
The `kid` header on each token says which key signed it. Skipping the overlap
signs everyone out.
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.
No description provided.