This is a basic how-to on configuring your first Client ID Metadata Documents (CIMD) documents with Auth0.
π Quick Navigation: What is CIMD? | Getting Started | Integrations | Advanced | Resources
β¨ Key Benefits:
- π Unified client metadata for secure OAuth registration
- π± Works seamlessly with AI tools, IDEs, and MCP servers
- π― Fine-grained permissions & RBAC support
- π Auditable & cacheable (transparent client configuration)
- π Client reuse across identity providers
This guide covers the following Auth0 prerequisites, along with easy how-to steps on configuring CIMD with your favorite AI tools & IDEs.
Prerequisites:
- π Auth0 Signup & Auth0 tenant creation
- βοΈ Enabling CIMD on your Auth0 tenant
- π Promoting Auth0 connections to domain level for third-party client usage
- π€ Creating test users
- π Creating APIs (or MCP Servers) with Auth0
- π Creating Roles for defining permissions and scopes for your API & users
βΆοΈ Start your MCP Server
AI Tools & IDEs Integration:
Advanced Use Cases:
- π Using a Confidential Client & Private Key JWT auth
- π Using an On-Behalf-Of Token Exchange to access first-party APIs
- ποΈ Using Auth0 Token Vault to access third-party APIs
π‘ New to CIMD? Learn what it is and why it matters below, or jump to Prerequisites to get started immediately!
What is CIMD? OAuth Client ID Metadata Documents are a new mechanism for registering OAuth clients using one's own personal domain document (JSON) file to represent your clients on any device or platform which may consume APIs. They are "decentralized" β you control them & can configure them to your own liking and personal taste. Identity Providers (IDPs) and MCP servers (and APIs) can then consume these documents when establishing your identity and registering your client.
CIMD documents are "idempotent" in a sense that they aim to provide a reliable, secure experience for all parties involved when it comes to authentication, authorization, and client registration. They also aim to cut down on very costly storage costs associated with creating "new dynamically" registered clients on every session, device, or wallet. CIMD provides a more universal-like client that is consistent across applications and APIs, and provides a low-friction sign-on experience for humans & agents alike.
A minimal CIMD document may look like the following:
{
"client_id": "https://contoso.dev/oauth/client.json",
"client_name": "Contoso",
"logo_uri": "https://contoso.dev/assets/contoso.png",
"grant_types: [ "authorization_code", "refresh_token" ],
"token_endpoint_auth_method": "none",
"application_type": "native",
"redirect_uris": ["https://contoso.dev/redirect"]
}
A hosted CIMD document such as this actually provides everything an identity server needs to register your client and begin granting it access. The client_id identifies your client and should match the URL/domain it is hosted from. The client_name and logo_uri identify your client, and are useful to provide on your login screen to users who will be granting this client access to APIs. The grant_types tell the authorization server what types of authorization flows your client supports (Authorization Code Flow for example). The token_endpoint_auth_method tells the authorization server what kind of authorization to use when your client requests access tokens for APIs. The application_type (native or web at this time) tells the authorization server whether this is a native (mobile or desktop) or web client. And lastly, redirect_uris are a familiar way to tell the authorization server what redirect URLs (callback URLs) your client will allow when a user requests to authorize using said client.
CIMD can technically be used with any OAuth Client and OAuth consuming API (resource server), however they will be quite popular in the coming years with AI tools and MCP servers due to many of these intrinsic qualities which fit the AI ecosystem quite well:
- several users, agents, AI tools, and clients which need access to several APIs & MCP Servers
- support for defining fine-grained permissions & security details about the authentication & authorization flow
- support for "dynamic registration" with iDPs and client reuse across IDPs
- some expandability & flexibility with the json definition (personalization qualities)
- easy to cache when desired, and highly auditable & visible (no more hidden "backend" clients, CIMD documents are just a public JSON document hosted on your domain)
You can read more here in the latest MCP spec about why CIMD is now one of the preferred registration approaches.
With CIMD, registration of your client is intended to be dynamic, using the authorization server's /authorize?client_id=https://../client.json endpoint to register your client if it does not already exist.
At a high level, this may look like this with a typical dynamic CIMD registration flow:

However, at Auth0 we are currently implementing this process with a "Manual CIMD Registration" step as our authorization server doesn't yet support dynamic CIMD registration. Our Management API now supports this new CIMD approach to registering clients, and you can begin using it to establish identity with your favorite AI tools and access MCP Servers & APIs. An overly simplified diagram of this flow looks like the following:
sequenceDiagram
%%{init: { "sequence": { "mirrorActors": true }}}%%
rect rgb(240, 248, 255)
Note over Admin π€,Auth0: Registration Phase
participant Admin π€
participant Auth0
participant Domain
Admin π€->>Auth0: Create CIMD app
Auth0->>Admin π€: POST /register<br/>(external_client_id = https://.../client.json)
Auth0->>Domain: GET https://.../client.json
Domain-->>Auth0: Client metadata (CIMD JSON)
Auth0->>Auth0: Validate + store client
end
rect rgb(240, 255, 240)
Note over Client,Auth0: Authorization Phase
actor User
participant Client
participant Auth0
User->>Client: Start login
Client->>Auth0: /authorize?client_id = https://.../client.json,<br/>(Auth0 resolves client by external_client_id == client_id)
Auth0->>User: Consent screen<br/>(client metadata)
User->>Auth0: Approve
Auth0-->>Client: Authorization code
Client->>Auth0: Exchange code
Auth0->>Client: Complete login & redirect to client redirect_uri
Client->>Auth0: Request resource access token with /oauth/token
Auth0-->>Client: Return resource access token <br/> (includes client_id=https://../client.json)
end
After your CIMD client has been manually registered with Auth0, you can begin granting it access to your first and third party APIs, and begin to allow user's to freely access your MCP tools or other APIs with this new client.
Furthermore, if you'd like to ensure reuse of this client across certain applications or for use with an AI agent, you can easily configure this as well, alongside granular MCP tool permissions for each identity you grant access to in Auth0.
Note about Dynamic CIMD: this will be released in the coming months at Auth0, and a number of related features are still in the works at Auth0 such as dynamic CIMD refresh/caching, tenant-wide app profiles & policy enforcement around CIMD domains and third party client usage, Cross App Access (XAA), MCP gateways, and many more features around the AI, MCP, and identity ecosystem.
Let's walk thru the prerequisite steps to getting started with CIMD and Auth0. These are quite trivial now, and should be quite easy to set you up for success with CIMD and Auth0 as your iDP.
You can easily signup for a free Auth0 tenant to get started here (no credit card required). Everything I'll cover in this guide is 100% free to play & get started with. I'll make reference to a few paid/trial features, but the free features offered here are really quite powerful and should be more than enough to get you started.
Once you've logged in and selected your Auth0 tenant at manage.auth0.com you easily enable the new CIMD features by going to:
Settings (top-level nav) -> Advanced (tab) within Tenant Settings page -> Settings section.
Enable the Client ID Metadata Document (CIMD) Registration toggle. I also like to disable Dynamic Client Registration (DCR) toggle because some AI tools & clients still get confused and have not prioritized CIMD over CIMD because it's quite new. You should also enable the Resource Paramater Compatibility Profile setting so that your tenant can use resource params when requesting API tokens. Enabling the use_scope_descriptions_for_consent option will also improve the experience in the UX when users consent to scoped permissions.
If you are using the Auth0-CLI client, you can also do this quite easily by simply running the following:
auth0 login --scopes "read:client_grants,create:client_grants,delete:client_grants,read:clients,create:clients,update:clients,read:resource_servers,create:resource_servers,update:resource_servers,read:roles,create:roles,update:roles,update:tenant_settings,read:connections,update:connections"
auth0 tenants use [your-tenant]
auth0 tenant-settings update set client_id_metadata_document_supported flags.use_scope_descriptions_for_consent
auth0 tenant-settings update unset flags.enable_dynamic_client_registration
Third-party clients (such as VS Code or Claude Code) currently require domain levels connections. You can promote any Auth0 connection to a domain level connection for this purpose. For this exercise, we will simply use the default Username-Password-Auth Database connection provided by Auth0.
Navigate to Authentication -> Database and select the Username-Password-Authentication connection. Then enable the Promote Connection to Domain Level toggle.
If you are using the Auth0-CLI client, you can also do this quite easily by simply doing the following:
- List your connections to get their IDs:
auth0 api get connections - From the list, identify only connections that should be available to be used with third party applications. For each of those specific connection IDs, run the following command to mark it as a domain-level connection. Replace
YOUR_CONNECTION_IDwith the actual ID (e.g.,con_XXXXXXXXXXXXXXXX)
auth0 api patch connections/YOUR_CONNECTION_ID --data '{"is_domain_connection": true}'
Here, we will create a simple username/password login for a user we can test with. You can easy any Auth0 supported login & connection method configured on your tenant though.
Navigate to User Management -> Users and select Create User. In the modal, provide an email and a password for the user. It can be any email/password combination you would like to test with.
If you are using the Auth0-CLI client, you can also do this quite easily by simply doing the following:
auth0 api post users \
--data '{
"email": "testuser@example.com",
"password": "Testpassword!!@",
"connection": "Username-Password-Authentication"
}'
Next, we create an API (or resource server) within Auth0 to represent the MCP Server. You can do this via the Applications -> APIs -> Create API option, but I prefer to do this via the CLI. Here are the recommended settings:
auth0 api post resource-servers --data '{
"identifier": "http://localhost:3001/mcp",
"name": "MCP Tools API",
"signing_alg": "RS256",
"token_dialect": "rfc9068_profile_authz",
"enforce_policies": true,
"scopes": [
{"value": "tool:whoami", "description": "Access the WhoAmI tool"},
{"value": "tool:greet", "description": "Access the Greeting tool"}
],
"subject_type_authorization": {
"user": {
"policy": "require_client_grant"
},
"client": {
"policy": "require_client_grant"
}
}
}'
This will create the "MCP Tools API" with a "Per-app authorization" policy. You should now the see the MCP Tools API has been created in your Auth0 Dashboard with the tool:whoami and tool:greet permissions.
Finally, set up roles and assign permissions to them. This allows you to control which users can access which tools, using the core Auth0 RBAC features.
Using the Dashboard UI:
Navigate to User Management -> Roles and select Create Role. Create the Tool Administrator role.

Next, assign the tool:whoami and tool:greet API permissions to your Tool Administrator role. Navigate to Permissions tab and select Add Permissions. Select your MCP Tools API and add the permissions.

Lastly, assign the Tool Administrator role to your test user. Navigate to the Users tab and assign the user this role.

Using the Auth0 CLI instead:
- Create Roles: For each role you need (e.g., "Tool Administrator", "Tool User"), run the create command.
# Example for an admin role
auth0 roles create --name "Tool Administrator" --description "Grants access to all MCP tools"
# Example for a basic user role
auth0 roles create --name "Tool User" --description "Grants access to basic MCP tools"
- Assign Permissions to Roles: After creating roles, note the ID from the output (e.g.
rol_) and assign the API permissions to it. ReplaceYOUR_ROLE_ID,http://localhost:3001/mcp, and the list of scopes.
# Example for admin role (all scopes)
auth0 roles permissions add YOUR_ADMIN_ROLE_ID --api-id "http://localhost:3001/mcp" --permissions "tool:whoami,tool:greet"
# Example for user role (one scope)
auth0 roles permissions add YOUR_USER_ROLE_ID --api-id "http://localhost:3001/mcp" --permissions "tool:whoami"
- Assign Roles to Users: Find users and assign them to the roles.
# Find a user's ID
auth0 users search --query "email:\"example@google.com\""
# Assign the role using the user's ID and the role's ID
auth0 users roles assign "auth0|USER_ID_HERE" --roles "YOUR_ROLE_ID_HERE"
Note: If you want to learn how to implement authorization using Auth0 FGA (more advanced), check the FastMCP FGA example. Note: Further customization not supported out of the box by RBAC can be done via a custom Post-Login action trigger.
Now it's time to run the MCP Server with our Auth0 SDK of choice. You can choose one of the Auth0 AI MCP Quickstart Servers. For this exercise, I've chosen to run the nextjs-mcp-js MCP server.
Clone the auth0-ai-samples repo and navigate to the nextjs-mcp-js directory:
git clone https://github.com/auth0-samples/auth0-ai-samples.git && cd auth0-ai-samples/auth-for-mcp/nextjs-mcp-js
npm i
Setup of your .env file with your Auth0 tenant's configuration, ex:
AUTH0_DOMAIN=cimd-dev.us.auth0.com
AUTH0_AUDIENCE=http://localhost:3001/mcp
MCP_SERVER_URL=http://localhost:3001/mcp
Start the MCP server:
// disable ssl cert checking locally
export NODE_TLS_REJECT_UNAUTHORIZED=0
npm run dev -- --port 3001
> nextjs-mcp-js@0.0.0 dev
> next dev --turbo --port 3001
β² Next.js 15.5.9 (Turbopack)
- Local: http://localhost:3001
- Network: http://10.10.10.10:3001
- Environments: .env
β Starting...
(node:53023) Warning: Setting the NODE_TLS_REJECT_UNAUTHORIZED environment variable to '0' makes TLS connections and HTTPS requests insecure by disabling certificate verification.
(Use `node --trace-warnings ...` to show where the warning was created)
β Ready in 1016ms
Note: you can disable ssl cert checks when running locally, but this should not be used in production.
π Congrats! π You've now completed all the pre-requisites, and are ready to start using CIMD with your MCP Servers and AI Tools.
Now it's time to start registering some CIMD clients with Auth0 and using them with your favorite AI Tools. Please feel free to select any of the additional guides below.
Last, we cover more advanced use cases with CIMD & Auth0 such as:
- Using a Confidential Client & Private Key JWT auth
- OpenAI AppSDK integration
- Using an On-Behalf-Of Token Exchange to access first-party APIs
- Using Auth0 Token Vault to access third-party APIs
β¨ Thanks for following this guide! We hope you find CIMD useful for your own use cases.
π Explore More:
- Auth0 AI & Auth0 Auth for MCP overview docs
- Auth0 Manual CIMD Registration
- Auth0 AI Samples
π Have Feedback? Found a bug or want to contribute? Pull requests welcome! π




