Token Introspection Endpoint

18

When an OAuth 2.0 client makes a request to the resource server, the resource server needs some way to verify the access token. The OAuth 2.0 core spec doesn’t define a specific method of how the resource server should verify access tokens, just mentions that it requires coordination between the resource and authorization servers. In some cases, especially with small services, both endpoints are part of the same system, and can share token information internally such as in a database. In larger systems where the two endpoints are on different servers, this has led to proprietary and non-standard protocols for communicating between the two servers.

The OAuth 2.0 Token Introspection extension defines a protocol that returns information about an access token, intended to be used by resource servers or other internal servers.

Introspection Endpoint

The token introspection endpoint needs to be able to return information about a token, so you will most likely build it in the same place that the token endpoint lives. The two endpoints need to either share a database, or if you have implemented self-encoded tokens, they will need to share the secret.

Token Information Request

The request will be a POST request containing just a parameter named “token”. It is expected that this endpoint is not made publicly available to developers. End-user clients should not be allowed to use this endpoint since the response may contain privileged information that developers should not have access to. One way to protect the endpoint is to put it on an internal server that is not accessible from the outside world, or it could be protected with HTTP basic auth.

POST /token_info HTTP/1.1
Host: authorization-server.com
Authorization: Basic Y4NmE4MzFhZGFkNzU2YWRhN

token=c1MGYwNDJiYmYxNDFkZjVkOGI0MSAgLQ

Token Information Response

The Token Introspection Endpoint should respond with a JSON object with the properties listed below. Only the “active” property is required, the rest are optional. Some of the properties in the Introspection spec are specifically for JWT tokens, so we will only cover the basic ones here. You can also add additional properties in the response if you have additional information about a token that may be useful.

active

Required. This is a boolean value of whether or not the presented token is currently active. The value should be “true” if the token has been issued by this authorization server, has not been revoked by the user, and has not expired.

scope

A JSON string containing a space-separated list of scopes associated with this token.

client_id

The client identifier for the OAuth 2.0 client that the token was issued to.

username

A human-readable identifier for the user who authorized this token.

exp

The unix timestamp (integer timestamp, number of seconds since January 1, 1970 UTC) indicating when this token will expire.

Example Response

Below is an example of the response that the introspection endpoint would return.

HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8

{
  "active": true,
  "scope": "read write email",
  "client_id": "J8NFmU4tJVgDxKaJFmXTWvaHO",
  "username": "aaronpk",
  "exp": 1437275311
}

Error Response

If the introspection endpoint is publicly accessible, the endpoint must first validate the authentication. If the authentication is invalid, the endpoint should respond with an HTTP 401 status code and an invalid_client response.

HTTP/1.1 401 Unauthorized
Content-Type: application/json; charset=utf-8

{
  "error": "invalid_client",
  "error_description": "The client authentication was invalid"
}

Any other error is considered an “inactive” token.

  • The token requested does not exist or is invalid
  • The token expired
  • The token was issued to a different client than is making this request

In any of these cases, it is not considered an error response, and the endpoint returns simply an inactive flag.

HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8

{
  "active": false
}

Security Considerations

Using a token introspection endpoint means that any resource server will be relying on the endpoint to determine whether an access token is currently active or not. This means the introspection endpoint is solely responsible for deciding whether API requests will succeed. As such, the endpoint must perform all applicable checks against a token’s state, such as checking whether the token has expired, verifying signatures, etc.

Token Fishing

If the introspection endpoint is left open and un-throttled, it presents a means for an attacker to poll the endpoint fishing for a valid token. To prevent this, the server must either require authentication of the clients using the endpoint, or only make the endpoint available to internal servers through other means such as a firewall.

Note that the resources servers are also a potential target of a fishing attack, and should take countermeasures such as rate limiting to prevent this.

Caching

Consumers of the introspection endpoint may wish to cache the response of the endpoint for performance reasons. As such, it is important to consider the performance and security trade-offs when deciding to cache the values. For example, shorter cache expiration times will result in higher security since the resource servers will have to query the introspection endpoint more frequently, but will result in an increased load on the endpoint. Longer expiration times leave a window open where a token may actually be expired or revoked, but still be able to be used at a resource server for the remaining duration of the cache time.

One way to mitigate this problem is for consumers to never cache the value beyond the expiration time of the token, which would have been returned in the “exp” parameter of the introspection response.

Limiting Information

The introspection endpoint does not necessarily need to return the same information for all queries of the same token. For example, two different resource servers (if they authenticate themselves when making the introspection request) may get different views of the state of the token. This can be used to limit the information about the token that is returned to a particular resource server. This makes it possible to have tokens that can be used at multiple resource servers without other servers ever knowing it is possible to be used at any other server.