> ## Documentation Index
> Fetch the complete documentation index at: https://docs.getnao.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Authentication

> Single sign-on for nao Enterprise - Microsoft Entra ID today, Okta on the roadmap

nao Enterprise supports single sign-on (SSO) so your users sign in to nao with the same identity provider they already use for the rest of your stack. SSO is gated by the `sso` feature flag on your Enterprise license - install the license first (see [Overview](/nao-agent/enterprise/overview#installing-the-license)).

## Microsoft SSO (Azure AD / Entra ID)

Microsoft SSO is implemented via OAuth against Azure AD (Entra ID). When configured, the nao login page exposes a **Sign in with Microsoft** button, and new users are auto-provisioned the first time they sign in (subject to your auto-create policy).

### Step 1: Register an application in Azure

1. Open the [Azure portal](https://portal.azure.com/) -> **Microsoft Entra ID** -> **App registrations**.
2. Click **New registration**. Give it a name (e.g. `nao SSO`).
3. **Supported account types**: pick **Single tenant** unless you need cross-tenant access.
4. **Redirect URI**: type **Web**, value `https://<your-nao-deployment>/api/auth/callback/microsoft`.
5. Click **Register**.

Note the **Application (client) ID** and **Directory (tenant) ID** from the **Overview** page - you'll need both.

### Step 2: Create a client secret

1. In your new app, open **Certificates & secrets** -> **Client secrets** -> **New client secret**.
2. Pick an expiry that matches your rotation policy.
3. Copy the **Value** immediately - it is only shown once.

### Step 3: Configure API permissions

1. Open **API permissions** -> **Add a permission** -> **Microsoft Graph** -> **Delegated permissions**.
2. Add `openid`, `profile`, `email`, `offline_access`.
3. If you plan to use [Redshift RLS via Entra ID](/nao-agent/enterprise/permissions#redshift-row-level-security-via-entra-id), expose your Redshift API scope under **Expose an API**:
   * Set the **Application ID URI** to `api://<clientId>` (using the Application (client) ID from Step 1).
   * **Add a scope** - Azure pre-fills the name as `user_impersonation`. The name is arbitrary, but it must match the scope you configure in Step 4.
   * This exposed scope is the one nao requests at runtime - it is not just a permission. It determines the **audience** (`aud`) of the token nao sends to Redshift, which Redshift validates against its native IdP app integration.
4. If your tenant requires it, click **Grant admin consent**.

### Step 4: Configure nao

Set the following environment variables on your nao deployment and restart:

```bash theme={null}
AZURE_AD_CLIENT_ID=<application-client-id>
AZURE_AD_CLIENT_SECRET=<client-secret-value>
AZURE_AD_TENANT_ID=<directory-tenant-id>
```

When `AZURE_AD_CLIENT_ID`, `AZURE_AD_CLIENT_SECRET`, and `AZURE_AD_TENANT_ID` are set and the license has the `sso` feature active, the **Sign in with Microsoft** button appears on the login page.

Optionally, set `AZURE_AD_TOKEN_SCOPE` to control the scope nao uses to silently acquire downstream access tokens:

```bash theme={null}
AZURE_AD_TOKEN_SCOPE=api://<clientId>/user_impersonation
```

* **Leave it unset for SSO-only deployments.** It defaults to `<clientId>/.default`, which is fine when nao does not need to call a downstream resource.
* **For Redshift native IdP federation, set it to the exposed API scope** whose audience Redshift expects - for example `AZURE_AD_TOKEN_SCOPE=api://<clientId>/user_impersonation`, matching the scope you exposed in Step 3.
* The resulting token's `aud` claim must match the audience configured in the Redshift native IdP app integration. If they differ, Redshift rejects the token.

### Step 5: Verify

1. Open your nao deployment's login page in a private window.
2. Click **Sign in with Microsoft** and complete the Microsoft prompt.
3. You should land in nao with a user account provisioned from your Microsoft identity (email + display name).
4. As an admin, open **Settings -> Team** to confirm the user appears with the role you expected.

<Info>
  The Microsoft refresh token issued at sign-in is stored encrypted by nao and reused to silently obtain access tokens for downstream services like Redshift. Users do not have to re-authenticate when they query the warehouse.
</Info>

### Mapping Microsoft groups to nao roles

Group-to-role mapping is not yet exposed in the UI. Today, nao auto-provisions new SSO users with the **Member** role. Promote users to **Admin** or demote them to **Viewer** from **Settings -> Team**. For automated mapping, contact us - the rules go through the license payload.

## Generic OIDC (Okta, Auth0, Keycloak, OneLogin, ...)

For identity providers other than Microsoft, nao supports single sign-on via any OIDC-compliant provider. One integration covers Okta, Auth0, Keycloak, OneLogin, and any provider that exposes a standard `.well-known/openid-configuration` discovery document. When configured, the login page shows a **Continue with `{provider name}`** button (the label comes from `OIDC_PROVIDER_NAME`, default `SSO`), and new users are auto-provisioned on first sign-in (subject to your auto-create policy).

### Step 1: Register an application in your provider

Create an OIDC / OAuth 2.0 application in your identity provider and note the **client ID** and **client secret**. Register the following redirect URI, replacing `{OIDC_PROVIDER_ID}` with the value you set in Step 2 (defaults to `oidc`):

```
https://<your-nao-host>/api/auth/oauth2/callback/{OIDC_PROVIDER_ID}
```

### Step 2: Configure nao

Set the following environment variables on your nao deployment and restart:

```bash theme={null}
OIDC_DISCOVERY_URL=https://<your-provider>/.well-known/openid-configuration   # required
OIDC_CLIENT_ID=<client-id>                                                    # required
OIDC_CLIENT_SECRET=<client-secret>                                            # required
OIDC_PROVIDER_ID=oidc            # optional, used in the callback URL (defaults to "oidc")
OIDC_PROVIDER_NAME=SSO           # optional, shown on the login button (defaults to "SSO")
OIDC_SCOPES=openid,profile,email # optional, comma-separated (defaults shown)
OIDC_AUTH_DOMAINS=example.com    # optional, comma-separated email-domain allowlist
OIDC_PKCE=true                   # optional, defaults to true
```

When `OIDC_DISCOVERY_URL`, `OIDC_CLIENT_ID`, and `OIDC_CLIENT_SECRET` are set, the SSO button appears on the login page. When they are unset, the button is hidden. Set `OIDC_AUTH_DOMAINS` to restrict sign-up to specific email domains.

### Step 3: Verify

1. Open your nao deployment's login page in a private window.
2. Click **Continue with `{provider name}`** and complete your provider's prompt.
3. You should land in nao with an account provisioned from your OIDC identity (email + display name).
4. As an admin, open **Settings -> Team** to confirm the user appears with the role you expected.

## Okta via SAML

The generic OIDC integration above covers Okta's OIDC apps. If your team needs Okta over SAML specifically, email [claire@getnao.io](mailto:claire@getnao.io) - we can scope a custom rollout.

## Removing SSO

To disable SSO temporarily, unset `AZURE_AD_CLIENT_ID` (or remove the license). The login page falls back to email + password authentication. Existing SSO users retain their accounts and can be migrated to email + password from **Settings -> Team**.
