---
name: appid-tokens
title: Validating tokens
description: 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&reg; 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!
last-updated: 2026-03-04
---

> ## Documentation Index
> The table of contents for this documentation set is at https://cloud.ibm.com/docs/appid?format=markdown
> The index for all IBM Cloud docs is at: https://cloud.ibm.com/docs/llms.txt
> Use these files to discover more information as needed.

# Validating tokens
{: #token-validation}

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&reg; 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!
{: shortdesc}

For more information about how tokens are used in App ID, see [Understanding tokens](https://cloud.ibm.com/docs/appid?topic=appid-tokens&format=markdown).
{: tip}

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?**

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
{: #remote-validation}

By using introspection, you can use App ID to validate your tokens.
{: shortdesc}

1. Send a POST request to the [/introspect](https://us-south.appid.cloud.ibm.com/swagger-ui/#/Authorization%20Server%20-%20Authorization%20Server%20V4/oauth-server.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:

      ```sh
      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
      ```
      {: screen}

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:

      ```json
      {
      "active": true
      }
      ```
      {: screen}


## Manually Validating Tokens
{: #local-validation}

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


1. Parse the tokens. The [JSON Web Token (JWT)](https://datatracker.ietf.org/doc/html/rfc7519){: external} 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](https://jwt.io/#libraries-io){: external} to parse the token.

   Example encoded token:

      ```sh
      eyJhbGciOiJSUzI1NiIsInR5cCI6IkpPU0UiLCJraWQiOiJhMmszIn0
      .eyJpc3MiOiJhcHBpZC1vYXV0aCIsImF1ZCI6ImFiYzEyMyIsImV4cCI6MTU2NDU2Nn0
      .IycnAGUmMHzpTWbe-qaRsx0B4Zi-SVav710Fb_8CTCQvLrHX9d42WuCZ5bW
      d-ikgEsf6waQxeBfhfwYxwHN87LZupApagVMZtylVAnXhG1pHu_32wbZsPvg6QjzNO
      j6ys2Lfl3qfb5Qrp9u4IsZltKPEN8HdfeOcKXxpw6UqP-8
      ```
      {: screen}

   Example decoded token:

      ```json
      {
      "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
      }
      ```
      {: screen}

2. Make a call to the [/publickeys endpoint](https://us-south.appid.cloud.ibm.com/swagger-ui/#!/Authorization%20Server%20-%20Authorization%20Server%20V4/oauth-server.publicKeys){: external} to retrieve your public keys. The public keys that are returned are formatted as [JSON Web Keys (JWK)](https://datatracker.ietf.org/doc/html/rfc7517){: external}.

   Example request:

      ```sh
      GET /oauth/v4/<tenantID>/publickeys HTTP/1.1
      Host: us-south.appid.cloud.ibm.com
      Cache-Control: no-cache
      ```
      {: screen}

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:

      ```json
      {
      "keys": [
         {
            "kty": "RSA",
            "use": "sig",
            "n": "AsdaE",
            "e": "SDAasw",
            "kid": "ad123dCAz"
         }
      ]
      }
      ```
      {: screen}

   | 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. |
   {: caption="Public key parameters" caption-side="top"}

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](https://jwt.io/) to validate the signature.

6. Validate the claims that are stored in the tokens. To verify future checks, you can use [this list](https://openid.net/specs/openid-connect-core-1_0.html#IDTokenValidation).

   | 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. |
   {: caption="Claims that must be validated" caption-side="top"}