Aller au contenu principal

Dynamic app (CIMD)

Dynamic app allows OAuth clients to connect to your tenant without pre-registration. Instead of a client ID issued by Logto, the client uses a public HTTPS URL as its client_id. The URL serves a JSON document describing the client, called the client ID metadata document (CIMD). Logto fetches the document and treats the client as a third-party application.

Dynamic app implements the IETF draft OAuth Client ID Metadata Document.

When to use dynamic app

Pre-registration works when you know your partners. It does not work when any client may connect, which is common in the Model Context Protocol (MCP) ecosystem: a user asks their AI agent to connect to your service, and the agent has never talked to your tenant before.

With dynamic app, the client publishes its own metadata at a URL it owns, and that URL is its identity. Nothing needs to be created in your tenant beforehand.

Registered third-party appDynamic app
Client IDIssued by LogtoAn HTTPS URL owned by the client
RegistrationRequiredNot required
Client secretSupportedNot supported
PermissionsPer applicationShared by all dynamic clients
Grant typesDepends on app typeauthorization_code and refresh_token

Dynamic clients are public clients, so they always use PKCE. You can use both models at the same time. A partner you trust can still have a registered app with its own permissions.

Enable dynamic app

  1. Go to Console > Applications and open the Third-party apps tab.
  2. Click Create application and select the Dynamic app card. It enables a tenant-level feature instead of creating an application.
  3. Confirm in the dialog. Once enabled, any OAuth client with a valid public HTTPS client ID URL can start an authorization request for your tenant.
  4. Open the dynamic app from the application list and go to the Permissions tab to grant permissions.

The dynamic app has no editable name, redirect URIs, or credentials. Each client provides its own in its metadata document.

remarque:

Dynamic app requires the OIDC provider SSRF protection, since Logto fetches metadata documents from the internet. Self-hosted instances that disable it cannot enable dynamic app.

Grant permissions

The Permissions tab defines the maximum permissions shared by all dynamic clients. It works like the permission management of a registered third-party app, with User and Organization sections.

Requesting a user permission that is not granted results in an error, while API resource and organization permissions that are not granted are ignored. Users also consent only to permissions they have through their roles.

Since every dynamic client shares this set, keep it minimal.

Publish a client ID metadata document

If you are building a client that connects to Logto, host a metadata document and use its URL as your client_id. The URL must use the https scheme and contain no fragment, user info, or dot path segments. Logto sends a GET request to the URL and expects a JSON object.

For example, Claude Code uses https://claude.ai/oauth/claude-code-client-metadata, which serves:

{
"client_id": "https://claude.ai/oauth/claude-code-client-metadata",
"client_name": "Claude Code",
"client_uri": "https://claude.ai",
"redirect_uris": ["http://localhost/callback", "http://127.0.0.1/callback"],
"token_endpoint_auth_method": "none"
}

The field names are the same as in OAuth 2.0 Dynamic Client Registration. Note that:

  • client_id must be identical to the URL that serves the document.
  • Dynamic clients are public clients. The document must not contain client_secret, and token_endpoint_auth_method must not be a shared-secret method. Use PKCE instead.
  • Metadata URIs such as client_uri, logo_uri, tos_uri, and policy_uri must be absolute https URLs. This does not apply to redirect_uris, so native clients can still use loopback addresses like the example above.
  • redirect_uris are matched as exact strings, except that loopback addresses can be matched with any port. Wildcard patterns are also supported.
  • scope, grant_types, and response_types are decided by Logto. If the document declares them, the values are ignored. Dynamic clients can only use the authorization code flow and refresh tokens.

Logto caches the document for up to 24 hours, following the Cache-Control and Expires headers of your response. Set them according to how often you expect to update the document.

Dynamic clients are third-party applications, so the consent screen is always shown.

The consent screen also shows a notice that the client is unregistered. The client name and logo come from the metadata document, so they can imitate any brand. The host of the client ID URL is displayed as well, since it is the only part the client cannot forge.

Manage authorizations

Authorizations granted to dynamic clients are regular third-party grants. Users can review and revoke them in account settings, and admins can manage them through the Management API. The client ID URL is used to identify the client.

Disabling the dynamic app stops new authorization requests, while existing grants are kept. Revoking a grant requires the client to get user authorization again, but previously issued access tokens may remain valid until they expire.

Limitations

  • Only the authorization code flow with PKCE and refresh tokens are supported. Client credentials, device flow, and token exchange are not available.
  • Permissions and branding cannot be configured per client.
  • App-level access control does not apply to dynamic clients, since they have no application record.
Third-party app (OAuth / OIDC)

Enable third-party AI agent access to your MCP server