Dynamic client registration (RFC 7591) lets OAuth clients self-register. How DCR works, why MCP deprecated it for CIMD, and how to lock down open endpoints.
Every OAuth client needs a client_id before it can ask for a token. For a web app your own team builds, someone creates that ID in an admin console once and moves on. An AI agent or MCP client that meets a server for the first time at runtime has nobody to do that for it. Dynamic client registration (DCR) fills the gap by letting the client register itself, and in doing so it lets anyone who can reach the endpoint mint a client that looks trusted.
That trade-off is the whole story. This guide explains how dynamic client registration works on the wire, why the Model Context Protocol (MCP) built on it and has now deprecated it in favor of Client ID Metadata Documents, where open registration breaks, and which controls keep it governable. It's written for identity engineers, platform teams and MCP server builders who have to decide whether agents may register themselves. For the wider picture of how MCP clients, servers and users each get an identity, see our complete guide to MCP identity, which maps the full identity chain that registration plugs into.
Dynamic client registration is an OAuth 2.0 protocol, defined in RFC 7591, that lets a client register itself with an authorization server by sending its metadata to a registration endpoint and receiving a client_id in return, without an administrator creating the client by hand.
OAuth dynamic client registration happens before any authorization flow starts. An authorization server that supports it publishes a registration_endpoint in its authorization server metadata (RFC 8414), so a client can discover where to register without configuration. OpenID Connect has a closely aligned profile, OpenID Connect Dynamic Client Registration 1.0, which adds fields such as application_type. When people say "DCR OAuth" they usually mean either one.
DCR fits ecosystems where clients and servers have no prior relationship: developer platforms that onboard third-party apps, federations where a trusted body signs client metadata, and agent ecosystems where a client may talk to hundreds of servers. In each case the registration endpoint decides who becomes a trusted client. Registration is an identity decision. Treat it like one.
The protocol is a single HTTP exchange followed by a normal OAuth flow. The client describes itself, the authorization server decides whether to accept that description, and the result is a client identity the server will recognize from then on.
registration_endpoint.client_id, plus a client_secret if the client will authenticate as a confidential client.client_id.A registration request is a JSON body of client metadata. Here is a minimal request from a native MCP client that listens on a loopback redirect and authenticates with PKCE only:
POST /register HTTP/1.1
Host: auth.example.com
Content-Type: application/json
Authorization: Bearer <initial-access-token, if the server requires one>
{
"client_name": "Example MCP Client",
"redirect_uris": ["http://127.0.0.1:33418/callback"],
"grant_types": ["authorization_code", "refresh_token"],
"response_types": ["code"],
"token_endpoint_auth_method": "none",
"application_type": "native"
}
Every field is a claim the client makes about itself. That's why the fields matter as much for governance as for plumbing:
| Field | What it declares | Why it matters for governance |
|---|---|---|
client_name | Human-readable name shown on the consent screen | Self-asserted. Anyone can call their client "Corporate Assistant" unless the server verifies it. |
redirect_uris | Where authorization codes may be delivered | The single most security-critical field. A bad value sends codes to an attacker. |
grant_types / response_types | Which OAuth flows the client will use | Restrict to authorization_code and refresh_token for interactive clients. |
token_endpoint_auth_method | How the client authenticates at the token endpoint (none, client_secret_basic, client_secret_post, or an extension such as private_key_jwt) | none marks a public client that relies on PKCE. Policy should decide which methods are acceptable. |
jwks / jwks_uri | The client's public keys, inline or by URL (never both) | jwks_uri makes the server fetch an attacker-chosen URL. |
logo_uri, client_uri, policy_uri, tos_uri | Branding and legal links for the consent screen | Spoofing surface, and another server-side fetch if logos are proxied. |
scope | Scopes the client intends to request | Cap it per policy rather than accepting whatever is asked for. |
software_id / software_version | Identifies the software across many installed instances | Lets you group sprawl: one product, thousands of registrations. |
software_statement | A signed JWT of client metadata from a software publisher | The main way to replace self-assertion with a vouched claim. |
On success the server answers 201 Created with the registered metadata plus the identity it issued: a client_id, an optional client_id_issued_at, and for confidential clients a client_secret with client_secret_expires_at (where 0 means the secret never expires). The server may also change or drop values it doesn't accept, so a client should read the response rather than assume its request was honored verbatim.
Servers that implement the companion management protocol, RFC 7592, also return a registration_access_token and a registration_client_uri. Together they let the client read, update or delete its own registration later. When a request is rejected, RFC 7591 defines error codes such as invalid_redirect_uri, invalid_client_metadata, invalid_software_statement and unapproved_software_statement, which give a policy engine clean ways to say no.
MCP dynamic client registration is the most visible use of RFC 7591 today, and also the clearest example of a standard being replaced. Understanding why both happened tells you how to plan your own registration policy.
Authorization is optional in MCP, but when a server uses it, the spec requires the client to obtain a client_id before the flow begins. That's easy for one client and one server. It's not easy when any of thousands of MCP clients (desktop assistants, IDEs, agent frameworks) may connect to any of thousands of servers, each fronted by a different authorization server. Pre-registering every pair is impossible, and RFC 7591 already existed as a standard answer. Earlier revisions of the MCP authorization spec, through 2025-06-18, said clients and authorization servers SHOULD support DCR, which made it the main way for a client to get an identity at a server it had never seen.
If you want the full sequence that registration slots into (discovery, consent, PKCE, token use), our guide to how MCP authentication works end to end walks through each step. For background on the protocol itself, see the Frontegg overview of the Model Context Protocol.
The current revision, dated 2026-07-28, keeps DCR but formally retires it as the default. Its authorization overview says authorization servers and MCP clients MAY support RFC 7591 and adds: "Note that Dynamic Client Registration is deprecated and retained for backwards compatibility with authorization servers that do not support Client ID Metadata Documents." The same revision says they SHOULD support OAuth Client ID Metadata Documents.
| MCP spec revision | Status of DCR | Client ID Metadata Documents |
|---|---|---|
| Earlier revisions (through 2025-06-18) | The main registration path for clients without a prior relationship | Not yet defined |
| 2025-11-25 (Final) | MAY, "included for backwards compatibility with earlier versions of the MCP authorization spec"; not deprecated | Introduced at SHOULD |
| 2026-07-28 (current) | MAY, deprecated; new implementations SHOULD NOT adopt it; migration path is CIMD | SHOULD; described as the most common case, where client and server have no prior relationship |
| First revision released on or after 2027-07-28 | Earliest point at which DCR can be removed | Expected default |
Deprecation here is a scheduled exit, not an outage. The spec's versioning policy keeps a deprecated feature in the specification for at least twelve months (ninety days only under an expedited-removal exception), and DCR's earliest removal is the first revision released on or after 2027-07-28, so DCR-only authorization servers keep working in the meantime.
application_type. When registering through DCR, MCP clients MUST specify an appropriate application_type (native or web). OpenID Connect defaults to web, which is wrong for a desktop client on a loopback redirect.issuer and re-register if the server changes. A DCR client_id is not portable; a CIMD client_id is.
client_id_metadata_document_supported.registration_endpoint.If none of these is workable for your environment (for example, your identity provider offers no registration of any kind), the usual fix is an authorization server in front of it, covered later in this guide.
Three models can give an MCP client its identity. They differ in where trust comes from, how much state the server holds, and who carries the risk when a client lies about itself.
OAuth Client ID Metadata Documents (CIMD) flip the registration model. Instead of POSTing metadata to be stored, the client publishes its metadata as a JSON document at an HTTPS URL, and that URL is the client_id. When the client starts an authorization request, the server fetches the document, checks that the client_id inside it matches the URL it was fetched from and that the requested redirect URI is one the document lists, then shows the user a consent screen naming the client and its hostname. CIMD is an active IETF OAuth working group draft, not yet an RFC.
client_id.client_id equals the URL and that the redirect URI is listed.CIMD doesn't remove the trust decision. It moves it. The MCP spec suggests trust policies such as allowlists of client hosts for closed deployments, accepting any HTTPS client_id for open servers, and signals such as domain reputation or domain age. A CIMD client_id is also portable: the same URL works at every authorization server, which is exactly what an ecosystem of many servers needs.
| Dimension | Dynamic client registration (DCR) | Client ID Metadata Documents (CIMD) | Pre-registration |
|---|---|---|---|
| How the client_id is created | Server issues it after a POST to the registration endpoint | The client's HTTPS metadata URL is the client_id | An administrator creates it ahead of time |
| Where trust comes from | Self-asserted metadata, optionally a software statement or initial access token | Control of the hosting domain, plus the server's trust policy | A human review before the client exists |
| Server-side state | One stored record per registration, which grows without bound if open | Fetched and cached documents; no registration database | One record per approved client |
| Portability across authorization servers | None; credentials are bound to one issuer | Full; one URL works everywhere | None; one registration per server |
| Main risk | Unauthenticated registration, spoofed names, hijacked redirects, sprawl | SSRF on fetch, lookalike domains, localhost redirect impersonation | Doesn't scale to unknown clients; manual lifecycle |
| Best fit | Legacy MCP clients and authorization servers without CIMD; gated enterprise use | Open ecosystems where clients and servers have never met | Closed enterprises and small, known client sets |
| MCP spec status (2026-07-28) | MAY, deprecated | SHOULD | First in the client selection order |
| Standard status | RFC 7591, IETF Proposed Standard | IETF Internet-Draft (rev 02) | Core OAuth; no extra protocol |
The DCR vs CIMD question has a different answer depending on who your clients are. Start from the environment, not the protocol:
An open registration endpoint is an unauthenticated API that creates trusted identities. Put that way, the failure modes are predictable. Each one below exploits the same gap: the server accepts what a client says about itself and then shows that claim to a user who is asked to trust it.
If the endpoint accepts anonymous POSTs, anyone can create clients, and scripts can create millions. Even without an attacker, sprawl happens naturally: every reinstall of a desktop client may register again, leaving thousands of client_ids that no one owns, no one reviews and nothing expires. Each one is a credential the server still honors. The control is an initial access token or a software statement, plus rate limits and expiry.
client_name and logo_uri are whatever the requester typed. An attacker registers "Corporate Assistant" with your logo, and the consent screen faithfully presents it. RFC 7591 warns that self-asserted metadata should be treated as unverified and suggests showing users that it is. The control is verified metadata (via software statements) and showing the redirect hostname, which is harder to fake than a display name.
The attacker registers a client whose redirect_uris points at a domain they control, then sends a victim a legitimate-looking authorization link. The victim logs in to the real identity provider, approves the lookalike client, and the authorization code lands on the attacker's server. Loose redirect matching (wildcards, prefix matches) makes this worse. Loopback redirects are a quieter variant: a malicious local app can claim the same localhost port, which is why the MCP spec says servers SHOULD display additional warnings for localhost-only redirect URIs. Exact redirect URI matching is the baseline defense in RFC 9700.
Several metadata fields are URLs the authorization server may fetch: jwks_uri for keys, logo_uri if logos are proxied, and with CIMD the client_id itself. If the server fetches without restrictions, an attacker can point it at internal addresses such as cloud metadata services. This is server-side request forgery (SSRF), where the attacker makes your server send requests on their behalf. The control is a hardened fetcher: block private and link-local ranges, refuse redirects, cap size and time, as OWASP guidance recommends.
Some MCP servers act as proxies to a third-party API and use one static client_id at that third party's authorization server, while letting MCP clients register dynamically with the proxy. If a user has already consented to the static client, the third party may skip consent on the next request, and an attacker's freshly registered client can ride that consent to obtain an authorization code. The MCP spec closes this by requiring that MCP proxy servers using static client IDs MUST obtain user consent for each dynamically registered client before forwarding to third-party authorization servers. Our guide to MCP security risks covers the confused deputy alongside token passthrough, tool poisoning and the rest of the MCP threat model.
You can run DCR safely, but only if you decide up front that registration is a privileged operation. These controls map directly to the failure modes above:
| Control | What it stops | Reference |
|---|---|---|
| Initial access token required to register | Anonymous registration, scripted sprawl | RFC 7591 |
| Software statements signed by publishers you trust | Spoofed names, logos and redirect URIs | RFC 7591 |
Trusted-host allowlists for redirect URIs, jwks_uri and CIMD hosts | Attacker-controlled redirects and fetch targets | Server policy; MCP spec CIMD trust policies |
| Rate limits and per-tenant quotas on the registration endpoint | Registration floods, database growth | Server policy |
| Exact redirect URI matching, no wildcards | Redirect hijacking, code theft | OAuth 2.1, RFC 9700, MCP spec (MUST) |
| Per-client consent, never shared across client_ids | Consent reuse, confused deputy | MCP spec (MUST for proxies) |
Restricted metadata: allowed grant types, PKCE required, approved auth methods, correct application_type | Clients requesting flows they should never use | RFC 7591 error codes; MCP spec |
| Hardened fetcher for every metadata URL | SSRF | MCP spec; CIMD draft; OWASP |
| Expiry of unused registrations and secrets | Orphaned clients that still work | client_secret_expires_at (RFC 7591); server policy |
| Registration management endpoint with its own token | Clients that can't rotate or clean up after themselves | RFC 7592 (Experimental) |
Initial access tokens vs software statements. An initial access token answers "is this caller allowed to register at all?" You issue it out of band, for example to a developer who has requested access, and it can be single-use or scoped to one tenant. A software statement answers "is this metadata true?" A publisher you trust signs it, and the server prefers its values over anything in the request body. Closed environments usually need the first; federated ecosystems need the second. Many need both.
Exact redirect matching is non-negotiable. OAuth 2.1 drops the loose matching that older deployments tolerated, and the MCP spec requires authorization servers to validate exact redirect URIs against registered values. See our breakdown of exact redirect URI matching in OAuth 2.1 and the other changes that matter for agents.
Expire what nobody uses. Track the last time each registration obtained a token, and delete registrations that have been idle past a threshold you set. Short-lived secrets help, but a public client with no secret never expires on its own.
Treat RFC 7592 with care. The management protocol is useful because it lets clients rotate secrets and delete themselves. It's also Experimental, not Standards Track, and the registration_access_token it issues is a credential that can rewrite a client's redirect URIs. Store it like a secret, and log every update.
Plenty of enterprise identity providers either don't offer a registration endpoint or offer one your security team won't enable. Some expose open DCR, some require an initial access token, and some are adding CIMD. None of that stops you from serving MCP clients. Three patterns cover most cases:
client_id per client per environment through the identity provider's admin API, and rotate secrets on a schedule. It's dynamic registration with a human in the loop.client_id into the MCP client. It works for power users and pilots. It doesn't scale.One caveat applies to all of them. A gateway that accepts DCR or CIMD becomes your registration endpoint, so every lockdown control above applies to it.
Here's the question that DCR, CIMD and pre-registration all leave open: once a client exists, who answers for it? A client_id that can obtain tokens is an identity, whether a human created it or an agent registered itself at 3 a.m. Agents and MCP clients are a fast-growing class of non-human identity, and they deserve the same rigor as a service account: an owner, a purpose, an expiry and a trail.
The more clients register themselves, the more the registration record becomes your source of truth. At minimum, every registered client should carry:
| Attribute | Why it matters |
|---|---|
| Named owner (person or team) | Someone to ask, and someone accountable, when the client misbehaves |
| Registration path (pre-registered, CIMD, DCR) and who approved it | Tells you how much the metadata can be trusted |
| Purpose and allowed scopes or MCP servers | Lets you spot a client requesting more than it was approved for |
| Created, last-used and expiry dates | Drives idle review and revocation |
| Consent grants and tokens issued, keyed by client_id and user | Ties every tool call back to a client and a human |
client_id.This is the accountability layer that registration protocols don't provide on their own. RFC 7591 tells you how a client gets an identity. It says nothing about who owns that identity next quarter, or how to trace a tool call made at 2 p.m. back to the client and the human behind it. That's where an identity foundation comes in: treating every agent and MCP client as a first-class identity with an owner, a scope and an audit trail, regardless of how it registered. It's the model behind the Agen identity foundation.
Use this sequence when you decide how agents and MCP clients will register in your environment:
registration_endpoint, which advertise client_id_metadata_document_supported, and which offer neither.jwks_uri, logos) against SSRF.No. In the current MCP specification (2026-07-28), authorization servers and clients MAY support Dynamic Client Registration, and the spec marks it deprecated, kept for backwards compatibility. Client ID Metadata Documents are the SHOULD-level path. Pre-registered client IDs remain valid too, so a server can work without any registration endpoint.
Only in MCP. The 2026-07-28 MCP revision deprecates DCR in favor of Client ID Metadata Documents, with removal possible no earlier than the first revision released on or after 2027-07-28. RFC 7591 itself is still an IETF Proposed Standard, and many OAuth deployments outside MCP continue to use it.
With DCR, a client POSTs its metadata to a registration endpoint and the authorization server stores it and issues a client_id. With CIMD (OAuth Client ID Metadata Documents), the client_id is an HTTPS URL pointing to a metadata document the server fetches on demand, so no per-client registration database is required.
Not by default. An unauthenticated registration endpoint lets anyone create a client with any name, logo and redirect URI, which enables consent phishing, client sprawl and SSRF. Constrain it with initial access tokens or software statements, exact redirect URI matching, rate limits, per-client consent and expiry of unused registrations.
A software statement is a signed JSON Web Token (JWT), defined in RFC 7591, that carries client metadata asserted by a software publisher. The client includes it in its registration request, and the authorization server verifies the signature against keys it trusts, so values like client_name and redirect_uris come from a vouched source rather than the requester.
Put an authorization server or gateway in front of the identity provider. It advertises CIMD (and DCR, if you need the fallback) to MCP clients, federates user login to your identity provider through one pre-registered client, and enforces registration policy itself. For a small, known client set, plain pre-registration is simpler.
Yes. An authorization server can advertise both a registration_endpoint and client_id_metadata_document_supported in its metadata. MCP clients that follow the current spec prefer CIMD when it is advertised, while older clients that only know DCR keep registering through the endpoint, so you can migrate gradually and retire DCR later.
RFC 7591 is the IETF Proposed Standard that defines OAuth 2.0 Dynamic Client Registration. It specifies the registration endpoint, the client metadata a client can submit, software statements, initial access tokens and the response that returns a client_id. Its companion, RFC 7592, adds an Experimental protocol for reading, updating and deleting registrations.
Dynamic client registration answers how a client gets an identity. The harder question is who owns that identity once it exists. If you want to see how that works in practice, the Agen identity foundation treats every agent as a first-class machine identity with a named owner and a human authority chain, so every action traces back to a person.
Keep reading
Workload identity federation lets services and AI agents get short-lived cloud credentials from a configured trust relationship, not a stored secret.
Written by
Agen.co
OAuth 2.1 consolidates OAuth 2.0 and its security best practices: mandatory PKCE, no implicit grant, exact redirect matching. Plus what it means for AI agents.