# Consume internal API on behalf of a citizen

This how-to guides you through the steps required to consume an API secured with [TokenX](/auth/tokenx.md):

## Prerequisites

- Your application receives requests with a citizen subject token in the `Authorization` header- The subject token can either be from [ID-porten](/auth/idporten.md) or from TokenX itself
- The API you're consuming has [granted access to your application](/auth/tokenx/how-to/secure.md#grant-access-to-consumers)

## Configure your application

Enable TokenX in your application:

```yaml
spec:
  tokenx:
    enabled: true
```

Depending on how you communicate with the API you're consuming, [configure the appropriate outbound access policies](/workloads/explanations/zero-trust.md#outbound-traffic):

**Service discovery**

```yaml
spec:
  accessPolicy:
    outbound:
      rules:
        - application: <some-api>
          namespace: <some-team>
```

**External addresses**

```yaml
spec:
  accessPolicy:
    outbound:
      external:
        - host: <some-host> 
```

## Exchange token

Send a HTTP POST request to the endpoint found in the `NAIS_TOKEN_EXCHANGE_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`. |
| `target` | `<cluster>:<namespace>:<other-app-name>` | The intended *audience* (target API or recipient) of the new token. |
| `user_token` | `eyJra...` | The user's access token from the inbound request. Token that should be exchanged. |

**application/json**

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

{
    "identity_provider": "tokenx",
    "target": "<cluster>:<namespace>:<other-app-name>",
    "user_token": "eyJra..."
}
```

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

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

identity_provider=tokenx&
target=<cluster>:<namespace>:<other-app-name>&
user_token=eyJra...
```

```json
{
    "access_token": "eyJra...",
    "expires_in": 3599,
    "token_type": "Bearer"
}
```

Your application does not need to validate this token.

> **Tokens are automatically cached by default**
> The endpoint will always return a cached token, if available.
> The endpoint will never return an expired token.

> To forcibly get a new token, set the `skip_cache` property to `true` in the request.
> This is only necessary if the token is denied by the target API, for example if permissions have changed since the token was issued.

## Consume API

Once you have acquired a new token, you can finally consume the target API by using the token as a [Bearer token](/auth/explanations.md#bearer-token):

```http
GET /resource HTTP/1.1

Host: api.example.com
Authorization: Bearer eyJraWQ...
```
