Concepts
Dynamic Client Registration (RFC 7591/7592)
Let third-party developers — and MCP clients — register OAuth clients against your project without a manual ticket.
Dynamic Client Registration (DCR), defined in RFC 7591, is the OAuth 2.0 extension that lets a client tell the authorization server “here is my metadata, please mint me a client_id.” The companion RFC 7592adds GET / PUT / DELETE on the registration so the client can later read, update, or revoke its own row.
The four DCR modes
Every Authio project has a dcr_mode column that decides how POST /oauth2/register behaves. The default for non-MCP projects is disabled; MCP-flagged projects default to initial_access_token with CIMD as the primary path (see the MCP integration guide).
| Mode | Auth required | Best for |
|---|---|---|
disabled | n/a — endpoint returns 403 registration_not_allowed | Default for non-MCP projects. |
admin | Project-admin dashboard session. | Operator-controlled approval; mirrors WorkOS Connect’s dashboard-only flow. |
initial_access_token | Authorization: Bearer iatk_…— an IAT the operator hands out. | Programmatic registration with per-IAT scope and redirect-URI clamps. |
open | None. Rate-limited to 50/h/IP and 1000/h/project. | Federated registration for “AI agents anywhere on the internet.” Explicit footgun for non-MCP. |
https://attacker.example.com/cb can then trick a signed-in user into authorising that client and leak the resulting code. Use initial_access_token mode unless you have specifically modeled the open-mode threat.Initial Access Tokens (IATs)
An IAT is a project-scoped bearer the operator generates in the dashboard (Settings → Connect / MCP → Issue IAT). The raw token looks like iatk_<43-char base64url> and is shown to the operator exactly once; only a SHA-256 hash is persisted, so a database compromise cannot replay outstanding IATs.
Each IAT can carry:
- Allowed scopes: the requested
scopeon registration is clamped to this set; extras are dropped silently. - Redirect-URI templates: each requested
redirect_urimust match one of these by exact string or by a single trailing*wildcard on the path. The operator can pre-constrain the registrant to “only redirect URIs under your domain.” - Expiry. After
expires_at, the IAT silently stops working.
Round-trip example (admin mode)
The dashboard’s management API attaches an X-Authio-DCR-Admin: 1 header after verifying the caller’s project-admin role. The raw HTTP looks like this:
POST /oauth2/register HTTP/1.1
Host: auth-api.authio.com
X-Authio-Project: proj_acme_prod
X-Authio-DCR-Admin: 1
Content-Type: application/json
{
"redirect_uris": ["https://acme.example.com/oauth/callback"],
"client_name": "Acme Workspace",
"client_uri": "https://acme.example.com",
"tos_uri": "https://acme.example.com/tos",
"scope": "openid email profile",
"token_endpoint_auth_method": "client_secret_basic"
}
Response (RFC 7591 §3.2.1):
HTTP/1.1 201 Created
Content-Type: application/json
Cache-Control: no-store
{
"client_id": "client_8f3c1a2b9d4e5f6071829304",
"client_secret": "dsc_9pXbW7…",
"client_secret_expires_at": 0,
"client_id_issued_at": 1730000000,
"registration_access_token": "rat_3jKLm…",
"registration_client_uri": "https://auth-api.authio.com/oauth2/register/client_8f3c1a2b9d4e5f6071829304",
"redirect_uris": ["https://acme.example.com/oauth/callback"],
"client_name": "Acme Workspace",
"scope": "openid email profile",
"token_endpoint_auth_method": "client_secret_basic"
}
Self-managing the registration (RFC 7592)
The registration_access_token in the response is a bearer scoped to this one row. The client then:
GET /oauth2/register/{client_id}— fetch the current metadata.PUT /oauth2/register/{client_id}— replace it (subject to the same validation as registration).DELETE /oauth2/register/{client_id}— soft-delete.
Like the IAT, the registration access token is shown exactly once; only the SHA-256 hash is persisted. Lose it and the client must be re-registered.
Rate limits
dcr_register_ip— 50 requests / hour per (project, IP). Applies in every mode.dcr_register_project— 1000 requests / hour per project. Applies inopenmode only.
Discovery
Authio publishes the RFC 8414 Authorization Server Metadata document at /.well-known/oauth-authorization-server. The registration_endpoint field always points at /oauth2/register; the per-project mode rejection happens at the endpoint, not in the metadata document, so an MCP client doing discovery does not need a project context yet.
