OpenID Connect Dynamic Client Registration for External API Gateways
Although not a typical authorization flow, you can use OpenID Connect dynamic client registration to enable your Salesforce instance as an independent OAuth authorization server to protect resources hosted on an external API gateway.
Required Editions
| Available in: both Salesforce Classic and Lightning Experience |
| Available in: All Editions |
See New connected apps can no longer be created in Spring ‘26 for more details.
Dynamic client registration enables resource servers to directly register client apps as connected apps with Salesforce. The client apps are external applications requesting access to the protected resources. To register client apps as connected apps, the resource server sends the authorization server a request. The authorization server verifies the resource server’s request and creates the connected app, giving it a unique client ID and client secret.
As part of the authorization process, token introspection allows all OAuth connected apps to check the current state of an OAuth 2.0 access or refresh token. The resource server or connected apps send the client app’s client ID and secret to the authorization server, initiating an OAuth authorization flow. As part of this flow, the authorization server validates, or introspects, the client app’s access token. If the access token is current and valid, the client app is granted access.
For example, you want your Salesforce partners to be able to access order status data independently. So you build a service that exposes order status across multiple systems by fronting it with an API gateway, which is deployed on MuleSoft’s Anypoint Platform. To enable protected access to this data, you take the following steps.
- Apply an OpenID token enforcement policy on the API gateway.
- Configure your Salesforce instance as a client management provider on Mulesoft’s Anypoint Platform.
With this configuration, the API gateway uses your Salesforce instance as its authorization provider in the OpenID Connect dynamic client registration flow.
Here are the steps for this flow.
- Create a connected app for the API gateway, and generate an initial access token for it. Salesforce requires this token to authenticate dynamic client registration requests. See Generate an Initial Access Token.
- Configure your API Gateway:
- Apply an OpenID token enforcement policy.
- Configure your Salesforce instance as a client management provider.
- If required by your API Gateway, register your initial access token.
- To initiate the flow, the API gateway registers a connected app with the Salesforce dynamic client registration endpoint.
- After a successful registration, Salesforce responds with the registered connected app’s metadata.
- The API gateway sends a request to the Salesforce authorization endpoint to approve the registered connected app based on the authorization grant type associated with it. With a successful validation, Salesforce generates an access token for the registered connected app.
- The API gateway sends a request to the Salesforce token introspection endpoint to validate the access token.
- After a successful validation, the API gateway allows the registered connected app to access the protected data.
Register a Connected App
The connected app representing the external API gateway registers a new client app as a connected app with the Salesforce dynamic client registration endpoint. The format of the dynamic client registration endpoint URL is https://hostname/services/oauth2/register.
Salesforce requires the requesting OAuth 2.0 connected app to provide the initial access token in the request’s header. This example is a request posted to the dynamic client registration endpoint.
POST /services/oauth2/register HTTP/1.1
Content-Type: application/json
Accept: application/json
Authorization: Bearer <initial.access.token>
Host: myorg.salesforce.com
{"redirect_uris":["https://client.salesforce.com/redirect.html",
"https://client.salesforce.com/callback","http://localhost"],
"response_types":["code","token","id_token"],
"grant_types":["authorization_code","implicit","refresh_token"],
"application_type":"web",
"contacts":["abc@sf.com","ve7jtb@example.org"],
"client_name","Client Name Example",
"logo_uri":"https://client.salesforce.com/logo.png",
"client_uri":"https://client.salesforce.com/info.html"}Include the following parameters in the registration request. For additional information about these parameters, refer to section 3.1 Client Registration Request in OpenID Connect Dynamic Client Registration 1.0 incorporating errata set 1.
| Parameter | Description |
|---|---|
redirect_url
|
The URL where users are redirected after a successful authentication. The redirect URI must match one of the values in the connected app’s Callback URL field. Otherwise, the approval fails. You can find the redirect URI on the connected app’s Manage Connected Apps page or from the connected app’s definition. This value must be URL encoded. |
response_types
|
(Optional) OAuth 2.0 response values that the client limits itself to using. Salesforce does not store or restrict response types for clients. |
grant_types
|
(Optional) OAuth 2.0 grant types that the client limits itself to using. Salesforce does not store or restrict grant types for clients. |
application_type
|
(Optional) Type of application, such as native or web. Salesforce does not store the application type with the client. |
contacts
|
(Optional) If you don’t provide a contact value, Salesforce auto-generates a default contact. |
client_name
|
(Optional) If you do not provide a client name value, Salesforce auto-generates a default client name. |
scopes
|
(Optional) Permissions that define the type of protected resources a connected app can access. You assign scopes to a connected app when you build it, and they’re included with the OAuth tokens during the authorization flow. If you don’t include this parameter, all scopes assigned to the connected app are requested. The scopes passed in this parameter must be a subset of the registered scopes. For valid parameters, see OAuth Scopes. If you do not provide scopes, Salesforce adds id, api, and openid for the client. If you include the refresh_token grant type in the request but do not provide a scope, Salesforce adds the refresh_token scope. |
Salesforce Responds with the Registered Connected App’s Metadata
After a successful registration, Salesforce sends the API Gateway a response with the
client_id, client_secret, and all registered metadata
about the new connected app. This example shows a response from Salesforce to the connected
app representing the API Gateway.
HTTP/1.1 201 Created
Content-Type: application/json
Cache-Control: no-store
Pragma: no-cache
{"client_id":"client_id=3MVG9lKcPoNINVBIPJjdw1J9LLM82HnFVVX19KY1
uA5mu0QqEWhqKpoW3svG3XHrXDiCQjK1mdgAvhCscA9GE",
"client_secret":"client_secret=
1955279925675241571",
"registration_access_token":"00DR00000009GVP!ARQAQE5XuPV7J4GoOu3wvLZjZI_TxoBpeZpRb6d8AVdII6cz
_BY_uu1PKxGeAjkSvO0LpWoL_qfbQWKlXoz1f2ICNiy.6Ndr",
"registration_client_uri":"https://login.salesforce.com/
services/oauth2/register/3MVG9qKMKuRGRcbs8STMW7uUqqf0OP5l1GeQt1qRF6_
UyAqTC1ky0RlpN3L9Z8PSo4nTTTmDzymYy4tEbrKY.",
"client_id_issued_at":1534292303,
"client_secret_expires_at":0,
"token_endpoint_auth_method":"client_secret_post",
"redirect_uris":["https://login.salesforce.com/redirect.html",
"https://client.salesforce.com/callback","http://localhost"],
"response_types":["code","token","id_token"],
"grant_types":["authorization_code","implicit","refresh_token"],
"contacts":["abc@sf.com"],
"client_name":"Client Name Example",
"logo_uri":"https://client.salesforce.com/logo.png",
"client_uri":"https://client.salesforce.com/info.html",
"scopes":["openid","refresh_token","id","api"]}
Request Token Introspection
The connected app representing the external API gateway sends a request to the Salesforce token introspection endpoint to validate its access token. For specific details about this request, see OpenID Connect Token Introspection.
Salesforce Validates the Token
Salesforce verifies the client credentials in the header and sends a response indicating whether the token is active. This response indicates that the token is still active.
HTTP/1.1 200 OK
Content-Type: application/json
{
"active":true,
"scope":"id api web full refresh_token openid",
"client_id":"OAuthSp",
"username":"myuser@salesforce.com",
"sub":"https://login.salesforce.com/id/00Dxx0000001gEREAY/005xx000001Sv6AAAS",
"token_type":"access_token",
"exp":1528502109,
"iat":1528494909,
"nbf":1528494909"
}If you include the child_sessions parameter in the request, the response
includes information about the validity of the child sessions, such as the following.
HTTP/1.1 200 OK
Content-Type: application/json
{
"active":true,
"scope":"id api web full refresh_token openid",
"client_id":"OAuthSp",
"username":"myuser@salesforce.com",
"sub":"https://login.salesforce.com/id/00Dxx0000001gEREAY/005xx000001Sv6AAAS",
"token_type":"access_token",
"exp":1528502109,
"iat":1528494909,
"nbf":1528494909
child_sessions":{
"content":"inactive",
"lightning":"active",
"visualforce":"missing"}
}If the token isn’t active, Salesforce sends the following response.
HTTP/1.1 200 OK
Content-Type: application/json
{
"active": false
}
