Back to all guides
Token Introspect

Token Introspect guide

What is needed to configure Token Introspect for the IndyKite platform.

Token introspection is the process through which a resource server validates an access or refresh token by querying the authorization server, typically via an introspection endpoint. This yields metadata (claims) about the token—such as subject (sub), scopes, issuer, and expiration.

Standardized by OAuth 2.0 Token Introspection (RFC 7662), introspection is critical for validating opaque tokens and can also play a role in managing JWTs across distributed systems.

Token Types & Validation Methods

1. Opaque Tokens

  • Represented as random strings with no readable structure.
  • Must be validated online via /introspect or /userinfo endpoints.
  • Commonly issued by providers like Okta, Auth0, Keycloak.
  • Enable centralized revocation and token lifecycle management.

Flow:

  1. Client sends the token to a resource server.
  1. The resource server sends a POST request to the introspection endpoint:
    POST /introspect
    Authorization: Basic base64(client_id:client_secret)
    Content-Type: application/x-www-form-urlencoded
    token=ACCESS_TOKEN
    
  1. The authorization server returns JSON describing the token:
    {
    "active": true,
    "scope": "read write",
    "client_id": "client123",
    "username": "alice",
    "sub": "user123",
    ...
    }
    
  1. The resource server uses the returned claims for authorization and access control decisions.

2. JWT Tokens (JSON Web Tokens)

  • Self-contained, signed tokens that include structured claims.
  • Can be validated offline, without contacting the issuer, by:
    • Decoding the payload.
    • Verifying the signature using a public key (via JWKS or .well-known).
  • Use introspection optionally for:
    • Claim enrichment.
    • Additional validation logic or identity mapping.

Flow:

  1. Receives the JWT (e.g., via Authorization: Bearer ... header).
  1. Decodes the token (Base64) to inspect claims.
  1. Verifies the signature using:
    • A public key (RS256) from the issuer's JWKS endpoint.
    • Or a shared secret (HS256).
  1. Uses verified claims (sub, exp, scope, aud, etc.) to enforce access policies.
Introspection endpoints are not necessary for JWTs when the token can be fully validated offline.

IndyKite-Specific Token Handling

IndyKite APIs can identify users via third-party tokens through token introspection configuration. This configuration enables the IndyKite platform to validate these tokens and utilize their content. Therefore, you must create a configuration that outlines how this token introspection should occur.

Process: Token Exchange with 3rd-Party JWTs

Step 1: Validation

This process involves examining the iss (issuer) claim within the JWT. If the token is issued by IndyKite, standard introspection procedures apply. Otherwise, the configuration must be fetched to perform the necessary checks.

The configuration will contain the type of verification:

  • JWT (Offline): Validate using public keys or .well-known/jwks.json.

Terraform example:

resource "indykite_token_introspect" "token_config" {
  name         = "terraform-token-introspect"
  display_name = "Terraform token introspect"
  description  = "Token introspect for User access token"
  location     = "ProjectGID"
  jwt_matcher {      -> JWT specifies all attributes to match with received token.
    issuer   = "https://xx.xx.auth0.com/"     -> Issuer is used to exact match based on iss claim in JWT.
    audience = "client-id"     -> Audience is used to exact match based on aud claim in JWT
  }
  offline_validation {}     -> Offline validation works only with JWT. If public_jwks is empty, will be generated
   ikg_node_type = "Person"      -> Node type in IKG to which we will try to match sub claim with DT external_id.
   claims_mapping = {      -> ClaimsMapping specifies which claims from the token should be mapped to IKG Property with given name.
        "email" = "email"
        "phone_number" = "phone_number"
    }
   perform_upsert = true       -> Perform Upsert specify, if we should create and/or update Identity node in IKG if it doesn't exist with.
}
  • Opaque (Online): Use /userinfo or introspection endpoints.

Terraform example:

resource "indykite_token_introspect" "token_config" {
  name         = "terraform-token-introspect"
  display_name = "Terraform token introspect"
  description  = "Token introspect for User access token"
  location     = "ProjectGID"
  opaque_matcher {   -> Opaque specifies the configuration is for opaque tokens.
    hint   = "my.domain.com"
  }
  online_validation {
    user_info_endpoint = "https://example.com/userinfo"   -> URI of userinfo endpoint which will be used to validate access token and also fetch user claims when opaque token is received. It can remain empty, if JWT token matcher is used
    cache_ttl = 600    -> Cache TTL of token validity can be used to minimize calls to userinfo endpoint. If not set, token will not be cached and call to userinfo endpoint will be made on every request
  }
   ikg_node_type = "Person"     -> Node type in IKG to which we will try to match sub claim with identity node external_id.
   claims_mapping = {       -> ClaimsMapping specifies which claims from the token should be mapped to IKG Property with given name.
        "email" = "email"
        "phone_number" = "phone_number"
    }
   perform_upsert = true    -> Perform Upsert specify, if we should create and/or update Identity node in IKG if it doesn't exist with.
}

Step 2: Subject Mapping

When the validity of the token and data are known from previous step, we can start with matching the IndyKite sub based on received sub from the 3rd party IDP.

To properly do this matching, we need to know:

  • Usually, sub claim from 3rd party IDP that is equal to external_id in IKG. (Therefore, you should never use external_id as a claims_mapping key).

    You can also use a different claim to identify the subject.

  • type that is part of configuration
    • external_id is not unique within whole IKG, but only per type. To uniquely find an identity node, we need to know its type too.

Based on that, we will know all the data to populate IndyKite token claims.

Step 3: Claims Mapping

The claims_mapping attribute specifies which claims from the token should be mapped to new names and name of property in IKG. Be aware, that this can override any existing claims, which might not be accessible anymore by internal services.

Key specifies the new name and also the name of the property in IKG.

It must follow: max_len: 256 and pattern: "^[a-zA-Z_][a-zA-Z0-9_]+$"

Value specifies which Token claim to map and how.

By default we support all standard claims from OpenID specification https://openid.net/specs/openid-connect-core-1_0.html#StandardClaims and mapping will fail if claim and data type do not match the standard.

For non-standard claims the type will be derived from the JSON.

Step 4: Token Exchange and Optional Upsert

Optionally supports Just-In-Time (JIT) provisioning: upsert the corresponding identity node in the IKG based on claims (perform_upsert attribute set to true).

JIT provisioning refers to the on-demand creation of a user identity node in the IKG when the user accesses the system for the first time, using the identity attributes from the token.

The user is granted access immediately, based on their new local identity.

Be aware that for performance reasons, if the created identity node is deleted, the token introspect will not create a new node if called again with the same token. A new token will need to be generated.

Configuration & Integration Options

Option JWT Opaque
Issuer ✅ Required
Audience (client_id) ✅ Required
Public Key (JWKS) ✅ Used for signature verification
User Info / Introspect Endpoint Optional for Offline / ✅ Required for Online ✅ Required
Caching ✅ JWKS & claims caching ✅ Token metadata caching
Validation Method Offline/Online Online

Common Claims in Introspection & JWTs

Claim Description
sub Subject (user ID) of the token.
username Login name of the user.
email Email of the user.
client_id OAuth client that obtained the token.
exp, iat Expiration and issued-at timestamps.
scope Space-separated list of access scopes.
aud Intended audience(s).
iss Issuer of the token.
jti Unique token identifier.
roles, permissions Optional claims for access control.
acr If acr Claim requested as Essential with values parameter requesting specific Authentication Context Class Reference values, the Authorization Server MUST return an acr Claim Value that matches one of the requested values.

Feature Summary

Feature Supported
JWT introspection
Opaque token introspection ✅ (Online)
Third-party token exchange
Public key & metadata caching
Multi-IDP support
Claims mapping ✅ Configurable
Just-In-Time provisioning (node upsert into IKG) ✅ Optional