
Using Dynamic Client Registration
On this page
Dynamic client registration (DCR) allows new clients to be registered using a standard API. For more details about the architectural structure of dynamic client registration, see Dynamic Client Registration Overview. This article illustrates how to implement dynamic client registration and uses the Curity Identity Server as an example.
Initial Access Token
Dynamic client registration is usually protected using OAuth. This means that the client typically needs to present an initial access token in its registration request. With the Curity Identity Server, the initial access token is a one-time token with the dcr
scope. Other vendors have similar requirements.
There are multiple ways to obtain an initial access token. The Curity Identity Server supports the client credentials flow or a user interactive flow such as the code flow. Other vendors may offer similar methods or even out-of-band mechanisms to provide the application with the initial access token.
This overview does not explain in detail how to obtain the token but focuses on how to register the client once it has obtained the token.
Client Registration Request
Using dynamic client registration, the client sends an API call to the client registration endpoint at the authorization server. As mentioned before, this endpoint is typically protected and requires the client to include an access token in the request, e.g., in the Authorization
request header using the bearer
authentication scheme (per RFC 6750).
To register a client, the request must contain all metadata for that client. Which metadata to include depends on the context, like the client's capabilities. OAuth authorization servers usually support common client metadata and request parameters. Note though, their vendors may also have proprietary interpretations of certain parameters. The following list describe the characteristics of the client registration request.
- Method:
POST
- Agent: Backend
- Content Type:
application/json
- Response Type:
application/json
The body of the request is a JSON document, as indicated by the content type. The following section provides a non-exhaustive overview of the parameters to include in that document.
Request Parameters
Primary Parameters
Parameter | Value | Mandatory | Description |
---|---|---|---|
scope | String | no | A string containing the scope values the client may use, separated by space. |
grant_types | Array | no | A list of grant types that the client supports. If omitted, the default value is authorization_code . |
redirect_uris | Array | yes* | A list of the client's callback URLs. *Required if the client registers for a flow that uses redirects, such as the code flow. |
response_types | Array | no | A list of response types. Only used for browser-based flows. If omitted, the default value is code . |
token_endpoint_auth_method | String | no | A string describing the authentication method this client intends to use when authenticating at the authorization server. If omitted, the default value is client_secret_basic . |
Additional Parameters
Parameter | Value | Mandatory | Description |
---|---|---|---|
client_name | String | no | A human-readable name of the client. |
client_uri | URL | no | URL of the home page of the client. |
logo_uri | URL | no | A link to the logo representing the client. |
tos_uri | URL | no | A link to the terms of service for the client. |
policy_uri | URL | no | A link to the policy for profile data for the client. |
software_statement | JWT | no | A signed JWT containing the client's metadata. Usually the same across multiple clients that are associated with the same application. |
software_id | String | no | A string identifying the application the client is associated with. Multiple clients (client instances) can share the same software ID. |
OpenID Connect Related Parameters
Parameter | Value | Mandatory | Description |
---|---|---|---|
default_acr_values | Array | no | A list of ACR values to use by default when authenticating the user for requests from the registered client. |
default_max_age | Integer | no | A default value in seconds for the maximum age of the authentication. If the session is older than the given value, the authorization server must re-authenticate the user. |
sector_identifier_uri | URL | no | A URL to calculate Pairwise Pseudonym Identifiers (PPID) for this client. |
subject_type | pairwise or public | no | Whether the subject in the ID token should be unique for the client (pairwise ) or whether it is the same for all clients (public ). |
frontchannel_logout_uri | URL | no | URL that the authorization server can render in an iframe to log the user out from the client. |
backchannel_logout_uri | URL | no | URL that the authorization server can call to log the user out from the client. |
Parameters Related to Request Objects
Parameter | Value | Mandatory | Description |
---|---|---|---|
require_signed_request_object | Boolean | no | Indicates whether the client uses signed request objects in its authorization request. The authorization server must reject authorization requests without signed request objects. If omitted, the default value is false . |
request_object_signing_alg | String | no | The JWS algorithm that the client uses to sign its request object. The authorization server must reject any signed request objects that do not use the given algorithm. |
require_pushed_authorization_request | Boolean | no | Indicates whether the client uses PAR to initiate authorization requests. If omitted, the default value is false . |
Parameters Related to Client-Initiated Backchannel Authentication (CIBA)
The client can indicate its support for CIBA by including the grant type urn:openid:params:grant-type:ciba
.
In addition, the registration request also needs to contain the following parameters.
Parameter | Value | Mandatory | Description |
---|---|---|---|
backchannel_token_delivery_mode | poll , ping or push | yes | Specifies how the client wants to retrieve authentication results. |
backchannel_client_notification_endpoint | URL | yes* | A URL that the authorization server should call when the authentication results are available. *Required if the delivery method is ping or push . |
backchannel_user_code_parameter | Boolean | no | Indicates whether the client supports user codes. If omitted, the default value is false . |
Extension Parameters
The registration request may contain any other request parameters not specified in any official standard document. For example, the Curity Identity Server also supports the following proprietary parameters.
Parameter | Value | Mandatory | Description |
---|---|---|---|
allowed_origins | Array | no | List of origins that should be allowed to frame the application. |
application_url | URL | no | A link to redirect the user to if the session times out. |
authenticator_filters | Array | no | A list of IDs of the authenticator filters to apply to the authenticator selection. |
disallowed_proof_key_challenge_methods | Array | no | List of PKCE challenge methods to disable for the client. |
requires_consent | Boolean | no | Indicates whether the client wants the authorization server to prompt users with consent screens. If omitted, the default value is false . |
require_proof_key | Boolean | no | Indicates whether the client uses PKCE. If omitted, the default value is false . |
access_token_ttl | Integer | no | The time-to-live in seconds for the access token. If omitted, the Curity Identity Server uses a configurable default value. |
id_token_ttl | Integer | no | The time-to-live in seconds for the ID token. If omitted, the Curity Identity Server uses a configurable default value. |
refresh_token_ttl | Integer | no | The time-to-live in seconds for the refresh token. If omitted, the Curity Identity Server uses a configurable default value. |
Client Authentication Methods
The following is a non-exhaustive list of valid values for the token_endpoint_auth_method
parameter.
Method | Description |
---|---|
none | The client is a public client that does not support any authentication method. |
client_secret_basic | The client uses the HTTP Basic authentication scheme to send its client ID and client secret. |
private_key_jwt | The client authenticates with a self-signed JWT. |
tls_client_auth | The client authenticates using mutual TLS. |
Grant Types and Flows
The following is a non-exhaustive list of valid values to include in the grant_types
parameter.
Grant Type | Description |
---|---|
authorization_code | The authorization code flow. |
implicit | The implicit flow. |
password | The resource owner password flow. |
client_credentials | The client credentials flow. |
urn:ietf:params:oauth:grant-type:device_code | The device authorization flow. |
urn:openid:params:grant-type:ciba | Client initiated backchannel authentication flow. |
urn:ietf:params:oauth:grant-type:token-exchange | Token exchange flow. |
Response Types
The following is a non-exhaustive list of valid values to include in the response_types
parameter.
Response Type | Description |
---|---|
code | The authorization code flow |
token | The implicit flow |
id_token | The implicit openid flow or the hybrid flow (together with code and token ) |
Example Request
The following listing shows an example request.
POST /dcr HTTP/1.1Host: localhost:8443Authorization: Bearer 9e565e0b-a487-4092-a4af-461add3155f2Content-Type: application/javascript{"scope": "openid read foo test_scope_1","redirect_uris": [ "https://localhost:9000/cb" ],"grant_types": [ "authorization_code" ],"response_types": "code","client_name": "monkey","client_uri": "https://localhost:9000/","tos_uri": "https://localhost:9000/tos","default_max_age": 44}
Registration Response
The response from the client registration endpoint is a JSON document that reflects the accepted values.
Example
{"grant_types": ["authorization_code","refresh_token","implicit","password"],"subject_type": "public","redirect_uris": ["https://localhost/client-one/cb1","https://localhost/client-one/cb2"],"client_id": "5bc6f48b-b3c4-413d-a374-20a77ffd1d59","token_endpoint_auth_method": "client_secret_basic","software_id": "client-one","client_secret_expires_at": 0,"scope": "openid","client_secret": "E4wYA0LOU7hQd-DDh6W2rrqP-OnSsj3pAk243a-j-oE","client_id_issued_at": 1503067741,"client_name": "client-one","response_types": ["code","token","id_token"],"refresh_token_ttl": 3600,"id_token_signed_response_alg": "RS256"}
Registration Using a Template Client
In some use cases, such as when you use DCR for mobile clients you want multiple registered clients to use almost identical settings. With the Curity Identity Server, you can use a template client to share settings between dynamically registered clients. This approach simplifies client registration because it only requires a single request parameter, the software_id
. This ID (as defined in RFC 7591) is the client ID of the template client.
Templatized Request
- Method:
POST
- Agent: Backend
- Content Type:
application/json
- Response Type:
application/json
Request Parameters
Parameter | Value | Mandatory | Description |
---|---|---|---|
software_id | String | yes | The ID of the template client to instantiate a new client from. |
If a registration request contains a software_id
and if its value matches the client ID of a template client, the Curity Identity Server uses the settings from the corresponding template. If such a request contains other parameters next to the software_id
, the Curity Identity Server ignores them. The settings from a template always take precedence.
Example Request Using Template Client
The following listing shows an example of a templatized request.
POST /dcr HTTP/1.1Host: localhost:8443Authorization: Bearer 9e565e0b-a487-4092-a4af-461add3155f2Content-Type: application/javascript{ "software_id": "webapp-client" }
The Curity Identity Server returns the values in the response according to the configuration in the template.
Conclusion
Dynamic client registration is a powerful way of managing OAuth clients when static configuration is not suitable. A registration request includes similar properties to those that you would set in an admin user interface for static clients. The authorization server sets the final client properties and returns them to the client in the registration response. When you use a template client, you can use the Admin UI to create all common client properties in advance of any registration requests.

Jacob Ideskog
Identity Specialist and CTO at Curity
Join our Newsletter
Get the latest on identity management, API Security and authentication straight to your inbox.
Start Free Trial
Try the Curity Identity Server for Free. Get up and running in 10 minutes.
Start Free Trial