> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.nvidia.com/nemo-platform/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.nvidia.com/nemo-platform/_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/overview). 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 **PlatformAdmin** 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 `NMP_SEED_ON_STARTUP=true` before `nemo services run`, or run `uv run python -m nmp.platform_seed` after services are healthy. If platform seed has not run, `admin_email` users can authenticate but still receive `403 Forbidden` because their PlatformAdmin 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 **`NMP_AUTH_`** prefix. Names are derived from the config keys in UPPER\_SNAKE\_CASE.

Examples:

```bash
NMP_AUTH_ENABLED=true
NMP_AUTH_POLICY_DECISION_POINT_BASE_URL=http://auth:8000
NMP_AUTH_POLICY_DECISION_POINT_PROVIDER=embedded
NMP_AUTH_ADMIN_EMAIL=admin@example.com
NMP_AUTH_EMBEDDED_PDP_AUTO_BUILD_WASM=true
```

Nested keys (e.g., OIDC) use double underscore: `NMP_AUTH_OIDC__ISSUER`, `NMP_AUTH_OIDC__CLIENT_ID`.

## OIDC Workload Identity Exchange

`auth.oidc` can also advertise SDK workload identity token exchange metadata:

```yaml
auth:
 oidc:
 enabled: true
 token_endpoint: "https://idp.example.com/oauth/token"
 workload_token_exchange_enabled: true
 workload_client_id: "nemo-platform-workload"
 workload_token_endpoint: "https://idp.example.com/oauth/token"
 workload_audience: "nemo-platform"
 workload_scope: "openid email groups"
```

When `NMP_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 `token_endpoint`. This is useful when host CLI login and workload
containers need different network-reachable IdP URLs.

For Docker-backed job runtimes, the executor may also need a controller-side
subject-token issuer. Configure only Docker-specific fields under the Docker
executor profile:

```yaml
jobs:
  executors:
    - provider: cpu
      profile: workload
      backend: docker
      config:
        workload_identity:
          token_endpoint: "https://idp.example.com/oauth/token"
          client_id: "nemo-platform-workload"
          username: "svc-nemo"
          password_env_var: "WORKLOAD_IDENTITY_PASSWORD"
          scope: "openid email groups"
```

The password value is read from the controller process environment using
`password_env_var`. The config does not support an inline `password` field.

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.
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/<tenant>/v2.0"
 client_id: "<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) — 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.