# Authentication

To embed a Story, Tile, or Dashboard Builder within your environment, you’ll need to authenticate each embed. Our authentication system is designed to be both secure and flexible. Without duplicating your user database in Toucan, you can pass a user context that dynamically segments data.

## Overview

<figure><img src="https://1809014303-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FZxYYf1KpgarKMgMsDCrw%2Fuploads%2Fgit-blob-74809cc0b8ca4e332d4b7f3daac438f37530e3a1%2FToucan%20Authentication%20Flow%20with%20One-Time%20Setup%20and%20Usual%20Flow.png?alt=media" alt=""><figcaption></figcaption></figure>

## Embed Manager

**Embed Manager Interface**\
The admin interface allows you to manage embeds and set up authentication.\
Path: `Admin Area > Embed Manager > Embed Settings`

<figure><img src="https://1809014303-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FZxYYf1KpgarKMgMsDCrw%2Fuploads%2Fgit-blob-2a28f4193f9ffcf2c4976e7527442d7c624c4aca%2FScreenshot%202024-09-16%20at%2017.20.39.png?alt=media" alt=""><figcaption><p>Access Embed Manager from Admin Area</p></figcaption></figure>

<figure><img src="https://1809014303-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FZxYYf1KpgarKMgMsDCrw%2Fuploads%2Fgit-blob-498db5c16bc24fdf0324d95eb1163d4e58c36779%2FCapture%20d%E2%80%99e%CC%81cran%202023-10-11%20a%CC%80%2011.44.30.png?alt=media" alt=""><figcaption><p>Embed Settings</p></figcaption></figure>

## Generate your client secret

Generate a client secret by clicking "Re-generate secret" in the Embed Manager.

{% hint style="warning" %}
Once generated, copy and store it securely, as it will disappear upon refreshing the page. Each new secret invalidates any previously issued tokens.
{% endhint %}

<figure><img src="https://1809014303-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FZxYYf1KpgarKMgMsDCrw%2Fuploads%2Fgit-blob-cc602bc3f03dbaa918e57d2e69e467a610fce6c9%2Fregenerate-secret.png?alt=media" alt=""><figcaption></figcaption></figure>

## Cryptographic keys

You have two methods to manage authentication tokens securely:

1. **RSA Key Pair Management:**\
   Generate and manage a single RSA key pair to sign JWT tokens.\
   Recommended key strength: at least 2048 bits (in this example, we use 4096 bits).

   ```bash
   # Generate a private key
   openssl genrsa -out "toucan_priv.pem" 4096

   # Generate a public key
   openssl rsa -in "toucan_priv.pem" -pubout -out "toucan_pub.pem"
   ```

   Once generated, upload the public key to your Toucan admin area.
2. **Using a JWKS Endpoint:**\
   For environments that support a JWKS endpoint (more information on [JWKS](https://auth0.com/docs/secure/tokens/json-web-tokens/json-web-key-sets)), this option allows you to rotate keys for enhanced security.

<figure><img src="https://1809014303-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FZxYYf1KpgarKMgMsDCrw%2Fuploads%2Fgit-blob-fd539e37ee4e4a514912132aee7bcb5db7b4e6c5%2FCapture%20d%E2%80%99e%CC%81cran%202023-10-11%20a%CC%80%2016.35.17.png?alt=media" alt=""><figcaption><p>JWKS method</p></figcaption></figure>

## Create JWT tokens with user context

To authenticate your embeds, create a JWT token signed with your private key. This JWT token does not pass through the user's browser; it links a user to their context through an opaque token sent to our authentication service.

**Code example in JS**

{% code overflow="wrap" lineNumbers="true" %}

```javascript
const fs = require('fs')
const jwt = require('jsonwebtoken')
​
​
const privateKey = fs.readFileSync('PATH_TO_YOUR_TOUCAN_EMBED_PRIVATE_RSA_KEY', 'utf8')
​
function signToken(payload) {
  try {
    return jwt.sign(payload, privateKey, { algorithm: 'RS512' });
  } catch (err) {
    throw err
  }
}
​
const token = signToken({
  sub: "toucan-embed-client",
  iss: "<YOUR-ISS>",
  aud: "https://OAUTH_SERVER_URL/TENANT_ID/oauth/oauth-token",
  exp: "<TIMESTAMP_IN_FUTURE>",
  jti: "<RANDOM_UNIQUE_ID>",
  embed_context: {
    "username": "YOUR_USER_EMAIL", // MANDATORY : user id
    "roles": ["USER"],  // MANDATORY
    "privileges": {  // MANDATORY : user access's right
      "APP-ID": ["PRIVILEGE"],
    },
    "groups": ["USER_GROUP"],  // user group
    "attributes": {  // everything else you want that can be used for custom permission, queries...
      "ENTITY_ID": "ENTITY_ID"
    },
    "secrets": { // Secrets will not be sent to the front or displayed, allowing data such as credentials or tokens used for authentication to be sent. 
      "TOKEN": "ACCESS_TOKEN_FOR_DATAWAREHOUSE"
    }
  }
})
```

{% endcode %}

{% hint style="info" %}
Other code examples lie in your **Embed Settings** interface.
{% endhint %}

**JWT Token's payload**

* **sub**: subject of the JWT. Shared in your Embed Interface settings.
* **iss**: issuer of the JWT. Shared in your Embed Interface settings.
* **aud**: recipient for which the JWT is intended. Shared in your Embed Interface settings.
* **exp**: time after which the JWT expires, in timestamp. Should follow your own authentication expiration policy.
* **jti:** unique identifier; can be used to prevent the JWT from being replayed. You have to generate a random string.
* **embed\_context**: object that represents the user and his context. Let's dive in.
  * **username**: it will represent your user. We recommend using the user's email but you could also use a unique identifier.
  * **roles**: USER or ADMIN. For your users, we recommend to let USER. For your SDK Key, for instance, ADMIN should be used. (cf. authenticate Embed SDK)
  * **privileges:** object that describes your user access's right to apps.
    * keys are Apps' IDs (cf. [find Apps' IDs](https://docs-v3.toucantoco.com/apps/managing-apps/creating-apps#find-app-id))
    * value is an enum on \["view", "validator", "contribute"] (more information in [user management](https://docs-v3.toucantoco.com/administration/managing-users/users#create-users) section)
  * **groups:** user groups defined in Toucan. Can be useful to define [visibility rules](https://docs-v3.toucantoco.com/administration/managing-users/setting-up-permissions-and-visibilities) based on user groups.
  * **attributes:** arbitrary variables that give additional context to the user. Most of the time, it includes information that allows data segregation on Live Data implementation.
  * **secrets**: variables used to send data to the Toucan tenant that will not be displayed. This section is used for variables that must remain secret, such as passwords or tokens.

{% hint style="warning" %}
**Warning**

As of today, we can't support a user context bigger than **3.5KB.** Toucan won't raise an error if it exceeds it, it will truncate it. If you encounter odd issues, please use the "**Check token**" in **Embed Settings** to ensure that your user's context is complete and not truncated.
{% endhint %}

## Generating the Opaque Token

To create an opaque token, use the JWT token crafted earlier. This token does not contain sensitive information but connects to the previously provided user context.

**Curl example**

```bash
curl --request POST -u "toucan-embed-client:CLIENT_SECRET"
  --url https://OAUTH_SERVER_URL/TENANT_ID/oauth/oauth-token \
  --header 'Content-Type: application/x-www-form-urlencoded' \
  --data grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer \
  --data scope=embed \
  --data assertion=JWT_TOKEN
```

**Parameters**

* **CLIENT\_SECRET:** string retrieve after uploading your public key
* **OAUTH\_SERVER\_URL:** URL of our own authentication service. Shared in the Embed Settings interface.
* **TENANT\_ID:** id of your tenant. Shared in the Embed Settings interface.
* **JWT\_TOKEN:** token that represents your user, crafted in the previous step.

{% hint style="success" %}
Once your opaque token is generated, pass it to the embed script in your application.
{% endhint %}

**Example**

**Static insertion**

{% code overflow="wrap" %}

```html
<script async src="https://myinstance.toucantoco.com/scripts/embedLauncher.js?id={EMBED_ID}&token=_0XBPWQQ_7613519f-a24b-4987-920d-218f7e6df591" type="text/javascript"></script>

```

{% endcode %}

**Programmatic insertion**

*(cf.* [*Embed SDK*](https://docs-v3.toucantoco.com/visualizations-and-layouts/embed-sdk#insertembedbyid) *and* [*Embed SDK Authentication*](https://docs-v3.toucantoco.com/visualizations-and-layouts/embedding/embed-sdk/embed-sdk-authentication)*)*

* **SDK\_AUTH\_TOKEN:** A token generated with admin rights to access all your embeds
* **EMBED\_ID: C**an be found in the Dashboards tab of your apps, or directly in the Embed Manager.

```javascript
const instance = await TcTcEmbed.initialize('SDK_AUTH_TOKEN');

await instance.insertEmbedById(
    'MY_EMBED_ID',
    document.getElementById('parent-container'),
    {
        token: '_0XBPWQQ_7613519f-a24b-4987-920d-218f7e6df591',
        ...
    }
);
```
