What is Token Introspection?
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.
What token types does IndyKite support?
Opaque Tokens
What are opaque tokens?
- Random strings with no readable structure.
- Must be validated online via
/introspector/userinfoendpoints. - Commonly issued by providers like Okta, Auth0, Keycloak.
- Enable centralized revocation and token lifecycle management.
How does opaque token validation work?
- Client sends the token to a resource server.
- 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
- The authorization server returns JSON describing the token:
{ "active": true, "scope": "read write", "client_id": "client123", "username": "alice", "sub": "user123", ... }
- The resource server uses the returned claims for authorization and access control decisions.
JWT Tokens (JSON Web Tokens)
What are JWT 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.
How does JWT validation work?
- Receives the JWT (e.g., via
Authorization: Bearer ...header).
- Decodes the token (Base64) to inspect claims.
- Verifies the signature using:
- A public key (RS256) from the issuer's JWKS endpoint.
- Or a shared secret (HS256).
- 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.
How does IndyKite handle third-party tokens?
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.
Step 1: How do I configure token validation?
The configuration specifies how to validate the token. You can choose between:
JWT (Offline Validation)
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 Validation)
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.
}
What do the configuration fields mean?
| Field | Description |
|---|---|
jwt_matcher.issuer |
Exact match for the iss claim in the JWT |
jwt_matcher.audience |
Exact match for the aud claim in the JWT |
opaque_matcher.hint |
Domain hint for opaque token identification |
offline_validation |
Use for JWT tokens; validates using public keys |
online_validation.user_info_endpoint |
Endpoint to validate opaque tokens and fetch claims |
online_validation.cache_ttl |
Seconds to cache token validity (reduces endpoint calls) |
ikg_node_type |
Node type in IKG to match with token subject (e.g., Person) |
claims_mapping |
Map token claims to IKG property names |
perform_upsert |
If true, creates/updates identity node in IKG when not found |
Step 2: How does subject mapping work?
After validating the token, IndyKite matches the token subject to an identity node in the IKG.
What information is needed for matching?
- Subject claim: Usually the
subclaim from the third-party IDP, which equalsexternal_idin the IKG.You can also use a different claim to identify the subject.
Important: Never use
external_idas aclaims_mappingkey—it's used for matching. - Node type: Specified in the configuration via
ikg_node_type. Required becauseexternal_idis only unique per node type, not across the entire IKG.
Step 3: How does claims mapping work?
The claims_mapping attribute specifies which claims from the token should be mapped to IKG property names.
- Key: The new claim name and IKG property name.
- Max length: 256 characters
- Pattern:
^[a-zA-Z_][a-zA-Z0-9_]+$
- Value: The token claim to map from.
Which claims are supported?
All standard claims from the OpenID specification are supported. Mapping will fail if claim and data type do not match the standard. For non-standard claims, the type is derived from the JSON.
Warning: Claims mapping can override existing claims, which may affect internal services.
Step 4: What is Just-In-Time (JIT) provisioning?
When perform_upsert = true, IndyKite supports Just-In-Time provisioning: automatically creating or updating an identity node in the IKG based on token claims.
How does JIT provisioning work?
- When a user accesses the system for the first time, their identity node is created on-demand using token attributes.
- The user is granted access immediately based on their new local identity.
Important: For performance reasons, if a created identity node is deleted, token introspection will not create a new node with the same token. A new token must be generated.
What configuration options are available?
| Option | JWT | Opaque |
|---|---|---|
| Issuer | Required | Not used |
| Audience (client_id) | Required | Not used |
| Public Key (JWKS) | Used for signature verification | Not used |
| User Info / Introspect Endpoint | Optional for Offline / Required for Online | Required |
| Caching | JWKS & claims caching | Token metadata caching |
| Validation Method | Offline or Online | Online only |
What claims are commonly used?
| 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 |
Authentication Context Class Reference (used for step-up authentication) |
What features does IndyKite Token Introspect support?
| Feature | Supported |
|---|---|
| JWT introspection | Yes |
| Opaque token introspection | Yes (Online) |
| Third-party token exchange | Yes |
| Public key & metadata caching | Yes |
| Multi-IDP support | Yes |
| Claims mapping | Yes (Configurable) |
| Just-In-Time provisioning (node upsert into IKG) | Yes (Optional) |
Next Steps
- Terraform examples: Token Introspect Terraform Configuration
- REST API: Config API Documentation
- Full examples: Developer Hub Resources
- Credentials guide: Credentials Guide