This guide is written by the team that builds Casdoor and describes the standards as published (listed under Sources), with notes on how Casdoor implements them as of November 3, 2026. Spotted a mistake? Tell us.
Dynamic client registration (DCR, RFC 7591) lets an OAuth or OpenID Connect client obtain a client_id by calling an API instead of asking an administrator to create one by hand. The client posts its metadata to the authorization server's registration endpoint, and the server returns credentials immediately.
It is the mechanism that makes "connect this app to any provider" work without per-deployment setup. It is also an open door if you turn it on without deciding who may register what.
Why it exists
A traditional OAuth integration assumes the client and the server know each other in advance. The administrator creates an application, copies the client ID and secret, and configures the redirect URI.
That model breaks when:
- The client is installed by many different organizations, each with its own provider.
- The client is a desktop, CLI or mobile app that cannot ship a shared secret.
- The client connects to arbitrary MCP servers or AI-agent endpoints discovered at runtime.
- The provider wants self-service onboarding instead of a manual ticket.
In those cases the client needs to register itself, at runtime, against the server it just discovered.
The registration request
A DCR request is a JSON object posted to the registration endpoint. The only required member is redirect_uris. Common members:
redirect_uris— one or more absolute URIs the server will redirect to.client_name— a human-readable name shown on consent pages.grant_types— for exampleauthorization_codeorrefresh_token.response_types— for examplecode.token_endpoint_auth_method—client_secret_basic,client_secret_post,private_key_jwtornonefor public clients.scope— the scopes the client intends to request.logo_uri,client_uri,contacts,software_id,software_version— metadata for display, support and inventory.
The server validates the metadata and responds with 201 Created:
client_id— required.client_secret— if the server issues one; public clients getnoneand no secret.client_id_issued_at,client_secret_expires_at—0means the secret does not expire.registration_access_tokenandregistration_client_uri— for RFC 7592 management.
RFC 7592 adds read, update and delete operations at the management URI, authenticated with the registration access token. Treat that token as a credential: it can rotate the client secret.
The security problem
Open registration means anyone who can reach the endpoint can create a client. That is fine for a public developer platform; it is not fine for an internal IdP that never intended to host third-party apps.
The realistic risks:
- Phishing redirects. An attacker registers a client with a redirect URI they control and a name that looks like a trusted app. Users see a real consent page and hand over access.
- Client sprawl. Automated scripts create thousands of clients, filling the database and the admin UI.
- Brand impersonation.
client_name,logo_uriandclient_uriare attacker-controlled unless validated. - Weak secrets. Public clients that should use PKCE and
token_endpoint_auth_method: noneget a client secret they cannot protect. - Abandoned clients. Old registrations keep valid secrets forever.
- Grant escalation. A client requests
client_credentialsorpasswordwhen it only needsauthorization_code.
Controls that belong in every deployment
- Default to off. Registration should be a deliberate setting, not something that appears with the first deployment.
- Scope it per tenant. One organization may allow self-registration; another may not.
- Validate redirect URIs strictly. Exact match, HTTPS except for loopback addresses (RFC 8252), no fragment, no wildcard, no userinfo. Reject
javascript:,data:and custom schemes you do not own. - Restrict grant types and response types to what the use case needs. Authorization code with PKCE covers most clients.
- Rate limit by IP and by tenant, and cap the number of clients.
- Expire unused clients and require re-registration, or at least rotate secrets.
- Log every registration with the metadata, source IP and time, and review the list periodically.
- Do not hand secrets to public clients. Use
token_endpoint_auth_method: noneplus PKCE, and do not rely on a secret embedded in a binary. - Moderate display metadata. Strip HTML from names and logos; show the redirect host on the consent page.
DCR versus CIMD
A newer pattern, the client ID metadata document (CIMD), removes the registration call entirely. The client uses an HTTPS URL as its client_id; the URL returns a JSON document with the client's metadata, and the server fetches it on demand.
| Pre-registered client | DCR (RFC 7591) | CIMD | |
|---|---|---|---|
| Who creates the client | Administrator | Client, at runtime | Client, by publishing a URL |
| Identity anchor | Server-issued ID | Server-issued ID | The client's own domain |
| Works across many providers | Manual setup per provider | Yes | Yes, if the server supports it |
| Server-side fetch required | No | No | Yes |
| Main risk | Stale manual config | Open registration abuse | SSRF, DNS and availability of the client domain |
| Typical user | Enterprise apps | MCP clients, developer platforms | MCP clients that own a stable domain |
CIMD is attractive for the MCP ecosystem because a client such as an AI assistant can identify itself with a domain it controls, and the same identity works against many servers. The cost moves to the server: it must fetch and validate remote documents safely, with timeouts, size limits and an allowlist policy.
DCR in Casdoor
Casdoor implements RFC 7591 registration and RFC 7592 management:
- The registration endpoint is
/api/oauth/register; management is/api/oauth/register/:clientId(GET, PUT, DELETE). - It is controlled per organization, by the Dynamic client registration switch on the organization. The stored policy is
openordisabled, and the default isdisabled— including for the built-in organization. - New clients default to
authorization_code, response typecodeandclient_secret_basicwhen the request omits those fields. - Dynamically registered clients become applications in that organization, visible and revocable in the console.
- Discovery advertises
client_id_metadata_document_supportedaccording to the same organization setting, so a client can tell whether URL-based client IDs are accepted.
If you are connecting MCP clients or AI agents, enable dynamic registration only for the organization that should receive them. If you are running an internal IdP for employees, leave it off and pre-register the applications you actually use. Casdoor is open source, and Casdoor Cloud starts at $6.67/month billed yearly for a dedicated instance.
FAQ
Is DCR required for MCP? MCP clients commonly use DCR when the server advertises a registration endpoint, and newer clients may use CIMD instead. A server that supports neither forces manual client setup, which most MCP hosts do not offer.
Should a public client get a client secret?
No. Public clients cannot keep one. Use token_endpoint_auth_method: none with PKCE and register exact redirect URIs, including loopback ports for desktop apps.
Can I delete a dynamically registered client? Yes, with the registration access token at the management URI (RFC 7592), or from the Casdoor console. Deleting it should invalidate its tokens and refresh tokens.
Does DCR replace PKCE? No. DCR is about creating the client; PKCE is about protecting the code exchange. Use both for public clients.
How do I stop spam registrations? Turn the feature off where it is not needed, rate limit it where it is, require exact redirect URIs, cap clients per tenant, and review or expire idle clients.
Sources
- RFC 7591: OAuth 2.0 Dynamic Client Registration
- RFC 7592: Dynamic Client Registration Management
- RFC 8252: OAuth 2.0 for Native Apps
- OpenID Connect Dynamic Client Registration 1.0
- OAuth Client ID Metadata Document draft
- Model Context Protocol: authorization
- Casdoor OIDC documentation
Product names are trademarks of their respective owners.