OIDC Setup
Connect NeMo Helix to an external OIDC identity provider (IdP) so users sign in with your organization’s identity and receive 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 below.
For a confidential client with Client Secret Basic, see Confidential OIDC Client. For login after setup, see Using Authentication. For the full config reference, see Auth Configuration.
How OIDC Fits in NeMo Helix
When OIDC is enabled:
- Platform configuration points to your IdP and defines independent public, confidential, and workload client profiles.
- 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). - Login: Users obtain tokens via device flow (browser) or password grant (CI) using the CLI, or authorization code flow in Studio.
- API calls: Clients send the configured bearer token in the
Authorization: Bearer <token>header. The default is the OAuth access token. NeMo Helix validates signed JWT bearers (signature, issuer, audience when configured, and expiry) and extracts the principal and configured groups for authorization.
OIDC provides the identity; workspace authorization comes from NeMo Helix role bindings. OAuth scope or scp values never become group principals or grant roles, but recognized NeMo Helix API scopes such as platform:read can narrow which APIs the bearer token can call.
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.
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.
Public client session handling
Public clients use direct identity-provider sessions by default. The CLI obtains and refreshes its provider tokens without routing them through NeMo Helix.
Set public_client.server_side_sessions: true when the public client should use
the NeMo Helix login broker instead. The client remains public and does not gain
a client secret; NeMo Helix completes Authorization Code + PKCE, stores the
provider refresh token in encrypted account credentials, and returns an opaque
refresh handle to the CLI.
The environment variable must come from a deployment secret, not from the platform ConfigMap. Studio does not use the login broker yet, so deployments that serve Studio must leave this option disabled.
Step-by-Step Configuration
Step 1: Register an OAuth Application
In your IdP (Azure AD, Okta, Keycloak, etc.):
- Create a new application registration
- Note the client ID
- Enable device flow (device authorization grant)
- Add the OIDC scopes your login flow needs, such as
openid,profile,email, andoffline_access - If you want OIDC login tokens to carry NeMo Helix API-scope restrictions, expose and consent the NeMo Helix API scopes your deployment requests, such as
platform:readandplatform:write
Step 2: Configure NeMo Helix
Set the OIDC settings in your platform config under auth.oidc:
By default, NeMo Helix extracts group principals from the JWT groups claim. If your IdP sends group or entitlement values such as employee, ml-team, or employee.profile.read in a different claim, set groups_claim to that claim name, then grant roles to those exact principal strings. Values inside the OAuth scope or scp claim are not group principals and do not grant workspace roles.
Selecting the API bearer
bearer_token_source controls which token from the current OIDC session is sent to NeMo Helix APIs:
access_token(default) preserves the standard OAuth resource-server flow and existing provider behavior.id_tokensupports providers that issue opaque access tokens but explicitly document their signed ID token as the browser application’s backend credential.
The setting applies to clients that select that profile. Studio uses the public
profile and reads the token from the current oidc-client-ts user on every
request, including after silent renewal; it does not retain a separate copy of
the initial ID token. The CLI fails authentication instead of falling back to
the access token when the selected profile requires an ID token but none is
present.
Do not use id_token solely to work around an opaque access token. Confirm the provider contract, configure audience, and verify that the ID token contains the identity and group claims used by your RBAC policy. The audience setting defaults to unset; when it is unset, NeMo Helix validates the token signature, issuer, and expiry but does not require a specific audience.
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 NHX_SEED_ON_STARTUP=true; if services are already running, run the seed task manually after services are healthy:
The seed task creates the HelixAdmin 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 Login Scopes (Optional)
Configure the OAuth scopes requested during CLI and Studio login:
These are the scopes requested from the IdP during login. Most deployments request OIDC protocol scopes such as openid, profile, email, and offline_access. A deployment can also request NeMo Helix API scope names, such as platform:read and platform:write, when those scopes are exposed by the IdP application. If your IdP application does not expose NeMo Helix API scopes, omit them; RBAC still applies.
Keep short NeMo Helix scope names in default_scopes. When auth discovery includes a resource scope prefix, the CLI shows both forms. For example, the login prompt might display platform:read (api://<app-client-id>/platform:read): platform:read is the NeMo Helix scope name, and the parenthesized value is the OAuth scope sent to the IdP. Users should pass the short NeMo Helix scope names to the CLI; the CLI applies the discovered prefix automatically.
Step 5: Verify
After deploying the configuration:
OIDC Configuration Reference
Breaking configuration migration
The client-profile model is a breaking change. Update server configuration and bundled clients together. Removed flat fields fail validation; Helix does not translate them at runtime.
Auth discovery now exposes interactive clients only through structured
oidc.clients entries. Removed top-level client IDs, endpoints, scopes,
device-flow options, and token_authorization_url are not projected.
Minimum IdP Checklist
Regardless of IdP, ensure:
- You have registered an OAuth application and have the client ID (and client secret if required).
- The application supports the device authorization grant (for
nemo auth login). - The selected bearer token includes claims for email, subject, and groups (or you have configured
email_claim,subject_claim,groups_claimto match your IdP’s claim names). - Any group or entitlement values that should grant NeMo roles are present in the configured
groups_claim. - If an interactive profile’s
default_scopesincludes NeMo Helix API scopes, those scopes are exposed by the IdP application and consented according to the provider’s model.
For providers that issue opaque access tokens but signed ID tokens, set bearer_token_source: id_token only when
the NeMo Helix deployment is intentionally configured to validate that ID token’s issuer, signature, and audience.
When device_authorization_requires_device_id is enabled, the CLI stores a random installation identifier at
$XDG_STATE_HOME/nhx/oidc-device-id (or ~/.local/state/nhx/oidc-device-id) with mode 0600. It reuses that value
for later logins. If device_authorization_display_name is unset, the CLI sends NeMo Helix CLI.
Set device_token_request_includes_scope: false when the provider accepts scopes only on the initial device
authorization request. The default remains enabled for providers that require the scope again while polling.
Claim mapping
NeMo Helix maps JWT claims to trusted identity headers using email_claim, subject_claim, and groups_claim (defaults: email, sub, groups). Override them when your IdP uses different claim names. Group values must match the principal strings you use for workspace members and role bindings.
For ordinary OIDC bearer validation, group values come from the configured groups_claim. They are included in the X-NHX-Principal-Groups header and OPA policy data, where they can match explicit workspace member or role-binding principals. Group names may contain dots, for example employee.profile.read. OAuth scopes from scope or scp do not become group principals; recognized NeMo Helix API scopes in those claims can still restrict API access. See Managing Access.
Provider-Specific Notes
- Azure AD: See Azure AD Setup (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 for a provider-agnostic checklist.
Related
- Using Authentication — Log in, make API calls, and manage tokens.
- Auth Configuration — Full auth config reference.