> For clean Markdown of any page, append .md to the page URL. > For a complete documentation index, see https://docs.nvidia.com/nemo-helix/latest/documentation/access-control/deployment/llms.txt. > For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.nvidia.com/nemo-helix/_mcp/server. # Configuration Reference Complete reference for enabling and configuring platform authorization: the `auth` section in config, Helm values, environment variables, and the choice between embedded and external OPA. For quickstart setup, see [Authentication and Authorization](/documentation/access-control). For OIDC settings, see [OIDC Setup](/documentation/access-control/authentication/oidc-setup). ## Enabling Authorization Authorization is enabled in the platform config by setting `auth.enabled: true`. This can be done in the platform config file: ```yaml auth: enabled: true ``` When using Helm, this is done by setting `platformConfig.auth.enabled: true` in your Helm values; this becomes `auth.enabled` in the calculated platform config. ```yaml # values.yaml platformConfig: auth: enabled: true ``` When `auth.enabled` is `false` (the default), all API requests are allowed without checks. When `true`, every request is evaluated by the Policy Decision Point (PDP). In Helm deployments, this setting is controlled via `platformConfig.auth.enabled`. ### Bootstrap Admin When authorization is enabled, a platform administrator can be configured. Setting **`admin_email`** tells platform seed which identity should receive the **HelixAdmin** role. Use it to create the first workspaces and grant roles to other users. After bootstrap, manage access via workspaces and members as described in [Managing Access](/documentation/access-control/authorization/managing-access). ```yaml auth: enabled: true admin_email: "your-admin@company.com" ``` The binding is created by `platform-seed`, not by auth service startup alone. Helm deployments run the platform-seed Job by default. For source installs, set `platform.seed_on_startup: true`, export `NHX_SEED_ON_STARTUP=true` before `nemo services run`, or run `uv run python -m nhx.platform_seed` after services are healthy. If platform seed has not run, `admin_email` users can authenticate but still receive `403 Forbidden` because their HelixAdmin binding does not exist. Platform seed also creates the default wildcard workspace bindings: `Editor` on the default workspace, `Viewer` on `system`, and `WorkspaceCreator` on `system`. That last binding is what preserves open workspace creation by default. Remove or replace it if you want workspace creation restricted to designated users or groups. This page covers the auth-specific configuration fields you need to enable and operate authorization. Auth-related values are found under `platformConfig.auth` in the values file. For OIDC-specific fields (`auth.oidc`), see [OIDC Setup](/documentation/access-control/authentication/oidc-setup). ## Authorization Engine: Embedded vs External OPA The PDP can run in two modes. For technical details, see [Policy Engine](/documentation/access-control/authorization/policy-engine). ### Embedded (default) * **Provider**: `policy_decision_point_provider: "embedded"`. * The auth service runs a built-in WASM policy engine. No OPA sidecar is required. * Policy data (role bindings, scopes, etc.) is loaded from the entity store and refreshed on an interval (`policy_data_refresh_interval`). Use embedded for new deployments and when you do not already have an OPA fleet. ### External OPA * **Provider**: `policy_decision_point_provider: "opa"`. * An external OPA sidecar (or server) fetches policy bundles from the auth service and evaluates requests. * Set `policy_decision_point_base_url` to the OPA service URL (e.g., `http://opa:8181`). * `bundle_cache_seconds` controls how long OPA caches the bundle. Use external OPA when you already use OPA for other services or need a single policy engine at the edge. ## Environment Variables Configuration can be overridden with environment variables using the **`NHX_AUTH_`** prefix. Names are derived from the config keys in UPPER\_SNAKE\_CASE. Examples: ```bash NHX_AUTH_ENABLED=true NHX_AUTH_POLICY_DECISION_POINT_BASE_URL=http://auth:8000 NHX_AUTH_POLICY_DECISION_POINT_PROVIDER=embedded NHX_AUTH_ADMIN_EMAIL=admin@example.com NHX_AUTH_EMBEDDED_PDP_AUTO_BUILD_WASM=true NHX_AUTH_TOKEN_SIGNING__PRIVATE_KEY_FILE=/etc/nhx/workload-token/private-key.pem ``` Nested auth keys use a double underscore after `NHX_AUTH_`: for example, `NHX_AUTH_OIDC__ISSUER`, `NHX_AUTH_OIDC__PUBLIC_CLIENT__CLIENT_ID`, and `NHX_AUTH_ACCESS_KEYS__ENABLED`. ## Scoped Access Keys Scoped Access Keys let an authenticated user create a scoped bearer token for non-SDK clients and automation. The implementation creates user-scoped signed JWT access keys, persists their lifecycle metadata, and rejects service principals. Users can list and revoke their own keys. Rotation is not implemented. Scoped Access Keys are an auth-service feature exposed under the auth CLI namespace (`nemo auth access-keys ...`) and the `/apis/auth/v2/access-keys` API routes. They are not a standalone NeMo Helix plugin. Scoped Access Keys are disabled by default. Enable them only when the auth service has a shared RSA signing key: ```yaml auth: enabled: true token_signing: issuer: "https://nhx.company.com/apis/auth" key_id: "nemo-helix-signing" private_key_file: "/etc/nhx/workload-token/private-key.pem" access_keys: enabled: true issue_format: "jwt" accepted_formats: ["jwt"] audience: "nemo-helix-access-key" default_expires_in_seconds: 2592000 max_expires_in_seconds: 2592000 rotation_grace_period_seconds: 172800 ``` Equivalent environment overrides: ```bash NHX_AUTH_TOKEN_SIGNING__ISSUER=https://nhx.company.com/apis/auth NHX_AUTH_TOKEN_SIGNING__KEY_ID=nemo-helix-signing NHX_AUTH_TOKEN_SIGNING__PRIVATE_KEY_FILE=/etc/nhx/workload-token/private-key.pem NHX_AUTH_ACCESS_KEYS__ENABLED=true NHX_AUTH_ACCESS_KEYS__ISSUE_FORMAT=jwt NHX_AUTH_ACCESS_KEYS__ACCEPTED_FORMATS=jwt NHX_AUTH_ACCESS_KEYS__AUDIENCE=nemo-helix-access-key NHX_AUTH_ACCESS_KEYS__DEFAULT_EXPIRES_IN_SECONDS=2592000 NHX_AUTH_ACCESS_KEYS__MAX_EXPIRES_IN_SECONDS=2592000 NHX_AUTH_ACCESS_KEYS__ROTATION_GRACE_PERIOD_SECONDS=172800 ``` List-valued env vars for accepted Scoped Access Key formats are written as comma-separated values, for example `NHX_AUTH_ACCESS_KEYS__ACCEPTED_FORMATS=jwt`. Service-level `AuthorizationMiddleware` accepts Scoped Access Key bearer tokens directly when `auth.access_keys.enabled=true`. When `auth.access_keys.enabled=false`, the middleware does not try to authenticate Scoped Access Keys. Gateway deployments that use `/apis/auth/ext-authz` still keep `auth.access_keys.enabled=true` when they want Scoped Access Keys to work, because the same flag controls creation and auth-service validation. Scoped Access Keys expire after 30 days by default. Create requests may omit `expires_in_seconds`; the auth service then uses `auth.access_keys.default_expires_in_seconds`. Callers may request a shorter or longer finite lifetime with `expires_in_seconds` or CLI `--expires-in`, but the requested value must be less than or equal to `auth.access_keys.max_expires_in_seconds` when the max is configured. Set `auth.access_keys.max_expires_in_seconds` to `null` only when unlimited keys are permitted. With `max_expires_in_seconds: null` and a finite `default_expires_in_seconds`, ordinary omitted-expiry requests still use the default lifetime, while explicit `expires_in_seconds: null` or CLI `--expires-in none` creates a no-expiration key. Set both max and default to `null` only when omitted-expiry requests should also create no-expiration keys. With a finite `max_expires_in_seconds` and `default_expires_in_seconds: null`, callers must provide a finite `expires_in_seconds`. When `max_expires_in_seconds` is `null`, callers may still provide a finite `expires_in_seconds`, and the auth service honors that finite lifetime. `POST /apis/auth/v2/access-keys/{jti}/rotate` mints a successor key and puts the rotated-out key into a `ROTATING` state that still authenticates for `auth.access_keys.rotation_grace_period_seconds` (48 hours by default), so deployments can cut over configuration before the old key is finalized. Call `DELETE /apis/auth/v2/access-keys/{jti}` on the old key to finalize rotation immediately, or let it lapse automatically once the grace period elapses. The issuer defaults to `/apis/auth` when `auth.token_signing.issuer` is unset. Use an externally reachable issuer URL when a gateway validates Scoped Access Keys before forwarding requests to Helix services. ## OIDC Workload Identity Exchange `auth.oidc.workload` configures SDK workload identity token exchange. The profile's presence enables workload exchange. Workload tokens share `auth.token_signing` by default, while fields under `workload` provide workload-specific overrides: ```yaml auth: token_signing: issuer: "https://nhx.company.com/apis/auth" key_id: "nemo-helix-signing" private_key_file: "/etc/nhx/workload-token/private-key.pem" oidc: enabled: true workload: client_id: "nemo-helix-workload" token_endpoint: "https://nhx.company.com/apis/auth/token" audience: "nemo-helix" scope: "openid email groups" kubernetes_token_review_enabled: true ``` Workload token exchange is a platform-wide mode. When `auth.oidc.workload` is configured, managed workloads that need creator-scoped platform access use exchanged bearer tokens, and trusted `X-NHX-*` identity headers are rejected on protected service routes. When it is absent but `auth.enabled=true`, the platform uses trusted-header mode. By default, workload-exchange access tokens use `auth.token_signing.key_id` as their JWT `kid`. To give workload tokens a distinct key identifier, set `auth.oidc.workload.token_key_id`. For cryptographic separation, also set `auth.oidc.workload.token_private_key_file`; changing only the key ID is useful for debugging and rotation labeling, but still reuses the same RSA private key. When `NHX_WORKLOAD_IDENTITY_TOKEN_FILE` is present, the SDK reads the subject token from that file and sends an RFC 8693 exchange request using `subject_token`, fixed JWT subject/access-token token types, optional `audience`, and optional `scope`. `workload.token_endpoint` is optional; when it is unset, the SDK uses the Helix workload token-exchange route advertised by discovery. `auth.oidc.workload.scope` is a blanket allow-list for scopes minted by the current workload token exchange endpoint. It is not a per-service or per-workload grant model. Use it conservatively; per-service and per-workload scope grants should be modeled with stable service identities and role bindings when those grants are available. For Docker-backed job runtimes, the presence of `auth.oidc.workload` controls workload identity. When configured, job steps with a delegation auth context receive a NeMo Helix opaque workload proof token at `NHX_WORKLOAD_IDENTITY_TOKEN_FILE`. For Kubernetes-backed job runtimes, the jobs backend can project a Kubernetes service account token into each workload pod for token exchange. The projected token expiration defaults to `600` seconds and must be at least `600` seconds. Set `auth.oidc.workload.kubernetes_token_review_enabled: true` so the auth service validates projected service-account tokens with the Kubernetes TokenReview API. The API service account must also be authorized to create `authentication.k8s.io/v1` `tokenreviews` (for example, by binding it to the built-in `system:auth-delegator` ClusterRole). In platform configuration, set `jobs.executors[].config.workload_identity.token_expiration_seconds` on the Kubernetes job executor profile. For example, this changes the projected token lifetime from the 600-second default to one hour: ```yaml jobs: executors: - provider: cpu profile: workload backend: kubernetes_job config: workload_identity: token_expiration_seconds: 3600 ``` ## Example Configurations ### Quickstart / development (auth disabled) ```yaml auth: enabled: false ``` ### Quickstart / development (auth enabled) ```yaml auth: enabled: true policy_decision_point_provider: embedded policy_decision_point_base_url: "http://localhost:8080" embedded_pdp_auto_build_wasm: true admin_email: "admin@example.com" ``` When running from a source checkout, embedded PDP startup can automatically build a missing `policy.wasm` with the pinned OPA version used by `make build-policy`. Packaged deployments should include `policy.wasm` at image or wheel build time; set `embedded_pdp_auto_build_wasm: false` to fail fast if that artifact is missing. After changing policy source files, run `make build-policy` to refresh the artifact. In offline development environments, provide the pinned OPA binary explicitly: ```bash OPA_BIN=/path/to/opa_linux_amd64_static uv run nemo services run --host 127.0.0.1 --port 8080 ``` Or seed the local cache used by `script/build_policy_wasm.sh`: ```bash mkdir -p .cache/opa/v1.8.0 cp /path/to/opa_linux_amd64_static .cache/opa/v1.8.0/opa_linux_amd64_static chmod +x .cache/opa/v1.8.0/opa_linux_amd64_static ``` ### Production with embedded PDP ```yaml auth: enabled: true policy_decision_point_base_url: "http://auth:8000" policy_decision_point_provider: embedded embedded_pdp_auto_build_wasm: false policy_data_refresh_interval: 30 admin_email: "platform-admin@company.com" oidc: enabled: true issuer: "https://login.microsoftonline.com//v2.0" public_client: client_id: "" ``` ### Production with external OPA ```yaml auth: enabled: true policy_decision_point_base_url: "http://opa:8181" policy_decision_point_provider: opa bundle_cache_seconds: 5 ``` ## Related * [Authentication and Authorization](/documentation/access-control) — Overview, auth methods, and getting started. * [OIDC Setup](/documentation/access-control/authentication/oidc-setup) — IdP configuration and CLI login. * [Gateway Integration](/documentation/access-control/deployment/gateway-integration) — Using a gateway for authorization. * [Managing Access](/documentation/access-control/authorization/managing-access) — Workspaces and member management. * [Policy Engine](/documentation/access-control/authorization/policy-engine) — PDP internals and configuration. ## Docs - [Credential Propagation](https://docs.nvidia.com/nemo-helix/latest/documentation/access-control/deployment/credential-propagation.md): - [Gateway Integration](https://docs.nvidia.com/nemo-helix/latest/documentation/access-control/deployment/gateway-integration.md): - [Production Hardening](https://docs.nvidia.com/nemo-helix/latest/documentation/access-control/deployment/production-hardening.md):