CIMD vs. DCR - Which One Should Register Your Agents?

Ok. Client registration. I know, super exciting stuff. Stay with me though, because this is becoming one of the more consequential design decisions in the agentic IAM lifecycle and almost nobody I know is talking about it.

Here’s the issue. Before any OAuth flows can happen, the authorization server has to know what it’s talking to. That’s typically done via a client_id. For twenty years, getting one meant a human had to log into a developer portal, fill out a form, and got a string back. That’s fine for a world where you register a handful of apps a year.

That world, as we knew it, is over. An MCP-connected agent might need to talk to a server it has never seen and might never see again. Multiply that by every agent, every server, every session, and you have an exponential problem. Pre-registration really stops making sense as a path forward at the scale we’re seeing AI need it.

Two answers exist right now: Dynamic Client Registration (DCR, RFC 7591) and Client ID Metadata Documents (CIMD, still a draft). They solve overlapping but not identical problems, and I want to make sure that you pick the right one for your archiutecture.


DCR: Automate the Form, Keep the Registry

DCR takes the “developer fills out a form” model and makes it programmatic. A client POSTs its metadata to a registration endpoint and gets a client_id, optionally a client_secret, and a registration access token back:

POST /register
Content-Type: application/json

{
  "client_name": "My Agent",
  "redirect_uris": ["https://myagent.example.com/callback"],
  "grant_types": ["authorization_code"],
  "token_endpoint_auth_method": "none"
}

The authorization server stores that record. Every future request from this client gets matched against it. That’s the entire innovation: do this thing so a human doesn’t have to.

It’s mature, but not very widely used RFC 7591 has been around since 2015 and Keycloak, Okta, Auth0, and basically every serious IdP supports it. If you need something that works today, in prod, DCR is not a risky bet.

It gives the AS a real audit trail before the fact. Every client that’s ever going to talk to your authorization server exists as a row in a database the moment it registers, so if you need to answer “what clients can talk to us” at any point in time, DCR can give you that. CIMD does not, and I’ll get to why that matters in a second.

It works fine in closed populations. If your client population is bounded, known to you, and not exploding (like most enterprise orgs), DCR is fine. It’s not like it’s a broken or outdated RFC. This is important because I do not want this article to give off a “DCR is dead” message. This claim is just an inflation that “DCR doesn’t scale to open agentic ecosystems” into “DCR is bad,” and that’s just not true. DCR has it’s place, I just think it’s not with Agentic identities.

Now the part where it starts to fall apart..

Open registration means anyone can register. That’s the entire point of the protocol, and it’s also the entire problem. Nothing in RFC 7591 verifies that the client_name you submit is actually you. A phishing operation can register a client called “Okta Admin Portal” with a redirect URI they control, and the authorization server has no native way to know the difference between that and the real thing. The spec even acknowledges this indirectly by recommending rate limiting and initial access tokens for open endpoints, which is a tell that they knew this was going to be a soft spot.

The registry potentially only grows. Nothing forces cleanup on this. And when’s the last time YOU went through all of your orgs applications and made sure they we’re legitimate and up to date? Agents that ran once and never came back will still have a client_id sitting in your database a year later if they’re not automatically de-registered. Multiply that by an agentic population that can spin up thousands of ephemeral instances per hour and you’ve built yourself a very large, very stale table that somebody eventually has to reconcile.

It puts every AS in the business of running a registry. This is a real operational cost.. You’re not just validating tokens anymore, you’re the permanent system of record for every client that’s ever knocked on your door, forever, with all the lifecycle and cleanup obligations that come with that.

That’s going to be a you problem and DCR hands it to every authorization server operator individually, at scale.


CIMD: The Client’s Identity Is a URL It Controls

CIMD takes this model and flips it on it’s head. Instead of registering with the server, the client publishes a JSON metadata document at a stable HTTPS URL, just like you would with a JWKS endpoint. The difference is that the URL is the client_id:

{
  "client_id": "https://myagent.example.com/oauth/metadata.json",
  "client_name": "My Agent",
  "client_uri": "https://myagent.example.com",
  "redirect_uris": ["https://myagent.example.com/oauth/callback"]
}

The authorization request then just uses the URL directly:

GET /authorize?client_id=https://myagent.example.com/oauth/metadata.json&...

Note that no registration call happens here. The authorization server fetches the metadata document, checks that it’s valid JSON, and confirms the URL it fetched from matches the claimed client_id. There is no registration step to skip.

This is the OAuth working group’s actual answer to the MCP scaling problem (draft-ietf-oauth-client-id-metadata-document, adopted October 2025), and MCP’s November 2025 spec already recommends it as the preferred default for client registration. That’s not by mistake. The industry looked at DCR and said “we need something else for this.”

Almost zero setup, really. An agent can complete a full OAuth flow with a server it has never encountered, no pre-coordination, no registration call, and no waiting on anyone’s approval. This is the “thousands of MCP servers we have never seen before” problem solved at the protocol level at scale.

Identity is tied to domain ownership, not to a self-reported string. The authorization server isn’t trusting whatever client_name you typed into a form. It’s trusting that you control the content served at a specific URL, just like .well-known endpoints are used for right now for OAuth. This is a much stronger claim than DCR’s “cause I said so.” It doesn’t verify you’re trustworthy, but it does verify that you’re you.

Stale entries fix themselves. If the metadata document disappears, the next auth attempt simply fails. There’s no registry to prune because there’s no persistent registry at all. The authorization server’s storage burden drops to whatever it wants to cache.

Here’s why I think the rest of the industry is going to start using CIMD instead of building their own thing:

It’s not just a spec exercise. WorkOS, Stytch, Authlete, and Descope have all shipped CIMD support or guidance in the last several months. Just like ID-JAG, when we see implementations show up before the RFC number exists, that’s usually a solid sign that the thing is solving a real problem.

It matches how the web already works. Domain ownership as a trust signal isn’t new, it’s basically how TLS certificates, DKIM, JWKS, and a dozen other web trust mechanisms already operate. CIMD isn’t inventing a new trust primitive, it’s applying one everyone already relies on to the OAuth client identity problem.

Now, the honest caveats, because nothing is perfect and I’d be lying if I said this was a solved problem..

Localhost impersonation is real and currently unsolved. A malicious local app can impersonate a legitimate desktop client using the same redirect URI pattern, and CIMD’s domain-ownership model doesn’t fully close that gap on its own. I’ve heard that Software Statements could potentially be used as a layer on top to close that gap, but that’s an additional piece and not something CIMD gives you out of the box.

Fetching a URL you don’t control is its own attack surface. SSRF risk is a real consideration when your authorization server is dereferencing arbitrary client-supplied URLs. This is solvable with standard mitigations, but it’s one more thing your implementation has to get right that DCR never needed.

It’s a draft, not an RFC. Support is real and growing fast, but you’re still building against a bit of moving target. Nothing new for AI developers. Move fast and break things is the motto, but if your organization requires something official with a final RFC number before it touches production, CIMD isn’t there yet. Give it some time. I don’t think it’ll take long, but it’s not there today.


So Which One Do You Actually Use

My take is that this isn’t really a “pick a winner” situation, it’s a “match the tool to the population” situation.

Closed, bounded, enterprise-managed client population? DCR is fine. Genuinely fine. You want the registry, you want the audit trail, you probably want a human or a policy gate in the loop before a new client gets minted anyway. Nothing about agentic identity breaks that model when the population is known and finite.

Open, high-scale, ephemeral agent population talking to servers it’s never met? This is a scenario that DCR was never built for and CIMD was built specifically to solve. If you’re running or building an MCP-exposed service that agents from the open internet are going to hit, CIMD is where the ecosystem is headed, and building against DCR here is a big mistake.

To be clear on both counts: neither of these solves the deeper agentic IAM questions I’ve written about before. Knowing which client is talking to you isn’t the same as knowing whether it should be allowed to do what it’s asking to do, or whether the human it claims to be acting for actually said yes. CIMD and DCR both answer “who is this,” full stop. Delegation, scope, and behavioral trust are separate problems that live on top of whichever registration model you pick.


TL;DR

  • DCR (RFC 7591) automates the old “fill out a form, get a client_id” model. It’s mature, widely supported, and gives you a real registry and audit trail — but it doesn’t verify identity, the registry only grows, and it puts every AS in the business of lifecycle-managing clients it may never see again.
  • CIMD (draft-ietf-oauth-client-id-metadata-document) makes the client_id an HTTPS URL that resolves to a JSON metadata document. No registration call, no stale registry, identity grounded in domain ownership instead of a self-reported string.
  • CIMD is already MCP’s recommended default for exactly the problem DCR can’t scale to: agents talking to thousands of servers they’ve never met.
  • CIMD’s open caveats are real: localhost impersonation is unsolved, domain trust isn’t permanent trust, and it’s still a draft, not an RFC.
  • Use DCR for closed, bounded, enterprise-managed populations. Use CIMD for open, high-scale, ephemeral agent ecosystems. Neither one answers the delegation or behavioral trust questions, those are still yours to solve.