Create a Hosted Login configuration client

Unlike public clients and confidential clients, configuration clients have nothing to do with user logins and registrations. Instead, configuration clients help you obtain the configuration access tokens needed to call the OpenID Connect (OIDC) Configuration APIs. When you request a configuration token, you need to use Basic authentication and provide a client ID and client secret as your user name and password. For example::

That client ID and client secret must come from a configuration client.

When your first subscribe to the Identity Cloud you’ll be given a configuration client and a token policy (if you weren’t given those items then you wouldn’t be able to call any of the OIDC Configuration APIs). That initial configuration client might be all you need. On the other hand, you might want to create, and use, other configuration clients; if nothing else, that way you won’t inadvertently delete your only configuration client, a disaster that would prevent you from obtaining configuration tokens.

Fortunately, creating a configuration client is pretty easy: all it takes is one simple API call. Just remember that, in order to make this one API call, you’ll first need to be issued a configuration token. That means you need to use an existing configuration client to obtain the token that lets you create a new configuration client. But, really, that’s as tricky as it gets.

📘

We won’t bother explaining how to get a configuration token in this article. But that’s OK: the article Get an administrative access token walks you through the process, step-by-step.

Let’s assume that you’ve obtained your token and are ready to begin. To create a configuration client, use the /{customerId}/config/clients operation and the POST method. For example, a Curl command to create a configuration client looks something like this

curl -X POST \
  https://v1.api.us.janrain.com/g/01000000-0000-3000-9000-000000000000/config/clients/fd72dfd7-3ad8-4237-a74d-013e04ae947c \
  -H 'Authorization: Bearer Ki712dpGq5GPQcsxMHY6ShHY7wU_iTs0o9dPx4TEzf5yLIvddjnDVBJxjPDucf5YVB' \
  -H 'Content-Type: application/json' \
  -d '{
    "name": "Akamai Documentation Configuration Client",
    "redirectURIs": [
        "http://127.0.0.1"
    ],
    "tokenPolicy": "48e04957-2d89-414e-bfcd-5ca6298a2f07",
    "type": "confidential"
}'

If you’re wondering what those parameters actually do (and how you configure them), the following table should answer your questions:

KeyDescription
nameFriendly name of the configuration client. For example:

"name": "Akamai Documentation Configuration Client"

You can name your clients anything you want: Client A, Client B, Client C, whatever. However, we recommend including the word Configuration somewhere in the name.: that makes it easier to tell which of your OIDC clients are configuration clients and which ones aren’t.

Incidentally, client names must be unique for each organization (i.e., for each customer ID): you can only have one OIDC client named Akamai Documentation Configuration Client.
redirectURIsURL of the page the user is redirected to following authentication. As we noted earlier, configuration clients aren’t used for logins and registrations. Because of that, the redirectURIs parameter is actually irrelevant: redirects aren’t a part of the client_credentials grant used with configuration clients.

So what that means to you? That means that it doesn’t matter what redirect URI you include when creating a confidential client: that URI will be ignored anyway. Despite that, you still have to include some sort of redirect URI in your API call. Otherwise the call fails with the following error:

"errors": "('redirectURIs',) field required"
loginPolicyUnique identifier of the login policy associated with the client. Login policies are not required when creating a configuration client; that’s because, as we’ve mentioned a few times now, configuration clients have nothing to do with logins and registrations.

Admittedly, you can reference a login policy when creating a configuration client. However, we recommend against that, and for two reasons. First, the policy is going to be ignored, so why bother? Second, leaving out the login policy provides an easy way to tell whether a given client is a configuration client or a confidential client. If there’s a login policy then it’s a confidential client; if there isn’t then it’s a configuration client.

If you leave off the login policy, the value of your new client’s loginPolicy property is automatically set to null:

"loginPolicy": null

Incidentally, there’s no way to change that. Yes, you can make a PUT call that assigns a new login policy ID (e.g., 1e1ab726-f4b5-4bad-ba45-877027af4097) to the client, and that PUT call will run without generating an error. At the same time, however, the value of the loginPolicy property will remain exactly as-is:

"loginPolicy": null

But, again, you don’t need a login policy when creating a configuration client. So don’t worry about it.
tokenPolicyUnique identifier of the token policy associated with the client. For example:

"tokenPolicy": "2dcae965-0d56-4961-a98e-f98583e30bb9"

When assigning a token policy to your configuration client, be sure that the token policy specifies configuration scopes like these:

"allowedScopes": [
":config/**",
"
:config/clients",
]

If the assigned token policy uses standard OpenID Connect scopes (like the following) then your new configuration client can’t be used with the token endpoint to return administrative tokens:

"allowedScopes": [
"openid",
"email",
"address",
]
typeSpecifies the type of OIDC client being created. Allowed values are:

- public
- confidential

When creating a configuration client you must always set the type to confidential:

"type": "confidential"

Why? Well, when you go to retrieve an administrative access token you need to provide the client ID and client secret of a configuration client. But public clients don’t have client secrets. That means that public clients can’t be used as configuration clients.

Incidentally, you can’t change the client type after it’s been assigned: once a public client always a public client. Again, you can try to change the type, and your API call will run without generating an error. However, the client type won’t be changed, either.

Which simply means that, when creating a configuration client, you need to get it right the first time: don’t set the client type to public. If you do, you’ll have to start all over again.

If your POST call succeeds you’ll get back property values for your new configuration client:

{
   "id": "bccf1068-43a1-4fd5-a9e7-dac6a8b5c67e",
   "name": "Akamai Documentation Configuration Client",
   "redirectURIs": [
       "http://127.0.0.1"
   ],
   "loginPolicy": null,
   "tokenPolicy": "48e04957-2d89-414e-bfcd-5ca6298a2f07",
   "type": "confidential",
   "_links": {
       "self": {
           "href": "/config/e0a70b4f-1eef-4856-bcdb-f050fee66aae/clients/bccf1068-43a1-4fd5-a9e7-dac6a8b5c67e"
       }
   },
   "secret": "cATXBlpxsL8OQqnCF3QSm-4YBtLUi-0vobBOWWwbVUeXOUPlzSipJ7tqYolQQtiaH8C_A9KsczxjSsmiEladWw"
}

Notice the secret property at the bottom of the API response? That’s your client secret, and we point this out simply because, if you do fail to make a note if it, the secret can be a little tricky to find again. For example, suppose you disregarded our advice and forgot to note the client secret. But you’re not worried: after all, you can just use the GET method to return the properties of the configuration client (and yes, the client secret is a property of a configuration client), right?

Uh, no, no exactly. Instead, here’s what you’ll get back when you call the GET method:

{
   "id": "bccf1068-43a1-4fd5-a9e7-dac6a8b5c67e",
   "name": "Akamai Documentation Configuration Client",
   "redirectURIs": [
       "http://127.0.0.1"
   ],
   "loginPolicy": null,
   "tokenPolicy": "48e04957-2d89-414e-bfcd-5ca6298a2f0",
   "type": "confidential",
   "_links": {
       "self": {
           "href": "/config/e0a70b4f-1eef-4856-bcdb-f050fee66aae/clients/bccf1068-43a1-4fd5-a9e7-dac6a8b5c67e"
       }
   }
}

If you’re looking for the client secret, we’ll save you the trouble: it’s not there. Returning the properties of a configuration client doesn’t return the client secret after all. If you need to look up the client secret, you’ll have to use the /config/{customerId}/clients/{oidcClientId}/secret operation instead:

curl -X POST \
  'https://v1.api.us.janrain.com/e0a70b4f-1eef-4856-bcdb-f050fee66aae/config/clients/bccf1068-43a1-4fd5-a9e7-dac6a8b5c67e/secret' \
  --header 'Authorization: Bearer mjqC8wHYcxW6d4gxGolsfp3nSSmxX10DJbQUz0OD2JqNV3M44BmDOebotEOalUIF'

That API call does return the client secret:

{
   "secret": "cATXBlpxsL8OQqnCF3QSm-4YBtLUi-0vobBOWWwbVUeXOUPlzSipJ7tqYolQQtiaH8C_A9KsczxjSsmiEladWw"
}

Not a big deal, but something you need to know.

After you have the client ID and client secret you can use those values to configure Basic authentication and begin using your new configuration client to return configuration access tokens: