Concept
OAuth 2.1 with Dynamic Client Registration
knowmind is an OAuth 2.1 provider with Dynamic Client Registration per RFC 7591. Custom connectors in Claude.ai, ChatGPT and Cursor register themselves automatically — nobody manually creates a client or pastes a secret.
What this is about
Classic OAuth setups require a pre-configured client app: a client ID, a client secret, and a hard-wired redirect URI. For custom connectors in browser AI tools that is impractical — the client only exists once the user adds it. The IETF specified RFC 7591 for exactly this case: the client registers itself with the authorization server at runtime. knowmind permits this only for custom connectors whose redirect URIs match an allowlist of MCP-capable platforms.
Sequence in detail
- Discovery: the connector reads the OAuth discovery metadata at
/.well-known/oauth-authorization-server. knowmind responds with every endpoint, the supported grant types, and the PKCE requirement S256. - Registration: the connector calls
POST /oauth/registerwith its name and its redirect URIs. knowmind checks the URIs against the allowlist (see table below), creates an oauth_clients record withtenant_id = NULLand returns a client ID. No client secret is issued — public client with PKCE. - Authorization request: the connector sends the user to
/oauth/authorizewithresponse_type=code,client_id,redirect_uri,scope, a randomstate, acode_challenge(Base64-URL encoded SHA-256 of the connector's locally storedcode_verifier), andcode_challenge_method=S256. - Login and consent: if the user is not yet signed in, knowmind redirects them to
/signin. Magic link in the mailbox, confirmation, return to the authorization page. On the user's first authorize the oauth_clients record'stenant_idis fixed to the signed-in user's tenant. Later authorize flows with the same client ID must hit the same tenant. - Authorization code: knowmind generates a short-lived code (valid for 10 minutes), stores it along with the
code_challenge,redirect_uri,user_idandtenant_id, and redirects the connector with?code=…&state=…. - Token exchange: the connector calls
POST /oauth/tokenwithgrant_type=authorization_code, the received code, the originalredirect_uri, itsclient_idand thecode_verifier. knowmind verifies PKCE (SHA-256 ofcode_verifierequalscode_challenge), consumes the code, and returns a regular kmt_ access token valid for 30 days. - MCP calls: every MCP call carries the token in the
Authorization: Bearer kmt_…header. Normal tenant isolation applies — the token only sees the tenant the user authorized during the authorize flow.
Allowlist of permitted redirect hosts
knowmind accepts redirect URIs only on the following hosts (HTTPS required, localhost allowed for development):
| Host | Platform | Subdomain matching |
|---|---|---|
| claude.ai | Claude (Anthropic) — custom connectors | yes |
| claude.com | Claude (Anthropic) — alternative host | yes |
| chat.openai.com | ChatGPT (legacy host) | yes |
| chatgpt.com | ChatGPT — custom actions / connectors | yes |
| cursor.sh | Cursor — MCP integration | yes |
| cursor.com | Cursor — alternative host | yes |
| anysphere.com | Anysphere — Cursor maker | yes |
| 127.0.0.1 | Local development (HTTP allowed) | no |
| localhost | Local development (HTTP allowed) | no |
Subdomain matching: *.claude.ai is accepted, e.g. connectors.claude.ai. Any other redirect host is rejected with HTTP 400 and error: invalid_redirect_uri. If you want a different platform added, contact info@schuebeler-consulting.de.
Tenant binding on first login
When a connector has just registered through /oauth/register, knowmind does not yet know a tenant — the client record carries tenant_id = NULL. On the first authorize flow the tenant_id is wired to the tenant of the signed-in user and is then immutable. If a second user of the same connector tries to authorize with a different tenant, knowmind responds with HTTP 403 access_denied and the hint message "This OAuth client belongs to a different workspace".
Practical consequence: every user who adds a new custom connector runs through their own DCR registration. Multiple users in the same tenant do not share a single oauth_clients record.
Security properties
- PKCE is mandatory. knowmind rejects authorize requests without a
code_challengeor withcode_challenge_method ≠ S256with HTTP 400. This protects the authorization code against interception via open redirects or compromised browser extensions. - No client secrets.
token_endpoint_auth_method = none. Public client with PKCE replaces the classic client secret model. No pre-distribution of secrets to browser apps. - Short access token lifetime. Access tokens live for 30 days; the connector renews them by repeating the authorize flow (no refresh tokens are issued in the standard flow — connectors trigger the authorize loop automatically when needed).
- Revoke at any time. In the cockpit under OAuth Clients you see every registered connector and can revoke it with one click. The token becomes invalid immediately.
- State parameter required for CSRF protection. The connector sets a random
state, knowmind mirrors it on redirect, the connector checks for a match.