Skip to content

feat: let resource servers introspect client_credentials tokens - #176

Merged
jaspermayone merged 2 commits into
mainfrom
jaspermayone/175-introspect-scope
Oct 10, 2026
Merged

jaspermayone merged 2 commits into
mainfrom
jaspermayone/175-introspect-scope

Conversation

@jaspermayone

Copy link
Copy Markdown
Member

Why

Quilt is a resource server. Krater calls Quilt with a Weave client_credentials token, and Quilt must check that token. Weave tokens are opaque, so Quilt must use POST /oauth/introspect. The default Doorkeeper rule lets an app introspect only its own tokens. Thus Quilt gets {"active": false} for every Krater token.

What changed

  • New optional scopes quilt and introspect. Each has a description in config/locales/doorkeeper.en.yml. Discovery scopes_supported shows them.
  • scopes_by_grant_type authorization_code: lists only the user scopes. Thus the authorization endpoint gives invalid_scope for directory, quilt and introspect. These scopes are for client_credentials tokens only. client_credentials and refresh_token are not limited.
  • allow_token_introspection keeps the Doorkeeper 5.8.2 default rule. It adds one case: the client authenticates with HTTP Basic, its app is allowed introspect, and the token has no user. A user's token stays private to its own app. A bearer token still introspects only tokens of its own app.
  • Only a superadmin can add or remove introspect on an app (create and update in Admin::OauthApplicationsController). Any admin can still change the other scopes.
  • The admin app forms list the app scopes.
  • docs/OAUTH.md has a new "Resource servers" section.
  • The Oauth::TokensController override (AppAccess) does not change.
sequenceDiagram
  participant K as Krater
  participant W as Weave
  participant Q as Quilt
  K->>W: POST /oauth/token (client_credentials, scope=quilt)
  W-->>K: access_token
  K->>Q: call the patch API (Bearer access_token)
  Q->>W: POST /oauth/introspect (Basic auth with Quilt's credentials)
  W-->>Q: active, client_id (Krater uid), scope "quilt", exp, iat, token_type
  Q-->>K: response
Loading

Admin steps after deploy

  1. A superadmin adds introspect to the scopes of the Quilt app in /admin/oauth_applications.
  2. An admin adds quilt to the scopes of the Krater app.

Tests

  • spec/requests/oauth/introspection_spec.rb: Quilt introspects a Krater quilt token (active, client_id, scope, exp, iat, token_type). Quilt can't see a Krater user token. An app without introspect can't see another app's token, but still sees its own. Revoked and expired tokens are inactive. A bearer token can't introspect another app's token. quilt is not issued to an app that is not allowed it. directory, quilt and introspect can't be asked for at the authorization endpoint.
  • spec/requests/admin_oauth_application_scopes_spec.rb: a plain admin can't add or remove introspect. A superadmin can.

Closes #175

@jaspermayone
jaspermayone marked this pull request as ready for review October 10, 2026 21:22
@jaspermayone
jaspermayone merged commit 11eeb83 into main Oct 10, 2026
9 checks passed
@jaspermayone
jaspermayone deleted the jaspermayone/175-introspect-scope branch October 10, 2026 21:23
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.

let resource servers introspect client_credentials tokens

1 participant