Add RFC 8707 Resource Indicators (audience binding)
Clients can name a target resource server via the `resource` parameter at the authorization and device-authorization endpoints. Clinch binds it to the issued token as its audience and reports it at introspection as `aud`, so a token minted for one API cannot be replayed against another that also trusts clinch. - `resource` is validated syntax-only (absolute URI, no fragment) — pass-through, no resource registry; the resource server enforces the audience on introspection - threaded from authorize / device_authorization onto the auth/device code, then the access and refresh tokens, and carried across refresh rotation - invalid values are rejected with error=invalid_target - introspection `aud` is the bound resource, falling back to the client_id - ADR 0004 records the pass-through-vs-registry decision Completes the clinch-side OAuth surface for MCP connectors (with DCR + introspection); Protected Resource Metadata (RFC 9728) lives on the resource server. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01F7cwhwDJp3MJJDoNPVE6zq
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
7149b98b7b
commit
2defa26a87
@@ -0,0 +1,12 @@
|
||||
class AddResourceToOidcTokens < ActiveRecord::Migration[8.1]
|
||||
# RFC 8707 Resource Indicators: the audience (target resource server) a token
|
||||
# is bound to. Threaded from the authorize / device_authorization request
|
||||
# through the code and carried across refresh rotation onto the access token,
|
||||
# where introspection reports it as `aud`.
|
||||
def change
|
||||
add_column :oidc_authorization_codes, :resource, :string
|
||||
add_column :oidc_device_codes, :resource, :string
|
||||
add_column :oidc_access_tokens, :resource, :string
|
||||
add_column :oidc_refresh_tokens, :resource, :string
|
||||
end
|
||||
end
|
||||
Generated
+5
-1
@@ -10,7 +10,7 @@
|
||||
#
|
||||
# It's strongly recommended that you check this file into your version control system.
|
||||
|
||||
ActiveRecord::Schema[8.1].define(version: 2026_07_19_000002) do
|
||||
ActiveRecord::Schema[8.1].define(version: 2026_07_19_000003) do
|
||||
create_table "active_storage_attachments", force: :cascade do |t|
|
||||
t.bigint "blob_id", null: false
|
||||
t.datetime "created_at", null: false
|
||||
@@ -123,6 +123,7 @@ ActiveRecord::Schema[8.1].define(version: 2026_07_19_000002) do
|
||||
t.datetime "created_at", null: false
|
||||
t.datetime "expires_at", null: false
|
||||
t.integer "oidc_authorization_code_id"
|
||||
t.string "resource"
|
||||
t.datetime "revoked_at"
|
||||
t.string "scope"
|
||||
t.string "token_hmac"
|
||||
@@ -149,6 +150,7 @@ ActiveRecord::Schema[8.1].define(version: 2026_07_19_000002) do
|
||||
t.datetime "expires_at", null: false
|
||||
t.string "nonce"
|
||||
t.string "redirect_uri", null: false
|
||||
t.string "resource"
|
||||
t.string "scope"
|
||||
t.datetime "updated_at", null: false
|
||||
t.boolean "used", default: false, null: false
|
||||
@@ -173,6 +175,7 @@ ActiveRecord::Schema[8.1].define(version: 2026_07_19_000002) do
|
||||
t.integer "interval", default: 5, null: false
|
||||
t.datetime "last_polled_at"
|
||||
t.string "nonce"
|
||||
t.string "resource"
|
||||
t.string "scope"
|
||||
t.string "status", default: "pending", null: false
|
||||
t.datetime "updated_at", null: false
|
||||
@@ -193,6 +196,7 @@ ActiveRecord::Schema[8.1].define(version: 2026_07_19_000002) do
|
||||
t.datetime "expires_at", null: false
|
||||
t.integer "oidc_access_token_id", null: false
|
||||
t.integer "oidc_authorization_code_id"
|
||||
t.string "resource"
|
||||
t.datetime "revoked_at"
|
||||
t.string "scope"
|
||||
t.integer "token_family_id"
|
||||
|
||||
Reference in New Issue
Block a user