# OAuth Client Registration | Static and CIMD

Learn how FusionAuth registers OAuth clients, either ahead of time as Applications or just-in-time from a Client ID Metadata Document.

> For the index of this section of the site, see [llms.txt](https://fusionauth.io/docs/llms.txt)

Before an OAuth client can request tokens, the authorization server needs a record of it, including which redirect URLs the client may use. That record is the client's registration.

FusionAuth supports two ways to register a client:

*   Static registration, where you create an [Application](https://fusionauth.io/docs/get-started/core-concepts/types/applications.md) for the client ahead of time.
*   Client ID Metadata Documents (CIMD), where the client describes itself in a document it hosts, and FusionAuth registers it the first time it shows up.

## Static Registration

With static registration, you create an Application in FusionAuth for each client. The Application Id becomes the client's `client_id`. You configure everything else on the Application: redirect URLs, enabled grants, client authentication, roles, and scopes.

Use static registration when you know your clients in advance, such as your own apps and services.

Someone has to create the Application before the client can log in. That doesn't work for software you don't control and can't predict, like an AI chat app connecting to your MCP server on behalf of a user.

## Client ID Metadata Documents

> **PLAN:** This feature requires [an Enterprise plan](https://fusionauth.io/docs/get-started/core-concepts/plans-features.md#enterprise-features).

Available since `1.70.0`

With CIMD, the `client_id` is an HTTPS URL, such as `https://chatgpt.com/oauth/client.json`. The client hosts a JSON document at that URL describing itself, including its name and redirect URIs. CIMD is defined in [draft-ietf-oauth-client-id-metadata-document](https://datatracker.ietf.org/doc/draft-ietf-oauth-client-id-metadata-document/), and the [MCP authorization spec](https://modelcontextprotocol.io/specification/draft/basic/authorization) uses it for client registration.

You don't register CIMD clients one at a time. Instead, you tell FusionAuth which origins to trust by creating a [CIMD domain](https://fusionauth.io/docs/get-started/core-concepts/types/cimd-domains.md) for each one, for example `https://chatgpt.com`. You can configure scopes, consent, resource URIs, and lambdas for each domain.

### How A CIMD Client Gets Registered

1.  The client starts the Authorization Code grant, using its document URL as the `client_id`. The request must go to the Tenant's endpoints, which end with the Tenant Id, such as `https://<host>/oauth2/authorize/<tenantId>`, and include exactly one [resource parameter](https://datatracker.ietf.org/doc/html/rfc8707), such as the URL of your MCP server.
2.  FusionAuth checks that the URL matches a CIMD domain in the Tenant. If nothing matches, the request fails.
3.  The user logs in.
4.  FusionAuth fetches the document, validates it, and registers the client. If the domain has a registration lambda, the lambda can reject the client or change its registration.
5.  The user consents to the requested scopes. CIMD clients are always treated as third-party clients, so FusionAuth always asks for consent at least once, even when the request includes no scopes. The consent page shows the client's `client_name`, its `client_uri` if provided, and the host where its document is hosted, so the user can tell which client they're connecting.
6.  FusionAuth redirects back to the client with an authorization code, and the client exchanges it for tokens.

The `resource` must be one of the domain's **Authorized resource URIs**, or FusionAuth rejects the request with `invalid_target`. The `aud` claim of both the access token and the Id token contains two values: the client's `client_id` URL and the `resource`.

FusionAuth caches the document. Until the cached copy expires, later logins from the same client reuse the registration without fetching the document again. The domain's cache settings control how long that is, as described in [CIMD Registration Caching And Lifecycle](https://fusionauth.io/docs/lifecycle/authenticate-users/oauth/cimd-registration-lifecycle.md). After the cached copy expires, the next login fetches the document again. Access and refresh tokens the client already holds keep working after the cached copy expires.

### Removing A CIMD Client

FusionAuth has no admin UI for removing a single CIMD client. There are three ways to remove access:

*   Delete the client's registration with the [Delete a CIMD Client Registration API](https://fusionauth.io/docs/apis/cimd-client-registrations/delete-a-cimd-client-registration.md). FusionAuth deletes the registration and its refresh tokens immediately. To find the registration Id, [search for the registration](https://fusionauth.io/docs/apis/cimd-client-registrations/search-for-cimd-client-registrations.md) by its `client_id` URL.
*   Set `decision` to `REVOKE` in the domain's registration lambda. FusionAuth deletes the client's registration and refresh tokens the next time the lambda runs for that client. The lambda runs when a user logs in after the client's cached document expires, or when the client requests a `resource` it hasn't used before.
*   Delete the CIMD domain. This removes every client registered through the domain, along with their refresh tokens.

Deleting a registration doesn't block the client. The next time a user logs in with that client, FusionAuth registers it again. To keep a client out, also set `decision` to `DENY` for it in the registration lambda. A `DENY` decision on its own blocks new logins but leaves existing refresh tokens working.

### Monitoring CIMD Clients

To see which clients have registered, use the [Search for CIMD Client Registrations API](https://fusionauth.io/docs/apis/cimd-client-registrations/search-for-cimd-client-registrations.md). Each registration shows the client's metadata, the scope decisions for each `resource` it has used, and whether its cached document is `Active`, in its `Grace` period, or `Expired`.

FusionAuth sends a [CIMD Registration Success](https://fusionauth.io/docs/extend/events-and-webhooks/events/cimd/cimd-registration-success.md) event when it registers a client or updates a registration, and a [CIMD Registration Failed](https://fusionauth.io/docs/extend/events-and-webhooks/events/cimd/cimd-registration-failed.md) event when it can't. Every failure also writes an Error entry to the Event Log. A rate limited request also writes an Information entry. With **Enable debug logging** on the CIMD domain, FusionAuth writes a Debug entry when it creates a registration, refreshes one after its cache expires, or adds a new resource to an existing one.

Logins through a CIMD client appear in login records and login reports under the CIMD domain's Id as the `applicationId`, even though the user has no registration for an Application with that Id. FusionAuth records these logins against the domain's backing Application, whose Id matches the CIMD domain's Id. They roll up into the aggregated login data that the [Report APIs](https://fusionauth.io/docs/apis/reports.md) use. The [User Login Success](https://fusionauth.io/docs/extend/events-and-webhooks/events/user/login/user-login-success.md) and [User Login Failed](https://fusionauth.io/docs/extend/events-and-webhooks/events/user/login/user-login-failed.md) events work differently: they leave out `applicationId` and include the CIMD domain's Id as `cimdDomainId`.

### What CIMD Clients Can't Do

CIMD clients are public clients. They authenticate with PKCE instead of a client secret, and they can only use the `authorization_code` and `refresh_token` grants. See [Fixed OAuth Behavior](https://fusionauth.io/docs/get-started/core-concepts/types/cimd-domains.md#fixed-oauth-behavior) for the full list of restrictions.

FusionAuth reads only `client_id`, `client_name`, `client_uri`, and `redirect_uris` from the document, and ignores every other field. A `scope` value in the document has no effect, so a CIMD client can only request the scopes enabled on its domain. FusionAuth also doesn't fetch `logo_uri`.

A CIMD client's access token can't authenticate the FusionAuth APIs that accept a user's JWT in place of an API key, such as the [Login API](https://fusionauth.io/docs/apis/login.md), the [JWT](https://fusionauth.io/docs/apis/jwt/issue-a-jwt.md) issue and refresh APIs, the [Change Password API](https://fusionauth.io/docs/apis/users/change-password.md), and the two-factor APIs. Use the token with your own resource server, the [Userinfo](https://fusionauth.io/docs/apis/oauth/userinfo.md) endpoint, or the [Introspect](https://fusionauth.io/docs/apis/oauth/introspect.md) endpoint instead.

FusionAuth recognizes a CIMD client's token by its `aud` claim, which is always exactly `["<client_id URL>", "<resource>"]`. Don't change `aud` in a JWT populate lambda for a CIMD domain, because FusionAuth won't recognize the token as a CIMD token.

### Limitations

*   CIMD works with every identity provider type except SAML v2 IdP-initiated login. IdP-initiated SAML login doesn't work with CIMD clients.
*   An identity provider can't create user registrations for a CIMD domain.
*   A CIMD domain's Id isn't a valid `client_id`. FusionAuth rejects it with an `invalid_client` error. A CIMD client must use the URL of its metadata document.

For more information, see [Identity Providers](https://fusionauth.io/docs/get-started/core-concepts/types/cimd-domains.md#identity-providers) and [CIMD Domains: Fixed OAuth Behavior](https://fusionauth.io/docs/get-started/core-concepts/types/cimd-domains.md#fixed-oauth-behavior).

## Dynamic Client Registration

[Dynamic Client Registration](https://datatracker.ietf.org/doc/html/rfc7591) (DCR) is an older way to solve the same problem. Under DCR, the client calls a registration endpoint on the authorization server, and the server creates and stores a new client record for every caller. FusionAuth doesn't support DCR; you can follow [GitHub issue 1125](https://github.com/FusionAuth/fusionauth-issues/issues/1125) for updates. CIMD covers the MCP use case with less stored state, since the client's metadata stays on the client's own server.

## Choosing An Approach

|  | Static registration | CIMD |
| --- | --- | --- |
| Who registers the client | You, before the client logs in | FusionAuth, the first time the client logs in |
| `client_id` | The Application Id | The URL of the client's metadata document |
| Where the client's metadata lives | The Application | The client's document, cached by FusionAuth |
| What you configure | One Application per client | One CIMD domain per trusted origin |
| Client authentication | Client secret or none, with or without PKCE | None. PKCE is required |
| Grants | Any grant FusionAuth supports | `authorization_code` and `refresh_token` |
| Consent | Configurable, including skipping it for first-party apps | Always prompts at least once |
| Removing access | Delete or deactivate the Application | Delete the CIMD domain, or revoke the client with a registration lambda |

Use static registration for clients you know about. Use CIMD when clients you don't know in advance need to log in, such as MCP clients like ChatGPT and claude.ai connecting to your MCP server.

## Next Steps

*   [Configure a CIMD domain](https://fusionauth.io/docs/get-started/core-concepts/types/cimd-domains.md) to start accepting CIMD clients.
*   [Host a Client ID Metadata Document](https://fusionauth.io/docs/lifecycle/authenticate-users/oauth/host-cimd-document.md) for an OAuth client you build.
*   [Connect claude.ai and ChatGPT to an MCP server](https://fusionauth.io/docs/extend/examples/mcp-clients-claude-chatgpt.md) protected by FusionAuth.

Related

[Extend CIMD Client Registration Lambda An overview of the CIMD client registration lambda. client id metadata documentcimdmcp](https://fusionauth.io/docs/extend/code/lambdas/cimd-client-registration.md)

[Extend Connect claude.ai And chatgpt.com To A FusionAuth-Protected MCP Server Learn how to connect claude.ai and chatgpt.com to an MCP server protected by FusionAuth using Client ID Metadata Documents. cimdoauth](https://fusionauth.io/docs/extend/examples/mcp-clients-claude-chatgpt.md)

[Lifecycle CIMD Registration Caching And Lifecycle Learn how long FusionAuth caches a Client ID Metadata Document, what happens when it expires, and how a CIMD client registration is refreshed or removed. cimdclient id metadata document](https://fusionauth.io/docs/lifecycle/authenticate-users/oauth/cimd-registration-lifecycle.md)

[Lifecycle Host A Client ID Metadata Document (CIMD) Publish a Client ID Metadata Document so your OAuth client can log in to FusionAuth without being registered ahead of time. cimdclient id metadata document](https://fusionauth.io/docs/lifecycle/authenticate-users/oauth/host-cimd-document.md)
---

## Other pages in OAuth

> For the full index of this section, see [Lifecycle](https://fusionauth.io/docs/llms-lifecycle.txt).

- [CIMD Registration Caching And Lifecycle](https://fusionauth.io/docs/lifecycle/authenticate-users/oauth/cimd-registration-lifecycle.md): Learn how long FusionAuth caches a Client ID Metadata Document, what happens when it expires, and how a CIMD client registration is refreshed or removed.
- [OAuth DPoP](https://fusionauth.io/docs/lifecycle/authenticate-users/oauth/dpop.md): Learn how to enable sender-constrained OAuth tokens DPoP (Demonstration of Proof-of-Possession) with FusionAuth and validate DPoP proofs in your APIs.
- [Host A Client ID Metadata Document (CIMD)](https://fusionauth.io/docs/lifecycle/authenticate-users/oauth/host-cimd-document.md): Publish a Client ID Metadata Document so your OAuth client can log in to FusionAuth without being registered ahead of time.
- [OAuth](https://fusionauth.io/docs/lifecycle/authenticate-users/oauth.md): An overview of how FusionAuth provides an OAuth 2.0 and OpenID Connect SSO login system.
- [OAuth Issuer Validation](https://fusionauth.io/docs/lifecycle/authenticate-users/oauth/issuer-validation.md): Learn how to validate the authorization response issuer parameter (RFC 9207) to prevent mix-up attacks.
- [Modes](https://fusionauth.io/docs/lifecycle/authenticate-users/oauth/modes.md): An overview of OAuth modes and how OAuth is commonly used.
- [OIDC Prompt](https://fusionauth.io/docs/lifecycle/authenticate-users/oauth/prompt.md): Learn about OpenID Connect prompt and example use cases.
- [OAuth Response Modes](https://fusionauth.io/docs/lifecycle/authenticate-users/oauth/response-modes.md): Learn about OAuth 2.0 response modes (query, fragment, form_post) and when to use each one.
- [Access Control with OAuth Scopes](https://fusionauth.io/docs/lifecycle/authenticate-users/oauth/scopes.md): Learn about OAuth scope policy configuration, managing custom scopes, and using scopes in an OAuth2 workflow.
- [Delegate Access With Token Exchange](https://fusionauth.io/docs/lifecycle/authenticate-users/oauth/token-exchange-delegation.md): Configure FusionAuth so that one service can exchange a User's access token for a token that calls another service on that User's behalf.
- [OAuth Token Exchange](https://fusionauth.io/docs/lifecycle/authenticate-users/oauth/token-exchange.md): Learn how FusionAuth implements OAuth 2.0 Token Exchange (RFC 8693) so that a service can call another service on behalf of a user.
- [Manage Software Tokens](https://fusionauth.io/docs/lifecycle/authenticate-users/oauth/tokens.md): Learn about OAuth2 and OpenID Connect Tokens and how they are used.
- [URL Validation](https://fusionauth.io/docs/lifecycle/authenticate-users/oauth/url-validation.md): Learn about OAuth URL validation policies in FusionAuth.
