<iframe src="https://www.googletagmanager.com/ns.html?id=GTM-M74D8PB" height="0" width="0" style="display:none;visibility:hidden">
Loading
Skip to NavigationSkip to Main Content
Validate Tokens with Public Key / Private Key Signed JWTs Using /introspect and a Service Application Integration
API Access Management
Okta Classic Engine
Okta Identity Engine
Overview

This article intends to exemplify how to use the /introspect endpoint with a service application using public key / private key client authentication method.

Applies To
Solution

This testing method demonstrates how to use the private_key_jwt client authentication and verify if a Token is valid with the /introspect endpoint.

This scenario uses a Service Application with a public key / private key since the request contains scopes that can be granted by the Org Authorization Server only. 

Retrieve the public key / private key from the Service Application in order to create the JWT Token used in the client_assertion. The Token can be created with tools like jwt.io. The Header, Payload, and Verify Signature sections have to be filled with the relevant data. 

The aud claim needs to be adjusted to reflect the endpoint where it is about to be sent.

In this case, the aud claim has to be https://${subdomain}.okta.com/oauth2/v1/token.

token  

Copy the Token generated in jwt.io and use it with the /token endpoint as the client_assertion parameter value:

curl --location 'https://${subdomain}.okta.com/oauth2/v1/token?client_assertion=${insertGeneratedTokenHere}' \
--header 'Accept: application/json' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'grant_type=client_credentials' \
--data-urlencode 'scope=okta.users.read okta.groups.read okta.idps.manage' \
--data-urlencode 'client_assertion_type=urn:ietf:params:oauth:client-assertion-type:jwt-bearer'

 

The curl should return an Access Token along with token_type, expires_in, and scope values:

{
    "token_type": "Bearer",
    "expires_in": 3600,
    "access_token": "eyJraWQiOiIzTjFVNlB2dnpmS21xWDVRLUFFNmlyTU96MEFXeGhU...",
    "scope": "okta.users.read okta.groups.read okta.idps.manage"
}

 

In order to verify the validity with /introspect, the Access Token needs to be sent as a token parameter value along with a newly generated JWT Token. The aud claim needs to be adjusted to reflect the endpoint where it is about to be sent.

In this case, the aud claim has to be https://${yourDomain}.okta.com/oauth2/v1/introspect.

introspect 

 

Use the new JWT Token to validate the Access Token returned from the /token endpoint:

curl --location 'https://${subdomain}.okta.com/oauth2/v1/introspect?client_assertion=${newJWTToken}' \
--header 'Accept: application/json' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'token=${AccessToken}' \
--data-urlencode 'token_type_hint=access_token' \
--data-urlencode 'grant_type=client_credentials' \
--data-urlencode 'client_assertion_type=urn:ietf:params:oauth:client-assertion-type:jwt-bearer'

 

If the Access Token is valid, the response will contain "active": true along with other data about the Access Token:

    "active": true,
    "scope": "okta.users.read okta.groups.read okta.idps.manage",
    "exp": 1731416981,
    "iat": 1731413381,
    "sub": "0oa5aqr7pwKCxZAhH0x7",
    "aud": "https://${subdoamin}.okta.com",
    "iss": "https://${subdoamin}.okta.com",
    "jti": "AT.8GaLb97SoJGyNjLMKWcsHyMDbLMoTHoVe9chK1Flm5k",
    "token_type": "Bearer",
    "client_id": "0oa5aqr7pwKCxZAhH0x7"
}
 

 

Loading
Validate Tokens with Public Key / Private Key Signed JWTs Using /introspect and a Service Application Integration