Authio docs

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).

ModeAuth requiredBest for
disabledn/a — endpoint returns 403 registration_not_allowedDefault for non-MCP projects.
adminProject-admin dashboard session.Operator-controlled approval; mirrors WorkOS Connect’s dashboard-only flow.
initial_access_tokenAuthorization: Bearer iatk_…— an IAT the operator hands out.Programmatic registration with per-IAT scope and redirect-URI clamps.
openNone. Rate-limited to 50/h/IP and 1000/h/project.Federated registration for “AI agents anywhere on the internet.” Explicit footgun for non-MCP.
Open mode is a footgun for non-MCP projects. An attacker that registers a client with a callback at 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 scope on registration is clamped to this set; extras are dropped silently.
  • Redirect-URI templates: each requested redirect_uri must 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 in open mode 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.