---
# SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: Apache-2.0

title: "Gateway Integration"
description: ""
---
In production, a gateway (reverse proxy, ingress controller, or service mesh) often sits in front of the NeMo Platform. This page explains the recommended enforced gateway path for bearer-token authentication, what headers the gateway must set, and which paths skip authorization.

For the security architecture, see [Security Model](/documentation/access-control/security-model).

## Overview

NeMo Platform services trust identity headers only after a bearer token has been validated. In gateway deployments, the recommended path is:

1. The gateway calls `/apis/auth/authenticate` before forwarding protected API requests.
2. The auth service validates the bearer token and returns trusted `X-NMP-Principal-*` and `X-NMP-Scopes` headers.
3. The gateway forwards those trusted headers to NeMo Platform services.
4. Services run their normal PDP authorization checks using the trusted principal and scopes.

This callout can validate any bearer token accepted by the auth service: OIDC access tokens when `auth.oidc.enabled=true`, Scoped Access Keys when `auth.access_keys.enabled=true`, and workload tokens when workload identity is enabled.

If gateway enforcement is not required, the gateway can forward bearer tokens unchanged and let service middleware validate them directly. This page focuses on the enforced gateway path.

## Gateway Bearer-Auth Callout

To use gateway bearer-auth callout, configure your gateway to call the NeMo Platform auth service with the original `Authorization` header. On success, forward only the trusted headers returned by the auth service. This keeps token validation and NeMo claim mapping inside the auth service instead of duplicating them in static gateway JWT config.

<Note>

For IdP-issued tokens, enforce your IdP's revocation policy before setting NeMo headers. Do not rely on a gateway rule that only maps JWT claims into headers, such as Envoy `claim_to_headers`, when immediate revocation must be honored.

</Note>

<Warning>

**Security Requirement**: Your ingress/gateway **must** strip the following headers from all incoming external requests before forwarding to NeMo Platform:

- `X-NMP-Principal-Id`, `X-NMP-Principal-Email`, `X-NMP-Principal-Groups`, `X-NMP-Principal-On-Behalf-Of`
- `X-NMP-Scopes`

If external clients can set these headers, they can forge any identity or bypass authorization entirely. The gateway should also block external access to `/internal/*` paths (used for service-to-service communication).

</Warning>

## Required Headers (Gateway Bearer-Auth Callout)

When the gateway has authenticated the bearer token, it must forward:

| Header | Description |
|--------|-------------|
| `X-NMP-Principal-Id` | Principal identifier (e.g., user ID or email). Required. |
| `X-NMP-Principal-Email` | User email (optional but recommended). |
| `X-NMP-Principal-Groups` | Comma-separated group names (optional). |
| `X-NMP-Scopes` | Space-separated token scopes (optional). |

Header names are case-insensitive; services normalize them.

## Bypass Paths

The following are **not** subject to authorization checks; they are always allowed:

- **Health and readiness**: `/health`, `/healthz`, `/ready`, `/readyz`, `/health/live`, `/health/ready`, `/metrics`
- **Discovery**: `/apis/auth/discovery` (for CLI/SDK OIDC discovery)
- **PDP endpoints**: Paths under `/apis/auth/v2/authz/` are restricted to service principals only. The middleware rejects external and regular-user requests automatically.
- **Studio**: Paths under `/studio` (the Studio UI handles its own OIDC login)

Configure the gateway so these paths are not sent to `/apis/auth/authenticate` when using gateway bearer-auth callout.

## Gateway Configuration Examples

### Envoy Auth-Service Callout

<Accordion title="Envoy ext_authz filter configuration">

Replace placeholder values before applying this configuration.

```yaml
http_filters:
  - name: envoy.filters.http.ext_authz
    typed_config:
      "@type": type.googleapis.com/envoy.extensions.filters.http.ext_authz.v3.ExtAuthz
      transport_api_version: V3
      failure_mode_allow: false
      status_on_error:
        code: ServiceUnavailable
      http_service:
        server_uri:
          uri: "http://nemo:8080"
          cluster: nemo
          timeout: 5s
        path_prefix: "/apis/auth/authenticate"
        authorization_response:
          allowed_upstream_headers:
            patterns:
              - exact: x-nmp-principal-id
              - exact: x-nmp-principal-email
              - exact: x-nmp-principal-groups
              - exact: x-nmp-scopes
  - name: envoy.filters.http.router
    typed_config:
      "@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
```

Envoy HTTP `ext_authz` callouts preserve the original request method and build the check URL from `path_prefix` plus the original request path. For example, `DELETE /apis/entities/v2/workspaces/default` is checked as `DELETE /apis/auth/authenticate/apis/entities/v2/workspaces/default`. NeMo accepts that prefixed callout URL, validates only the bearer token, and returns trusted principal headers. The original request path is still authorized later by the service PDP check after Envoy forwards the request.

</Accordion>
### Header Stripping

Configure your gateway to remove NeMo Platform auth headers from incoming external requests. This prevents clients from forging identities.

<Accordion title="Envoy header stripping">

Add `request_headers_to_remove` to your route configuration:

```yaml
route_config:
  virtual_hosts:
    - name: nmp_service
      domains: ["*"]
      request_headers_to_remove:
        - "x-nmp-principal-id"
        - "x-nmp-principal-email"
        - "x-nmp-principal-groups"
        - "x-nmp-principal-on-behalf-of"
        - "x-nmp-scopes"
      routes:
        - match: { prefix: "/" }
          route: { cluster: nmp_backend }
```

</Accordion>
## Testing Gateway Auth

After configuring gateway bearer-auth callout, verify:

1. **Headers are set correctly** — Make a request through the gateway and check that `X-NMP-Principal-Id` and `X-NMP-Scopes` are present on the service side when the token contains scopes.
2. **Headers are stripped from external requests** — Try sending `X-NMP-Principal-Id` or `X-NMP-Scopes` from outside; verify they are stripped by the gateway.

## Related

- [Auth Configuration](/documentation/access-control/deployment) — Enabling auth and PDP provider (embedded vs OPA).
- [Security Model](/documentation/access-control/security-model) — Trust boundaries and gateway trust model.
- [Production Hardening](/documentation/access-control/deployment/production-hardening) — Security checklist including gateway requirements.
