> This page is for version 0.5.0.
> For other versions, use one of these documentation indexes:
> - Latest (default): https://docs.nvidia.com/nemo-helix/latest/llms.txt
> - 0.8.0: https://docs.nvidia.com/nemo-helix/v0.8.0/llms.txt
> - 0.7.1: https://docs.nvidia.com/nemo-helix/v0.7.1/llms.txt
> - 0.7.0: https://docs.nvidia.com/nemo-helix/v0.7.0/llms.txt
> - 0.6.0: https://docs.nvidia.com/nemo-helix/v0.6.0/llms.txt
> - 0.5.1: https://docs.nvidia.com/nemo-helix/v0.5.1/llms.txt
> - 0.5.0: https://docs.nvidia.com/nemo-helix/v0.5.0/llms.txt
> - 0.4.0: https://docs.nvidia.com/nemo-helix/v0.4.0/llms.txt
> - 0.3.0: https://docs.nvidia.com/nemo-helix/v0.3.0/llms.txt
> - 0.2.0: https://docs.nvidia.com/nemo-helix/v0.2.0/llms.txt

> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.nvidia.com/nemo-helix/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.nvidia.com/nemo-helix/_mcp/server.

# OIDC Setup

Connect NeMo Helix to an external OIDC identity provider (IdP) so users sign in with your organization's identity and receive OAuth2 access tokens for API access.

**Prerequisites**: You need an OAuth application registered in your IdP with the client ID, issuer URL, and device flow grant enabled. See the [Minimum IdP Checklist](#minimum-idp-checklist) below.

For login after setup, see [Using Authentication](/documentation/access-control/authentication/using-authentication). For the full config reference, see [Auth Configuration](/documentation/access-control/deployment).

## How OIDC Fits in NeMo Helix

When OIDC is enabled:

1. **Platform configuration** points to your IdP (issuer URL, client ID, optional scope prefix and claim names).
2. **Discovery**: Clients and the platform discover token and device-auth endpoints from the IdP's `.well-known/openid-configuration` (or from NeMo Helix's aggregated discovery at `{BASE_URL}/apis/auth/discovery`).
3. **Login**: Users obtain access tokens via **device flow** (browser) or **password grant** (CI) using the CLI.
4. **API calls**: Requests send the access token in the `Authorization: Bearer <token>` header. NeMo Helix validates the JWT (signature, issuer, audience, expiry) and extracts the principal and scopes for authorization.

OIDC provides the identity; authorization (workspace roles, scopes) works the same as with any other auth method.

## Flows Supported

* **Device authorization flow**: User runs `nemo auth login`; the CLI shows a code and opens the IdP page; after the user signs in and consents, the CLI receives an access token (and optionally a refresh token). Best for interactive use.
* **Resource owner password grant**: For non-interactive environments (CI), `nemo auth login --username <user> --password <pass>` exchanges credentials for a token. Your IdP must support this grant type.

> **Warning**
>
> Password grant sends user credentials directly to the IdP. It bypasses MFA and is disabled by many production IdPs. Use it only for CI/testing. Prefer device flow for interactive users.

## Step-by-Step Configuration

### Step 1: Register an OAuth Application

In your IdP (Azure AD, Okta, Keycloak, etc.):

1. Create a new application registration
2. Note the **client ID**
3. Enable **device flow** (device authorization grant)
4. *(Optional)* Create custom API scopes (`platform:read`, `platform:write`) if you want token-level scope restrictions. See [API Scopes](/documentation/access-control/authorization/api-scopes).
5. If you created custom scopes, grant admin consent for them (if required by your IdP)

### Step 2: Configure NeMo Helix

Set the OIDC settings in your platform config under `auth.oidc`:

```yaml
auth:
 enabled: true
 admin_email: "platform-admin@company.com"
 oidc:
 enabled: true
 issuer: "https://your-idp.example.com/realm"
 client_id: "your-client-id"
 # Optional: strip IdP scope prefix (e.g., Azure AD prepends API URI)
 # scope_prefix: "api://your-client-id/"
 # Optional: override claim names if your IdP uses non-standard names
 # email_claim: "upn"
 # subject_claim: "oid"
 # groups_claim: "groups"
```

### Step 3: Seed Auth Role Bindings

The `auth.admin_email` setting identifies the bootstrap admin, but the role binding is created by the platform seed task. Docker quickstart runs platform seed automatically, and Helm deployments run the platform-seed Job by default. For source installs, start services with `platform.seed_on_startup: true` or `NMP_SEED_ON_STARTUP=true`; if services are already running, run the seed task manually after services are healthy:

```bash
# Set NMP_BASE_URL first if services are not on http://localhost:8080.
curl -sf http://localhost:8080/health/ready
uv run python -m nmp.platform_seed
```

The seed task creates the **PlatformAdmin** binding for `auth.admin_email`, the wildcard **Editor** binding for the `default` workspace, the wildcard **Viewer** binding for the `system` workspace, and the wildcard **WorkspaceCreator** binding for `system` that preserves open workspace creation by default. Without this step, OIDC login can succeed while admin operations, workspace creation, and access to the default and system workspaces can still return `403 Forbidden`.

### Step 4: Configure Scopes (Optional)

This step is only needed if you created custom API scopes in Step 1. If you skip scopes, NeMo Helix still enforces RBAC — scopes add an additional token-level restriction on top. See [API Scopes](/documentation/access-control/authorization/api-scopes).

If you are using scopes, configure the default scopes requested during login:

```yaml
auth:
 oidc:
 default_scopes: "openid profile email offline_access platform:read platform:write"
```

If your IdP prefixes scopes (e.g., Azure AD uses `api://client-id/platform:read`), set `scope_prefix` so NeMo Helix strips it before authorization:

```yaml
auth:
 oidc:
 scope_prefix: "api://your-client-id/"
```

### Step 5: Verify

After deploying the configuration:

```bash
# Log in via device flow
nemo auth login

# Check login status
nemo auth status
# Expected: shows principal email, scopes, token expiry

# Verify API access
nemo workspaces list
```

## OIDC Configuration Reference

| Field                           | Type   | Description                                                               |
| ------------------------------- | ------ | ------------------------------------------------------------------------- |
| `enabled`                       | bool   | Enable OIDC token validation.                                             |
| `issuer`                        | string | IdP issuer URL (e.g., `https://login.microsoftonline.com/<tenant>/v2.0`). |
| `client_id`                     | string | OAuth client ID for NeMo Helix.                                           |
| `additional_issuers`            | list   | Extra issuer URLs to accept (e.g., Azure AD v1 format).                   |
| `audience`                      | string | Expected token audience (defaults to `client_id`).                        |
| `email_claim`                   | string | JWT claim for email (default: `email`).                                   |
| `subject_claim`                 | string | JWT claim for subject (default: `sub`).                                   |
| `groups_claim`                  | string | JWT claim for groups (default: `groups`).                                 |
| `default_scopes`                | string | Space-separated scopes requested when user does not pass `--scope`.       |
| `scope_prefix`                  | string | Prefix stripped from token scopes before authorization.                   |
| `token_endpoint`                | string | Override token endpoint (otherwise discovered from IdP).                  |
| `device_authorization_endpoint` | string | Override device auth endpoint.                                            |
| `jwks_uri`                      | string | Override JWKS URI.                                                        |

## Minimum IdP Checklist

Regardless of IdP, ensure:

1. You have registered an OAuth application and have the **client ID** (and client secret if required).
2. The application supports the **device authorization grant** (for `nemo auth login`).
3. The access token includes claims for email, subject, and groups (or you have configured `email_claim`, `subject_claim`, `groups_claim` to match your IdP's claim names).
4. *(If using scopes)* Custom API scopes (`platform:read`, `platform:write`) are exposed, included in access tokens, and admin consent is granted if required.

## Claim mapping

NeMo Helix maps JWT claims to [trusted identity headers](/documentation/access-control/security-model#trusted-identity-headers) using `email_claim`, `subject_claim`, and `groups_claim` (defaults: `email`, `sub`, `groups`). Override them when your IdP uses different claim names — values must match what you use for workspace members and authorization.

| Purpose                | Config key      | Default  | Header                   |
| ---------------------- | --------------- | -------- | ------------------------ |
| Subject (Principal ID) | `subject_claim` | `sub`    | `X-NMP-Principal-Id`     |
| Email                  | `email_claim`   | `email`  | `X-NMP-Principal-Email`  |
| Groups                 | `groups_claim`  | `groups` | `X-NMP-Principal-Groups` |

> **Note**
>
> Group values are extracted from the JWT and included in the `X-NMP-Principal-Groups` header and OPA policy data, but **automatic group-to-role mapping is not yet implemented**. Role assignments must be made explicitly via the members API. See [Managing Access](/documentation/access-control/authorization/managing-access).

## Provider-Specific Notes

* **Azure AD**: See [Azure AD Setup](/documentation/access-control/authentication/providers/azure-ad-entra-id) (issuer, `additional_issuers`, device flow, claim overrides).
* **Okta**: Choose the correct authorization server (custom vs org). Ensure device flow is enabled.
* **Keycloak**: Configure realm, client, and role mappers. Enable device flow in client settings.
* **Other providers**: See [Generic OIDC Provider](/documentation/access-control/authentication/providers/generic-oidc) for a provider-agnostic checklist.

## Related

* [Using Authentication](/documentation/access-control/authentication/using-authentication) — Log in, make API calls, and manage tokens.
* [Auth Configuration](/documentation/access-control/deployment) — Full auth config reference.