* refactor!(auth): drop SSH handshake secret in favor of mTLS The OPENSHELL_SSH_HANDSHAKE_SECRET / x-sandbox-secret mechanism was misnamed: it does not authenticate SSH (which flows over the RelayStream gRPC RPC and is gated by mTLS plus supervisor Unix-socket permissions). It only gated a small set of sandbox-to-gateway control-plane RPCs, and production deployments already enforce mTLS on that channel — so the shared secret was redundant. Replace the secret check with an mTLS-presence marker. Sandbox-class methods (ReportPolicyStatus, PushSandboxLogs, GetSandboxProviderEnvironment, SubmitPolicyAnalysis, GetSandboxConfig, GetInferenceBundle) accept callers without a Bearer token; the gRPC mTLS handshake is the trust boundary. Dual-auth methods treat Bearer-present as full-scope CLI access and Bearer-absent as sandbox-restricted scope via validate_sandbox_caller_update. Drops the secret from all drivers (K8s, Podman, VM), the sandbox gRPC interceptor, the Helm chart (values + pre-install hook + StatefulSet env), the RPM bootstrap script, the man pages, and the debug-openshell-cluster skill. Also removes the never-read ssh_handshake_skew_secs flag and config field. BREAKING CHANGE: --ssh-handshake-secret / OPENSHELL_SSH_HANDSHAKE_SECRET and --ssh-handshake-skew-secs / OPENSHELL_SSH_HANDSHAKE_SKEW_SECS are removed from the gateway, sandbox, and all driver binaries. The openshell-ssh-handshake K8s Secret is no longer managed by the chart; operators may delete the orphan. Deployments using --disable-gateway-auth must enforce caller authentication at the fronting proxy, since the gateway no longer validates a per-request secret on sandbox-class methods. Refs OS-174. * docs(auth): scrub residual SSH handshake secret references Sweep across docs, e2e scripts, the Podman driver README/NETWORKING notes, the RPM/Helm/setup guides, the gateway man page, and RFC 0003 to remove instructions and examples that still referenced OPENSHELL_SSH_HANDSHAKE_SECRET / --ssh-handshake-secret / ssh_handshake_skew_secs. The mechanism is gone; nothing should still suggest setting it. Negative-assertion regression tests are kept so the env var cannot silently be re-introduced. * test(drivers): drop SSH handshake secret negative-assertion tests The supporting code, env vars, CLI flags, and config plumbing are gone — these tests asserted absence of strings that no longer have any path to being set. Remove the guards from the Docker, Podman, Kubernetes, and VM driver test modules.
OpenShell Helm Chart
Experimental — the Kubernetes deployment path is under active development. Expect rough edges and breaking changes.
This chart deploys the OpenShell gateway into a Kubernetes cluster. It is published as an OCI artifact to GHCR at oci://ghcr.io/nvidia/openshell/helm-chart.
Prerequisites
The Kubernetes Agent Sandbox CRDs and controller must be installed on the cluster before deploying OpenShell. Install them with:
kubectl apply -f https://github.com/kubernetes-sigs/agent-sandbox/releases/latest/download/manifest.yaml
Install on Kubernetes
helm install openshell oci://ghcr.io/nvidia/openshell/helm-chart --version <version>
Install on OpenShift
# Precreate the openshell namespace so we can create the SCC cluster role
oc create ns openshell
# Sandboxes are deployed into the openshell namespace and use the default service account for now
oc adm policy add-scc-to-user privileged -z default -n openshell
# Deploy openshell with overrides to allow SCC assignment of fsGroup and runAsUser for the gateway
helm install openshell oci://ghcr.io/nvidia/openshell/helm-chart --version <version> -n openshell \
--set pkiInitJob.enabled=false \
--set server.disableTls=true \
--set podSecurityContext.fsGroup=null \
--set securityContext.runAsUser=null
Available versions
| Tag | Source | Notes |
|---|---|---|
<semver> (e.g. 0.6.0) |
Tagged GitHub release | Tracks the matching gateway and supervisor image versions. Recommended for production. |
0.0.0-dev |
Latest commit on main |
Floating tag, overwritten on every push. appVersion is dev, so images resolve to the :dev tag. |
0.0.0-dev.<commit-sha> |
A specific commit on main |
Per-commit pin. Chart version and appVersion both use the full 40-character commit SHA, which matches the image tag pushed by CI. |
The dev tags are intended for testing changes ahead of a release. Production deployments should pin to a tagged release.
Configuration
See values.yaml for configurable values. Selected overlays:
ci/values-gateway.yaml— gateway-only configurationci/values-cert-manager.yaml— cert-manager integrationci/values-keycloak.yaml— Keycloak OIDC integration
PKI bootstrap
By default, a pre-install/pre-upgrade hook Job runs openshell-gateway generate-certs
to create the gateway's server and client mTLS Secrets. The Job uses the gateway image
itself, so air-gapped environments only need to mirror that one image (no separate
openssl/alpine sidecar).
The Job is idempotent:
- Both target Secrets exist → log and exit 0.
- Exactly one exists → fail with
kubectl delete secret -n <ns> <server> <client>recovery hint. - Neither exists → generate a CA, server cert, and client cert; POST both
kubernetes.io/tlsSecrets (tls.crt,tls.key,ca.crt).
Disable with --set pkiInitJob.enabled=false when bringing your own PKI (cert-manager,
external CA, or pre-created Secrets). See certManager.* in values.yaml for the
cert-manager alternative.