IBM Cloud Docs
Custom identity

Custom identity

You can use your own custom identity provider when you are authenticating. Your identity provider can conform to any authentication mechanism alternate to those supported by IBM Cloud® App ID, including proprietary or legacy.

Overview

By bringing your own identity provider, you can create a custom authentication flow that uses your own protocols. You have more control, such as information that you want to share or information that is stored.

Be sure to configure your custom provider before you add it to your application.

When would I want to use this flow?

When App ID does not provide direct support for a particular identity provider, you can use the custom identity flow to bridge the authentication protocol to App ID's existing authentication flow. For example, you want to use GitHub or LinkedIn to allow your users to sign in. You can use the identity provider's existing SDK to facilitate user authentication information before packaging and exchanging it with App ID.

There are many scenarios where a different authentication flow is necessary:

  • Proprietary, in-house identity providers
  • Third-party identity providers
  • Complicated authentication flows, which can include proprietary multi-factor mechanisms

Occasionally, a legacy provider might use their own custom authentication protocol. Because the custom identity flow completely decouples authentication from authorization, you can adopt any authentication mechanism of your choice and then provide the resulting authentication information to App ID. All without exposing user credentials.

Technically, how does this flow work?

The custom identity workflow is built on the JWT-Bearer extension grant type that is defined in Assertion Framework for OAuth 2.0 Authorization Grants [RFC7521]. To exchange user information for App ID tokens, your authentication architecture creates a trust relationship with App ID by using an asymmetric RSA key pair. Once trust is established, you can use the JWT-Bearer grant type to exchange verified user information within a signed JWT for App ID tokens.

What does the flow look like?

As with all authentication flows, custom identity requires that the application is able to establish a degree of trust with App ID to ensure the integrity of identity provider user information. Custom identity employs an asymmetric RSA public and private key pair to establish its trust relationship. Depending on your architectural requirements, custom identity supports two trust models that differ only in the storage location and usage of the private key.

Custom authentication request flow
The request flows for custom authentication

Identity provider signed flow
  1. Identity provider signed
Just as with traditional OAuth 2.0 flows, the most secure trust model creates a relationship between your identity provider and authorization server; in this case App ID) directly. Under this model, your identity provider is responsible for storing the private key and signing JWT assertions. When passed to App ID, these assertions are validated with the matching public key, which ensures that the user information from your identity provider was not maliciously altered during transport.
Application signed flow
  1. Application signed
Alternatively, you can base your trust model on the relationship between your app and App ID. In this workflow, your private key is stored in your server-side application. After a successful authentication, your app is responsible for converting the identity providers response into a JWT and signing it with its private key before the app sends the token to App ID. Since this identity provider has no relationship with App ID, this architecture creates a weaker trust model. Although App ID can trust the information that is sent by the server-side application, it cannot be certain the data was the original sent by the identity provider.

Generating a JSON web token

You can convert your verified user data to a custom identity JWT by generating a JSON web token. The token must be signed with the private key that matches your preconfigured public key. For a list of token signing libraries, check out https://jwt.io/.

Example JWT format

{
  // Header
  "alg": "RS256",
  "typ": "JOSE",
  // Payload
  // Required
  "iss": "String", // Should reference your identity provider
  "aud": "String", // Must be the OAuth server URL name
  "exp": "Int",    // Should be a value with a short lifespan
  "sub": "String", // Must be the unique user ID provided by your identity provider

  // Normalized claims (optional)
  "name": "String",
  "email": "String",
  "locale": "String",
  "picture": "String",
  "gender": "String",

  // Custom Scopes to add to access token (optional)
  scope="custom_scope1 custom_scope2"

  // Other custom claims (optional)
  role="admin"
}
JWS fields
Field Description
iss Should contain a reference to your identity provider.
aud The OAuth server URL. Format: https://<region>.appid.cloud.ibm.com/oauth/v4/<tenantID>.
exp The length of time that the token is valid. For security reasons, it should have a short life span and be specific.
sub The unique user ID that is provided by the identity provider.
Normalized claims All normalized claims are provided in the identity token that is returned in response to this request. More custom claims can be found by using the /userinfo endpoint.
Scope

By default, all App ID tokens contain a group of preset scopes. You can request extra scopes by doing one of the following:

  • Specify the scope in the scope field of your JWS token.
  • Specify the scope through the URL-form scopes parameter of the /token request.

Retrieving App ID tokens

To create the bridge between your custom provider and App ID, you need to have App ID tokens. To obtain service tokens, exchange your verified user information by using the /token endpoint.

Post /token
Content-Type: application/x-www-from-urlencoded
grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer
assertion=<payload>
scope="<spaceSeparatedScopeArray>"
Required request variables
Variable Description
Content-type applications/x-www-from-urlencoded
grant_type urn:ietf:params:oauth:grant-type:jwt-bearer
assertion A JWS payload string.
scope A white space separated list of your custom scopes.