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

# OpenShift

> Install the OpenShell Helm chart on OpenShift, including the SCC binding and chart overrides required by OpenShift's Security Context Constraints.

> **Warning**
>
> The OpenShift install path is experimental. It currently requires running sandbox pods under the `privileged` SCC and installing the gateway with TLS disabled. Use only for evaluation on a private network.

OpenShift's [Security Context Constraints](https://docs.openshift.com/container-platform/latest/authentication/managing-security-context-constraints.html) reject the chart's default pod security settings. Installing on OpenShift requires precreating the namespace, granting the `privileged` SCC to the sandbox service account, and overriding a few chart values so the cluster admission controller can assign UIDs and FS groups itself.

OpenShell installs sandbox nftables rules as individual commands. On OpenShift
nodes where optional conntrack or packet log expressions are unavailable, those
optional rules can fail without rolling back the required proxy bypass reject
rules.

## Prerequisites

* OpenShift 4.x cluster with `oc` configured
* Helm 3.x
* [Agent Sandbox](/kubernetes/setup#install-agent-sandbox) controller and CRDs installed

## Install

## Create the namespace

Pre-create the namespace so the SCC binding can be applied before the chart installs:

```shell
oc create ns openshell
```

## Grant the privileged SCC to sandbox pods

Sandbox pods run under the `openshell-sandbox` service account in the `openshell` namespace and require the `privileged` SCC:

```shell
oc adm policy add-scc-to-user privileged -z openshell-sandbox -n openshell
```

## Install the chart with OpenShift overrides

```shell
helm install openshell oci://ghcr.io/nvidia/openshell/helm-chart \
  --version <version> \
  --namespace openshell \
  --set server.disableTls=true \
  --set podSecurityContext.fsGroup=null \
  --set securityContext.runAsUser=null
```

| Override                                                             | Reason                                                                                    |
| -------------------------------------------------------------------- | ----------------------------------------------------------------------------------------- |
| `server.disableTls=true`                                             | Runs the gateway over plaintext HTTP for simpler evaluation.                              |
| `podSecurityContext.fsGroup=null` / `securityContext.runAsUser=null` | Clear the chart's hardcoded UID and fsGroup so OpenShift's SCC admission can assign them. |

## Wait for the gateway to be ready

```shell
oc -n openshell rollout status statefulset/openshell
```

If you set `workload.kind=deployment`, use
`oc -n openshell rollout status deployment/openshell` instead.

## Connect to the gateway

The gateway is now running over plaintext HTTP. Connect with `oc port-forward`:

```shell
oc -n openshell port-forward svc/openshell 8080:8080
```

Register the gateway with the CLI:

```shell
openshell gateway add http://127.0.0.1:8080 --local --name openshift
openshell status
```

## Production: expose externally with a real certificate

The steps above run the gateway over plaintext HTTP for quick evaluation. For
a real deployment, cert-manager can issue the gateway's server certificate
from a real Issuer or ClusterIssuer (for example, an ACME issuer), and an
OpenShift Route with TLS passthrough exposes it externally while the gateway
keeps terminating its own TLS and mTLS.

Install cert-manager and configure a working `ClusterIssuer` first — see
[Managing Certificates](/kubernetes/managing-certificates) for the
`certManager.serverIssuerRef` details. Configure an OIDC provider as described
in [Access Control](/kubernetes/access-control) — remote gateways authenticate
CLI users via OIDC, not mTLS, so the gateway must know the OIDC issuer URL.
Install the chart with:

```shell
helm install openshell oci://ghcr.io/nvidia/openshell/helm-chart \
  --version <version> \
  --namespace openshell \
  --set podSecurityContext.fsGroup=null \
  --set securityContext.runAsUser=null \
  --set server.disableTls=false \
  --set certManager.enabled=true \
  --set certManager.serverIssuerRef.name=<cluster-issuer-name> \
  --set certManager.serverIssuerRef.kind=ClusterIssuer \
  --set certManager.serverDnsNames[0]=<external-hostname> \
  --set openshiftRoute.enabled=true \
  --set openshiftRoute.host=<external-hostname> \
  --set server.oidc.issuer=<oidc-issuer-url> \
  --set server.oidc.audience=<oidc-audience>
```

| Override                                         | Reason                                                                                                                                                                                                                                                                                                                                                                                       |
| ------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `certManager.serverIssuerRef`                    | Creates a second server certificate from your Issuer or ClusterIssuer for external clients. The gateway uses SNI to present this cert for the external hostname while continuing to present the internal (chart CA) cert to supervisors. The internal certificate's `ca.crt` is the chart CA that also signed the client cert, so the default `clientCaFromServerTlsSecret=true` is correct. |
| `openshiftRoute.enabled` / `openshiftRoute.host` | Creates an OpenShift Route with TLS passthrough — the router forwards the encrypted connection by SNI without decrypting, so the gateway uses the SNI hostname to select the external certificate.                                                                                                                                                                                           |
| `server.oidc.issuer` / `server.oidc.audience`    | Configures server-side OIDC validation. Without these, the gateway expects mTLS client certificates and rejects OIDC-only CLI connections. See [Access Control](/kubernetes/access-control).                                                                                                                                                                                                 |

Register the gateway with the CLI over OIDC. Remote gateways authenticate CLI
users via OIDC, not mTLS — see [Access Control](/kubernetes/access-control):

```shell
openshell gateway add https://<external-hostname> \
  --name openshift \
  --oidc-issuer <issuer-url>
openshell gateway login openshift
```

## Next Steps

* For more on certificate provisioning modes, refer to [Managing Certificates](/kubernetes/managing-certificates).
* To expose the gateway externally through the Kubernetes Gateway API instead of a Route, refer to [Ingress](/kubernetes/ingress).
* To configure OIDC authentication, refer to [Access Control](/kubernetes/access-control).