# Secure your API with TokenX

This how-to guides you through the steps required to secure your API using [TokenX](/auth/tokenx.md):

## Grant access to consumers

Specify inbound access policies to authorize your consumers:

```yaml
spec:
  tokenx:
    enabled: true
  accessPolicy:
    inbound:
      rules:
        - application: app-1  # same namespace and cluster

        - application: app-2  # same cluster
          namespace: team-a

        - application: app-3
          namespace: team-b
          cluster: prod-gcp
```

The above configuration authorizes the following applications:

- application `app-1` running in the same namespace and same cluster as your application
- application `app-2` running in the namespace `team-a` in the same cluster
- application `app-3` running in the namespace `team-b` in the cluster `prod-gcp`

Now that you have granted access to your consumers, they can now exchange tokens for new tokens that target your application.
You will need to validate these tokens in your application.

## Validate tokens

Verify incoming requests from consumers by validating the [JWT Bearer token](/auth/explanations.md#bearer-token) in the `Authorization` header.

The steps below describe how to validate a token using the *token introspection endpoint*.

> **What is the token introspection endpoint?**
> The token introspection endpoint simplifies the token validation process, but does require a network call.

> If your application uses a library or framework that supports validering JWTs, you can alternatively let these handle the validation instead.
> See [the reference page for manually validating tokens](/auth/tokenx/reference.md#manual-token-validation).

Send a HTTP POST request to the endpoint found in the `NAIS_TOKEN_INTROSPECTION_ENDPOINT` environment variable.
The request must have a `Content-Type` header set to either:

- `application/json` or
- `application/x-www-form-urlencoded`

The body of the request should contain the following parameters:

| Parameter | Example Value | Description |
| :--- | :--- | :--- |
| `identity_provider` | `tokenx` | Always `tokenx`. |
| `token` | `eyJra...` | The access token you wish to validate. |

**application/json**

```http
POST ${NAIS_TOKEN_INTROSPECTION_ENDPOINT} HTTP/1.1
Content-Type: application/json

{
    "identity_provider": "tokenx",
    "token": "eyJra..."
}
```

**application/x-www-form-urlencoded**

```http
POST ${NAIS_TOKEN_INTROSPECTION_ENDPOINT} HTTP/1.1
Content-Type: application/x-www-form-urlencoded

identity_provider=tokenx&
token=eyJra...
```

The response is always a HTTP 200 OK response with a JSON body.

It always contains the `active` field, which is a boolean value that indicates whether the token is valid or not.

##### Success response

If the token is valid, the response will additionally contain **all** the token's claims:

```json
{
    "active": true,
    "exp": 1730980893,
    "iat": 1730977293,
    ...
}
```

Claims are copied verbatim from the token to the response.

> **Which claims are validated by the endpoint?**
> The endpoint only validates the token's signature and its [standard claims](/auth/explanations.md#claims-validation).

> [Other claims](/auth/tokenx/reference.md#claims) are included in the response, but are not validated.
> Your application must validate these other claims according to your own requirements.

##### Error response

If the token is invalid, the only additional field in the response is the `error` field:

```json
{
    "active": false,
    "error": "token is expired"
}
```

The `error` field contains a human-readable error message that describes why the token is invalid.
