# OIDC Federation Setup Guide (SSO)

This document describes the requirements for setting up Single Sign-On (SSO) via OpenID Connect (OIDC) between your Identity Provider (IdP) and the Adhese platform.

---

## 1. Overview

We use OIDC-based identity federation to allow your users to log in to the Adhese platform using your organisation's Identity Provider (IdP). Our platform acts as the Service Provider (SP)/Relying Party (RP), while your IdP handles user authentication.

---

## 2. Information We Need From You

To configure the connection on our side, we need the following from your IdP:

<table id="bkmrk-item-description-dis"><thead><tr><th>Item</th><th>Description</th></tr></thead><tbody><tr><td>**Discovery URL**</td><td>Your OIDC discovery endpoint, typically `https://<your-idp>/.well-known/openid-configuration`. If not available, provide the individual endpoints below.</td></tr><tr><td>**Authorization endpoint**</td><td>URL where we redirect users to authenticate</td></tr><tr><td>**Token endpoint**</td><td>URL where we exchange the authorisation code for tokens</td></tr><tr><td>**UserInfo endpoint**</td><td>URL where we can retrieve additional user claims (if not all included in the ID token)</td></tr><tr><td>**JWKS URI**</td><td>URL to your public signing keys for token validation</td></tr><tr><td>**Client ID**</td><td>The client identifier registered for Adhese in your IdP</td></tr><tr><td>**Client Secret**</td><td>The client secret associated with the Client ID</td></tr><tr><td>**Supported scopes**</td><td>Confirmation that the required scopes (see section 4) are available</td></tr></tbody></table>

> If your IdP supports a discovery endpoint, most of the above can be derived automatically. In that case, providing the discovery URL, Client ID, and Client Secret is sufficient.

---

## 3. Information We Provide To You

You will need the following from us to configure your IdP:

<table id="bkmrk-item-description-red"><thead><tr><th>Item</th><th>Description</th></tr></thead><tbody><tr><td>**Redirect URI (Callback URL)**</td><td>We will provide the exact redirect URI that must be registered as an allowed callback in your IdP.</td></tr><tr><td>**Required scopes**</td><td>See section 4</td></tr><tr><td>**Required claims**</td><td>See section 4</td></tr></tbody></table>

---

## 4. Required Scopes and Claims

### Required Scopes

<table id="bkmrk-scope-purpose-openid"><thead><tr><th>Scope</th><th>Purpose</th></tr></thead><tbody><tr><td>`openid`</td><td>Mandatory for OIDC. Returns the `sub` (subject) claim.</td></tr><tr><td>`email`</td><td>Required. Must return the `email` and `email_verified` claims.</td></tr></tbody></table>

### Required Claims

<table id="bkmrk-claim-scope-required" style="width: 100%;"><thead><tr><th style="width: 14.0644%;">Claim</th><th style="width: 10.2441%;">Scope</th><th style="width: 11.0909%;">Required</th><th style="width: 17.9976%;">Expected Value</th><th style="width: 46.6031%;">Description</th></tr></thead><tbody><tr><td style="width: 14.0644%;">`sub`</td><td style="width: 10.2441%;">`openid`</td><td style="width: 11.0909%;">Yes</td><td style="width: 17.9976%;">Unique user ID</td><td style="width: 46.6031%;">Unique identifier for the user</td></tr><tr><td style="width: 14.0644%;">`email`</td><td style="width: 10.2441%;">`email`</td><td style="width: 11.0909%;">Yes</td><td style="width: 17.9976%;">Valid email address</td><td style="width: 46.6031%;">The user's email address</td></tr><tr><td style="width: 14.0644%;">`email_verified`</td><td style="width: 10.2441%;">`email`</td><td style="width: 11.0909%;">Yes</td><td style="width: 17.9976%;">`true`</td><td style="width: 46.6031%;">Must be `true`. Users with `email_verified: false` or a missing `email_verified` claim will be denied access.</td></tr></tbody></table>

> **Important:** The `email_verified` claim is an optional claim per the OIDC specification, meaning IdPs are not required to include it by default. Please verify that your IdP is configured to include this claim in the ID token when the `email` scope is requested. Additionally, the value must be `true` — users whose email address has not been verified at the IdP level will not be able to log in.

### Optional Scopes and Claims

The `profile` scope is not required but recommended. It enables us to display user-friendly names in the Adhese UI.

<table id="bkmrk-claim-scope-required-1"><thead><tr><th>Claim</th><th>Scope</th><th>Required</th><th>Description</th></tr></thead><tbody><tr><td>`name`</td><td>`profile`</td><td>No</td><td>Full display name</td></tr><tr><td>`given_name`</td><td>`profile`</td><td>No</td><td>First name</td></tr><tr><td>`family_name`</td><td>`profile`</td><td>No</td><td>Last name</td></tr><tr><td>`preferred_username`</td><td>`profile`</td><td>No</td><td>Username</td></tr></tbody></table>

---

## 5. Role Mapping (Optional)

User roles can be managed directly within the Adhese platform. However, if you prefer to manage roles centrally from your IdP, we support automatic role assignment based on a custom claim in the ID token.

### How It Works

- You choose the claim name (e.g., `adhese_role`) — let us know which name you use so we can configure the mapping on our side.
- The claim value can be a single role (string) or multiple roles (array).
- Roles are mapped automatically on each login, so changes in your IdP are reflected immediately.

**Single role example:**

```json
{
  "adhese_role": "admin"
}

```

**Multiple roles example:**

```json
{
  "adhese_role": ["viewer", "creative_approver"]
}

```

### Available Roles — Classic UI

<table id="bkmrk-role-description-cla"><thead><tr><th>Role</th><th>Description</th></tr></thead><tbody><tr><td>`classic_admin`</td><td>Full admin. Has full permissions in the Classic UI.</td></tr><tr><td>`classic_read_only`</td><td>Read-only access to the Classic UI.</td></tr></tbody></table>

### Available Roles — New UI

<table id="bkmrk-role-description-adm"><thead><tr><th>Role</th><th>Description</th></tr></thead><tbody><tr><td>`admin`</td><td>Full administrator</td></tr><tr><td>`creative_approver`</td><td>Can approve creatives</td></tr><tr><td>`creative_master`</td><td>Full creative management</td></tr><tr><td>`managed_ad_master`</td><td>Managed advertising management</td></tr><tr><td>`self_service_ad_master`</td><td>Self-service advertising management</td></tr><tr><td>`viewer`</td><td>Read-only access</td></tr><tr><td>`access_all_advertisers_debtors_brands`</td><td>Access across all advertisers, debtors, and brands</td></tr></tbody></table>

> If you do not configure role mapping, roles will be managed manually within the Adhese platform by an administrator.

---

## 6. Setup Checklist

### Your side (IdP)

- [ ] Register a new OIDC client/application for Adhese
- [ ] Configure the redirect URI provided by us as an allowed callback URL
- [ ] Ensure the `openid` and `email` scopes are enabled
- [ ] Verify that the `email_verified` claim is included in the ID token with a value of `true`
- [ ] (Optional) Enable the `profile` scope
- [ ] (Optional) Configure a custom claim for role mapping
- [ ] Share the Client ID, Client Secret, and discovery URL (or individual endpoints) with us

### Our side (Adhese)

- [ ] Provide the redirect URI
- [ ] Configure the IdP connection with the provided endpoints and credentials
- [ ] Configure scope requests (`openid`, `email`, and optionally `profile`)
- [ ] Configure essential claim validation for `email_verified`
- [ ] (Optional) Configure role mapping based on the agreed custom claim
- [ ] Perform a test login together

---

## 7. Testing

Once both sides are configured, we recommend performing a joint test:

1. Initiate a login on the Adhese platform
2. Verify that the redirect to your IdP works correctly
3. Authenticate with a test user
4. Verify that the callback to Adhese succeeds
5. Confirm that the user's email and profile information are correctly displayed
6. (If applicable) Confirm that role mapping is applied correctly

If the login fails with an error related to the essential claim, the most common causes are:

- The `email` scope is not enabled on the IdP
- The `email_verified` claim is not included in the ID token
- The user's email is not verified at the IdP level (`email_verified: false`)