IBM Cloud Docs
Validating tokens

Validating tokens

Token validation is an important part of modern app development. By validating tokens, you can protect your app or APIs from unauthorized users. IBM Cloud® App ID uses access and identity tokens to ensure that a user or app is authenticated before they are granted access. If you're using one of the SDKs provided by App ID, both obtaining and validating your tokens is done for you!

For more information about how tokens are used in App ID, see Understanding tokens.

Tokens are used to verify that a person is who they say that they are. They confirm any access permissions that the user might hold, for a specified length of time. When a user signs in to your application and is issued a token, your app must validate the user before they are given access.

What if I'm working in a language that App ID doesn't have an SDK for?

Don't worry! You have three options:

  • Work with the App ID APIs
  • Implement your own validation logic
  • Use any OIDC-compliant open source SDK

Using the App ID APIs

By using introspection, you can use App ID to validate your tokens.

  1. Send a POST request to the /introspect API endpoint to validate your token. The request must provide the token and a basic authorization header that contains the client ID and secret.

    Example request:

    POST /oauth/v4/<tenantID>/introspect HTTP/1.1
    Host: us-south.appid.cloud.ibm.com
    Content-Type: application/x-www-form-urlencoded
    Authorization: Basic jdFlUaGlZUzAwTW0Tjk15TmpFMw==
    Cache-Control: no-cache
    
    token=XXXXX.YYYYY.ZZZZZ
    
  2. The server checks the expiry and signature of the token and returns a JSON object that tells whether the token is active or inactive.

    Example response:

    {
    "active": true
    }
    

Manually Validating Tokens

You can validate your tokens locally by parsing the token, verifying the token signature, and validating the claims that are stored in the token.

  1. Parse the tokens. The JSON Web Token (JWT) is a standard way of securely passing information. It consists of three main parts: Header, Payload, and Signature. They are base64URL encoded and separated by a dot(.). You can use any base64URL decoder available to parse the token. Alternatively, you can use any of the libraries that are listed to parse the token.

    Example encoded token:

    eyJhbGciOiJSUzI1NiIsInR5cCI6IkpPU0UiLCJraWQiOiJhMmszIn0
    .eyJpc3MiOiJhcHBpZC1vYXV0aCIsImF1ZCI6ImFiYzEyMyIsImV4cCI6MTU2NDU2Nn0
    .IycnAGUmMHzpTWbe-qaRsx0B4Zi-SVav710Fb_8CTCQvLrHX9d42WuCZ5bW
    d-ikgEsf6waQxeBfhfwYxwHN87LZupApagVMZtylVAnXhG1pHu_32wbZsPvg6QjzNO
    j6ys2Lfl3qfb5Qrp9u4IsZltKPEN8HdfeOcKXxpw6UqP-8
    

    Example decoded token:

    {
    "alg": "RS256",
    "typ": "JOSE",
    "kid": "a2k3",
    "iss": "https://us-south.appid.cloud.ibm.com/oauth/v4/39a37f57-a227-4bfe-a044-93b6e6050a61",
    "aud": "abc123",
    "exp": 1564566
    }
    
  2. Make a call to the /publickeys endpoint to retrieve your public keys. The public keys that are returned are formatted as JSON Web Keys (JWK).

    Example request:

    GET /oauth/v4/<tenantID>/publickeys HTTP/1.1
    Host: us-south.appid.cloud.ibm.com
    Cache-Control: no-cache
    
  3. Store the keys in your app cache for future use. Storing the keys speeds up the process and prevents network delay if another call is made.

  4. Import the public key parameters.

    Example response:

    {
    "keys": [
       {
          "kty": "RSA",
          "use": "sig",
          "n": "AsdaE",
          "e": "SDAasw",
          "kid": "ad123dCAz"
       }
    ]
    }
    
    Public key parameters
    Parameter Description
    kty Defines the algorithm that is used.
    use Defines the purpose of the key.
    kid Defines the unique ID of the key.
    Other There might be other remaining parameters that are specific to your algorithm that must also be imported.
  5. Verify the token's signature. The token header contains the algorithm that was used to sign the token and the Key ID or kid claim of the matching public key. Because public keys do not frequently change, you can cache public keys in your app and occasionally refresh them. If your cached key is missing the kid claim, you can validate the tokens locally.

    1. Have your application verify that the contents of the incoming token header match the parameters of the public key.
    2. Check specifically that the same algorithms were used and that your public key cache contains a key with the relevant Key ID.
    3. Ensure that your hash value is the same as the signature of the PEM form of the public key. Your hash value can be obtained by combining and hashing the header of the payload of the token. Because this process can be complex to manually implement, it might be helpful to use one of the listed libraries to validate the signature.
  6. Validate the claims that are stored in the tokens. To verify future checks, you can use this list.

    Claims that must be validated
    Claim Description
    iss The issuer must be the same as the App ID OAuth server.
    exp The current time must be less than the expiry time.
    aud The audience must contain the client ID of your app.
    tenant The tenant must contain the tenant ID of your app.
    scope The scope of permissions that is granted to the user. This is specific to the access token.