> For the complete documentation index, see [llms.txt](https://docs.navigaglobal.com/navigaid/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.navigaglobal.com/navigaid/access-token/using-access-tokens.md).

# Fetching and using Access Tokens

## Introduction

Access tokens are short lived JWT tokens that can identify either a user or an application. For an introduction to the JWT standard, see [https://jwt.io/introduction](https://jwt.io/introduction/.).

Because the tokens are short lived and since they can not be refreshed on their own, the verification of them are simpler than compared to ID-tokens. This means that they can be validated without the need for an IMSG reverse proxy.

This document describes how to fetch and use Naviga ID access tokens.

{% hint style="info" %}
The links in these instructions point to the stage environment. To access the production systems, simply remove `.stage` from all URLs. For example: \
Stage Access-Token Service:[ ](https://access-token.stage.imid.infomaker.io)[`https://access-token.stage.imid.infomaker.io`](https://access-token.stage.imid.infomaker.io)\
Prod Access-Token Service:[`https://access-token.imid.infomaker.io`](https://access-token.stage.imid.infomaker.io)
{% endhint %}

## Fetch access tokens

There are two ways to authenticate to retrieve an access token, either as a user or as an application.&#x20;

{% hint style="info" %}
Locally cache and reuse Access Tokens for as long as they are valid (i.e. not expired). Do not fetch a new access token for each request you perform to a service API such as CCA or OC.
{% endhint %}

### Fetch access-token as logged in user

## As a logged in user, using ID-token

<mark style="color:green;">`POST`</mark> `https://access-token.stage.imid.infomaker.io/v1/token`

Choose **ONE** of the available ways to include the ID-token in the request.

#### Query Parameters

| Name        | Type   | Description                  |
| ----------- | ------ | ---------------------------- |
| imid\_token | string | Value should be the ID token |

#### Headers

| Name          | Type   | Description                                                                                                          |
| ------------- | ------ | -------------------------------------------------------------------------------------------------------------------- |
| Cookie        | string | ID-token set as `dev-imidToken` cookie. In client web applications, this is done by setting `credentials: 'include'` |
| Authorization | string | `Bearer ${ID token}`                                                                                                 |

{% tabs %}
{% tab title="200 " %}

```
{ 
  "access_token" : "eyJhbGciOiJIUzI1NiIsInR…", 
  "token_type": "Bearer", 
  "expires_in": 600 
}
```

{% endtab %}
{% endtabs %}

{% hint style="warning" %}
Groups are only included in the access token if they have a "group to role"-mapping setup in Naviga ID Login.&#x20;
{% endhint %}

### Fetch a scoped access-token as logged in user

## As a logged in user, using ID-token

<mark style="color:green;">`POST`</mark> `https://access-token.stage.imid.infomaker.io/v1/token`

Choose **ONE** of the available ways to include the ID-token in the request.

#### Query Parameters

| Name        | Type   | Description                  |
| ----------- | ------ | ---------------------------- |
| imid\_token | string | Value should be the ID token |

#### Headers

| Name          | Type   | Description                                                                                                          |
| ------------- | ------ | -------------------------------------------------------------------------------------------------------------------- |
| Cookie        | string | ID-token set as `dev-imidToken` cookie. In client web applications, this is done by setting `credentials: 'include'` |
| Authorization | string | `Bearer ${ID token}`                                                                                                 |

#### Request Body

| Name                                          | Type   | Description                                                                           |
| --------------------------------------------- | ------ | ------------------------------------------------------------------------------------- |
| scope<mark style="color:red;">\*</mark>       | string | Used to define requested scopes. Separate multiple scopes with spaces (" ")           |
| grant\_type<mark style="color:red;">\*</mark> | string | Must be set to `urn:ietf:params:oauth:grant-type:token-exchange` if scope is supplied |

{% tabs %}
{% tab title="200 " %}

```
{ 
  "access_token" : "eyJhbGciOiJIUzI1NiIsInR…", 
  "token_type": "Bearer", 
  "expires_in": 600 
}
```

{% endtab %}
{% endtabs %}

{% hint style="warning" %}
Groups are only included in the access token if they have a "group to role"-mapping setup in Naviga ID Login.&#x20;
{% endhint %}

See [below](#fetching-access-tokens-as-application-configured-using-scopes) for an example on how to use scopes.

### Fetch access-token as application (using client credentials)

If you haven't yet created an application in Naviga ID, se the [Managing Applications](/navigaid/client-credentials/managing-applications.md#creating-an-application) page and follow the instructions there.

## As an application, using client credentials

<mark style="color:green;">`POST`</mark> `https://access-token.stage.imid.infomaker.io/v1/token`

Both JSON and form data are supported payload formats.

#### Request Body

| Name                                             | Type   | Description                                                                 |
| ------------------------------------------------ | ------ | --------------------------------------------------------------------------- |
| client\_secret<mark style="color:red;">\*</mark> | string |                                                                             |
| client\_id<mark style="color:red;">\*</mark>     | string |                                                                             |
| grant\_type<mark style="color:red;">\*</mark>    | string | should be `client_credentials`                                              |
| scope                                            | string | Used to define requested scopes. Separate multiple scopes with spaces (" ") |

{% tabs %}
{% tab title="200 " %}

```
{
  "access_token" : "eyJhbGciOiJIUzI1NiIsInR…", 
  "token_type": "Bearer",
  "expires_in": 600
}
```

{% endtab %}

{% tab title="400: Bad Request " %}

```javascript
{
    // Response
}
```

{% endtab %}

{% tab title="404: Not Found " %}

```javascript
{
    // Response
}
```

{% endtab %}

{% tab title="401: Unauthorized " %}

```javascript
{
    // Response
}
```

{% endtab %}

{% tab title="403: Forbidden " %}

```javascript
{
    // Response
}
```

{% endtab %}
{% endtabs %}

#### Fetching access-tokens as application configured using scopes

To use scopes, the application must have been configured with allowedScopes when created (and not using groups).  If that is not the case, you can either modify the application by removing the groups and add allowedScopes, or simply create a new application.

When fetching a token, in the `scope` field, specify the scopes that you wish to include in the token. If you specify more inclusive scopes than what is definied in the allowedScopes for your application, the req will fail. If you specify invalid scopes, such as with unit, service, role or pemission that does not exists in Naviga ID, the req will fail.

All scopes have the following format

`["permission"|"role"]:[unitName|"*"]:[serviceName]:[entityName]`

Below is a list of examples of scopes

| Scope                                 | Description                                                                                                |
| ------------------------------------- | ---------------------------------------------------------------------------------------------------------- |
| `permission:gl-news:opencontent:view` | If allowed, the token will get the `opencontent:view` permission only in the gl-news unit                  |
| `permission:*:opencontent:view`       | If allowed, the token will get the `opencontent:view` permission in **all units** in the org               |
| `role:gl-news:opencontent:readOnly`   | If allowed, the token will get all permissions in the `opencontet:readOnly` role only in the gl-news unit. |
| `role:*:opencontent:readOnly`         | If allowed, the token will get all permissions in the `opencontet:readOnly` role in all units in the org   |

#### Fetching access-token as application configured using groups

{% hint style="warning" %}
Note that group-based applications are our legacy way of configuring authorization. It is still supported, by we highly recommend to transition to scope-based applications.
{% endhint %}

CURL example. Start by storing `client_id` and `client_secret` in environment variable `CLIENT_ID` and `CLIENT_SECRET` respectively.&#x20;

```
curl --data "grant_type=client_credentials&client_id=$CLIENT_ID&client_secret=$CLIENT_SECRET" https://access-token.stage.imid.infomaker.io/v1/token
```

CURL example that stores token in environment variable `NAVIGA_ACCESS_TOKEN`.

```
export NAVIGA_ACCESS_TOKEN=$(curl --silent --data "grant_type=client_credentials&client_id=$CLIENT_ID&client_secret=$CLIENT_SECRET" https://access-token.stage.imid.infomaker.io/v1/token | jq -r '.access_token')
```

## Filtering access token permissions using scopes

### permission-filter-include-org

Includes all requested permissions in the org array. Only one instance of the scope should exist.

### permission-filter-include-unit:{unitName}

Includes all requested permissions in the specified unit array. Multiple instances of the scope can exist as long as the unit name is unique.

*Error if unitName does not exist or if sub does not have access to that unit*

### **Examples**

````
## Original permissions
```
{
    permissions: {
        org: [
            perm-1
            perm-2
        ],
        units: {
            barometern: [
                perm-3
            ],
            smp: [
                perm-4
            ]
        }
    }
}
```
## permission-filter-include-org permission-filter-include-unit:smp
```
{
    permissions: {
        org: [
            perm-1
            perm-2
        ],
        units: {
            smp: [
                perm-4
            ]
        }
    }
}
```
## permission-filter-include-org
```
{
    permissions: {
        org: [
            perm-1
            perm-2
        ],
        units: {}
    }
}
```
## permission-filter-include-unit:smp
```
{
    permissions: {
        org: [],
        units: {
            smp: [
                perm-4
            ]
        }
    }
}
```
````

## Authenticate using an Access Token

{% hint style="danger" %}
Only send Access Tokens over **HTTPS**
{% endhint %}

Simply include the Access Token in the Authorization header whenever you perform a request to a Naviga ID enabled service API, such as CCA and OC.

```
Authorization : "Bearer $NAVIGA_ACCESS_TOKEN"
```

{% hint style="info" %}
Do not include the ID-token cookie when executing requests to APIs. If the service is using an IMSG, there's a chance of a "Too many tokens"-error.
{% endhint %}

CURL example. Environment variable `NAVIGA_ACCESS_TOKEN` and `NAVIGA_ORG` needs to be set.

```
curl -H "Authorization: Bearer $NAVIGA_ACCESS_TOKEN" https://demo.stage.imid.infomaker.io/v1/org/$NAVIGA_ORG/test

```
