mirror of
https://github.com/n8n-io/n8n.git
synced 2026-10-17 13:39:44 +02:00
Recognize an HTTPS-URL client_id as a Client ID Metadata Document (CIMD): the server fetches the client's OAuth metadata from that URL and uses it as the verifiable client identity, instead of requiring Dynamic Client Registration. DCR stays available and unchanged for clients that don't support CIMD. Backend: - New CimdMetadataHttpClient fetches the document. The client_id URL is attacker-influenced and fetched pre-auth, so the request is always routed through the SSRF filter regardless of N8N_SSRF_PROTECTION_ENABLED; the document is validated (HTTPS, redirect_uris present, client_id matches the URL) and cached. - The clients store resolves a URL client_id from its cached document, which stays the source of truth; a row is persisted only to satisfy the consent/token foreign keys, marked isCimd and excluded from the registered-client cap (which bounds anonymous DCR). - Per the CIMD trust model the requested redirect_uri is validated against the document's declared redirect_uris (by the SDK) rather than the instance redirect-URI allowlist. - Gated behind N8N_OAUTH_SERVER_CIMD_ENABLED (default on). Frontend: - CIMD clients get a dedicated trust card on the consent screen: the verifiable domain, where the authorization code is sent (green check for loopback, a neutral host line otherwise), and an honest caveat that the name/icon are self-reported and unreviewed, with a link to the raw metadata document. They skip the manual redirect-trust acknowledgement DCR clients still require. - The connected-clients settings show a "Verified" badge for CIMD clients. Adds an isCimd column to oauth_clients (migration) and exposes isCimd on the OAuth client and consent-details payloads.
3.7 KiB
3.7 KiB
oauth_authorization_codes
Description
Table Definition
CREATE TABLE "oauth_authorization_codes" ("code" varchar(255) PRIMARY KEY NOT NULL, "clientId" varchar NOT NULL, "userId" varchar NOT NULL, "redirectUri" varchar NOT NULL, "codeChallenge" varchar NOT NULL, "codeChallengeMethod" varchar(255) NOT NULL, "expiresAt" bigint NOT NULL, "state" varchar, "used" boolean NOT NULL DEFAULT (false), "createdAt" datetime(3) NOT NULL DEFAULT (STRFTIME('%Y-%m-%d %H:%M:%f', 'NOW')), "updatedAt" datetime(3) NOT NULL DEFAULT (STRFTIME('%Y-%m-%d %H:%M:%f', 'NOW')), "resource" varchar, "scope" text NOT NULL DEFAULT ('["tool:listWorkflows","tool:getWorkflowDetails"]'), CONSTRAINT "FK_e829ca1240b877f73fd5fab14a2" FOREIGN KEY ("userId") REFERENCES "user" ("id") ON DELETE CASCADE ON UPDATE NO ACTION, CONSTRAINT "FK_81de58036895ccabf2214c6d99e" FOREIGN KEY ("clientId") REFERENCES "oauth_clients" ("id") ON DELETE CASCADE ON UPDATE NO ACTION)
Columns
| Name | Type | Default | Nullable | Children | Parents | Comment |
|---|---|---|---|---|---|---|
| clientId | varchar | false | oauth_clients | |||
| code | varchar(255) | false | ||||
| codeChallenge | varchar | false | ||||
| codeChallengeMethod | varchar(255) | false | ||||
| createdAt | datetime(3) | STRFTIME('%Y-%m-%d %H:%M:%f', 'NOW') | false | |||
| expiresAt | bigint | false | ||||
| redirectUri | varchar | false | ||||
| resource | varchar | true | ||||
| scope | TEXT | '["tool:listWorkflows","tool:getWorkflowDetails"]' | false | |||
| state | varchar | true | ||||
| updatedAt | datetime(3) | STRFTIME('%Y-%m-%d %H:%M:%f', 'NOW') | false | |||
| used | boolean | false | false | |||
| userId | varchar | false | user |
Constraints
| Name | Type | Definition |
|---|---|---|
| - (Foreign key ID: 0) | FOREIGN KEY | FOREIGN KEY (clientId) REFERENCES oauth_clients (id) ON UPDATE NO ACTION ON DELETE CASCADE MATCH NONE |
| - (Foreign key ID: 1) | FOREIGN KEY | FOREIGN KEY (userId) REFERENCES user (id) ON UPDATE NO ACTION ON DELETE CASCADE MATCH NONE |
| code | PRIMARY KEY | PRIMARY KEY (code) |
| sqlite_autoindex_oauth_authorization_codes_1 | PRIMARY KEY | PRIMARY KEY (code) |
Indexes
| Name | Definition |
|---|---|
| sqlite_autoindex_oauth_authorization_codes_1 | PRIMARY KEY (code) |
Relations
erDiagram
"oauth_authorization_codes" }o--|| "oauth_clients" : "FOREIGN KEY (clientId) REFERENCES oauth_clients (id) ON UPDATE NO ACTION ON DELETE CASCADE MATCH NONE"
"oauth_authorization_codes" }o--|| "user" : "FOREIGN KEY (userId) REFERENCES user (id) ON UPDATE NO ACTION ON DELETE CASCADE MATCH NONE"
"oauth_authorization_codes" {
varchar clientId FK
varchar_255_ code PK
varchar codeChallenge
varchar_255_ codeChallengeMethod
datetime_3_ createdAt
bigint expiresAt
varchar redirectUri
varchar resource
TEXT scope
varchar state
datetime_3_ updatedAt
boolean used
varchar userId FK
}
"oauth_clients" {
varchar_255_ clientSecret
bigint clientSecretExpiresAt
datetime_3_ createdAt
TEXT grantTypes
varchar id PK
boolean isCimd
boolean isFirstParty
varchar_255_ name
TEXT redirectUris
varchar_255_ tokenEndpointAuthMethod
datetime_3_ updatedAt
}
"user" {
datetime_3_ createdAt
boolean disabled
varchar_255_ email
varchar_32_ firstName
varchar id PK
date lastActiveAt
varchar_32_ lastName
boolean mfaEnabled
TEXT mfaRecoveryCodes
TEXT mfaSecret
varchar password
TEXT personalizationAnswers
varchar_128_ roleSlug FK
TEXT settings
datetime_3_ updatedAt
}
Generated by tbls