# Validate Access Tokens

## When using IMSG

For services hosted behind an IMSG, nothing needs to be done. The IMSG does already support access tokens. The IMSG will take care of validating the access token and create a service token, just as if the API was accessed with an ID token.

## Validate without IMSG

### Authentication

*Authentication means being sure of who the caller is*

The steps required to ensure an access token is valid are the following:

1. Ensure `ntt` (Naviga Token Type) claim in the access token payload equals `access_token`
2. Read the `kid` (key id) from the access token header.&#x20;
3. Fetch the corresponding public key from [`https://imas.stage.imid.infomaker.io/v1/jwks`](https://imas.stage.imid.infomaker.io/v1/jwks) for stage env or [`https://imas.imid.infomaker.io/v1/jwks`](https://imas.imid.infomaker.io/v1/jwks)  for production env.
4. Ensure `alg` (algorithm) in the access token header is identical to the key's `alg`&#x20;
5. Use a suitable library for your language to validate the access-token signature using the key
6. Check that current time is less than `exp` in access token payload.&#x20;

{% hint style="warning" %}
It's important that server clock is synchronized, if not, the application might accept tokens that have expired.
{% endhint %}

The keys published on `/jwks`can, and should, be cached for up to 10 min in the application.

Note, a token with a `kid` that does not exist in a cached `/jwks` might still be a valid token. It might be that a new key has been published but not yet fetched by the application. For that reason, the application should re-fetch the `/jwks` (once) if an unknown `kid` appears. &#x20;

Similarly, a key might be revoked at any time, so never cache `/jwks` for more than 10min. If `/jwks` is cached for a longer period of time, tokens with invalidated `kid`/signature can appear to be valid when they are not.&#x20;

### Authorization

*Authorization means knowing what actions the caller is allowed to do*

Permissions are included as described by the payload below. Permission strings are on the format `service_name:permission_name`.  Permissions in the `permissions.org` array should are valid in all units while permissions in `permissions.units[unit_name]` array is only valid in that specific unit.

More information about Naviga ID's permission model can be found on the [authorization schema](https://docs.navigaglobal.com/navigaid/architecture/groups-and-roles) page.

The Access Token payload is as follows:

```javascript
{ 
  "ntt": "access_token", // ntt stands for Naviga Token Type
  "org": string, // org name
  "sub": uuid_string, // subject is the unique user id in Naviga ID
  "groups": [string, string,...], // groups the sub belongs to in the organization's identitity provider
  "userinfo": { 
    "given_name": string, // optional
    "family_name": string,  // optional
    "email": string, // optional
    "picture": string // optional
  },
  "permissions": {
    "org": [string, string,...] // permissions valid in all units,
    "units": {
      unit_string_name : [string, string...], // permissions only valid in unit unit_string_name
      ...
    } 
  } 
  "iat": unix_timestamp_seconds, // issued at
  "exp": unix_timestamp_seconds,  // expires at
  "jti": uuid_string, // token id
} 
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.navigaglobal.com/navigaid/access-token/validate-access-tokens.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
