diff --git a/docs/about/installation.mdx b/docs/about/installation.mdx index e2ad59bd9..378439758 100644 --- a/docs/about/installation.mdx +++ b/docs/about/installation.mdx @@ -67,7 +67,7 @@ sudo loginctl enable-linger $USER ## Kubernetes -Kubernetes deployments use the OpenShell Helm chart. For chart installation and configuration, refer to the [Helm chart README](https://github.com/NVIDIA/OpenShell/blob/main/deploy/helm/openshell/README.md). +Kubernetes deployments use the OpenShell Helm chart. For step-by-step installation, refer to [Kubernetes Setup](/kubernetes/setup). For chart values and packaging details, refer to the [Helm chart README](https://github.com/NVIDIA/OpenShell/blob/main/deploy/helm/openshell/README.md). ## Next Steps diff --git a/docs/index.yml b/docs/index.yml index 5a1039552..bbeb4decf 100644 --- a/docs/index.yml +++ b/docs/index.yml @@ -19,6 +19,8 @@ navigation: title: "How It Works" - folder: observability title: "Observability" +- folder: kubernetes + title: "Kubernetes" - folder: reference title: "Reference" - folder: security diff --git a/docs/kubernetes/access-control.mdx b/docs/kubernetes/access-control.mdx new file mode 100644 index 000000000..c07f77eaa --- /dev/null +++ b/docs/kubernetes/access-control.mdx @@ -0,0 +1,106 @@ +--- +# SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 +title: "Access Control" +sidebar-title: "Access Control" +description: "Configure OIDC user authentication or reverse-proxy auth termination for a Kubernetes-deployed OpenShell gateway." +keywords: "Generative AI, Cybersecurity, Kubernetes, Authentication, mTLS, OIDC, Keycloak, Entra ID, Okta, Gateway Auth" +position: 4 +--- + +The OpenShell gateway supports two access-control models for human callers on Kubernetes: + +| Model | When to use | +|---|---| +| OIDC (recommended) | Production deployments. Integrates with an existing identity provider, supports role-based access control, and gives each user their own identity without distributing certificates. | +| Reverse-proxy auth termination | An access proxy (Cloudflare Access, ngrok, corporate SSO) authenticates callers in front of the gateway. The gateway trusts the proxy and skips its own client-cert check. | + +The Helm chart always generates mTLS certificates at install time. The gateway uses them for transport-layer security regardless of which access-control model you choose. The client bundle in the `openshell-client-tls` secret is used internally by sandbox supervisors, not for granting access to individual users. + +For how the CLI resolves gateways and stores credentials, refer to [Gateway Authentication](/reference/gateway-auth). + +## OIDC User Authentication + +Set `server.oidc.issuer` to enable OIDC. The gateway validates the `Authorization: Bearer ` header on every request against the issuer's JWKS endpoint. + +```shell +helm upgrade openshell \ + oci://ghcr.io/nvidia/openshell/helm-chart \ + --version \ + --namespace openshell \ + --set server.oidc.issuer=https://your-idp.example.com/realms/openshell \ + --set server.oidc.audience=openshell-cli +``` + +The `audience` value must match the client ID configured in your identity provider for the OpenShell resource server. + +### OIDC values reference + +| Value | Default | Purpose | +|---|---|---| +| `server.oidc.issuer` | `""` | OIDC issuer URL. Empty disables OIDC. | +| `server.oidc.audience` | `openshell-cli` | Expected `aud` claim in the JWT. | +| `server.oidc.jwksTtl` | `3600` | JWKS key cache TTL in seconds. | +| `server.oidc.rolesClaim` | `""` | Dot-separated path to the roles array in JWT claims. | +| `server.oidc.adminRole` | `""` | Role name that grants admin access. | +| `server.oidc.userRole` | `""` | Role name that grants standard user access. | +| `server.oidc.scopesClaim` | `""` | Dot-separated path to the scopes array in JWT claims. | + +### Auth-only mode vs. RBAC mode + +Leave both `adminRole` and `userRole` empty to use auth-only mode: any request with a valid JWT from the configured issuer is accepted, but no role distinction is enforced. + +Set both values to enable RBAC mode, where the gateway checks the role claim and enforces access based on the assigned role: + +```shell +helm upgrade openshell \ + oci://ghcr.io/nvidia/openshell/helm-chart \ + --version \ + --namespace openshell \ + --set server.oidc.issuer=https://your-idp.example.com/realms/openshell \ + --set server.oidc.audience=openshell-cli \ + --set server.oidc.rolesClaim=realm_access.roles \ + --set server.oidc.adminRole=openshell-admin \ + --set server.oidc.userRole=openshell-user +``` + +`adminRole` and `userRole` must both be set or both be empty — setting only one is not supported. + +### Provider-specific rolesClaim paths + +| Provider | rolesClaim value | +|---|---| +| Keycloak | `realm_access.roles` | +| Microsoft Entra ID | `roles` | +| Okta | `groups` | + +## Reverse-Proxy Auth Termination + +When an access proxy — such as Cloudflare Access, ngrok, or a corporate SSO gateway — handles authentication in front of the OpenShell gateway, you can disable the gateway's own client certificate verification: + +```shell +helm upgrade openshell \ + oci://ghcr.io/nvidia/openshell/helm-chart \ + --version \ + --namespace openshell \ + --set server.disableGatewayAuth=true +``` + +The gateway still serves TLS, but stops requiring a client certificate on incoming connections. The proxy is responsible for authenticating callers and forwarding only authorized traffic. + +To also disable TLS entirely (when the proxy terminates TLS before the request reaches the gateway): + +```shell + --set server.disableTls=true \ + --set server.disableGatewayAuth=true +``` + + +Only disable TLS and gateway auth when the gateway is not reachable from outside the cluster and the proxy path is fully trusted. Never expose a plaintext, auth-disabled gateway to a public network. + + +Register the gateway with the CLI using the proxy's public URL — the browser-based login flow runs automatically on first use: + +```shell +openshell gateway add https://gateway.example.com --name production +``` diff --git a/docs/kubernetes/ingress.mdx b/docs/kubernetes/ingress.mdx new file mode 100644 index 000000000..fa0a1cf14 --- /dev/null +++ b/docs/kubernetes/ingress.mdx @@ -0,0 +1,83 @@ +--- +# SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 +title: "Ingress" +sidebar-title: "Ingress" +description: "Expose the OpenShell gateway externally using the Kubernetes Gateway API and a GRPCRoute." +keywords: "Generative AI, Cybersecurity, Kubernetes, Gateway API, Envoy Gateway, GRPCRoute, Ingress, External Access" +position: 3 +--- + +By default, the OpenShell gateway is only reachable inside the cluster. To let CLI clients connect without a `kubectl port-forward`, expose the gateway through an ingress. + +OpenShell uses the [Kubernetes Gateway API](https://gateway-api.sigs.k8s.io) for ingress. The chart creates a `GRPCRoute` that routes inbound gRPC traffic to the gateway pod. You need a Gateway API implementation installed on your cluster to fulfill the `GRPCRoute`. This page uses [Envoy Gateway](https://gateway.envoyproxy.io), which the chart is tested with. + +## Install Envoy Gateway + +Envoy Gateway installs the Gateway API CRDs and registers the `eg` GatewayClass: + +```shell +helm install eg \ + oci://docker.io/envoyproxy/gateway-helm \ + --version v1.7.2 \ + --namespace envoy-gateway-system \ + --create-namespace \ + --wait +``` + +Verify the GatewayClass is accepted: + +```shell +kubectl get gatewayclass eg +``` + +The `ACCEPTED` column should show `True`. + +## Install OpenShell with Gateway API enabled + +Enable the GRPCRoute and let the chart create a Gateway resource in the `openshell` namespace: + +```shell +helm upgrade --install openshell \ + oci://ghcr.io/nvidia/openshell/helm-chart \ + --version \ + --namespace openshell \ + --set grpcRoute.enabled=true \ + --set grpcRoute.gateway.create=true \ + --set grpcRoute.gateway.className=eg +``` + +## Get the external address + +After the Gateway is provisioned, Envoy Gateway creates a LoadBalancer service in the `openshell` namespace. Wait for it to get an external address: + +```shell +kubectl -n openshell get svc -l gateway.envoyproxy.io/owning-gateway-name=openshell +``` + +Once the `EXTERNAL-IP` is assigned, register the gateway with the CLI: + +```shell +openshell gateway add http:// --name production +openshell status +``` + +## Configure SSH relay + +For sandbox SSH connections to work through the external address, set `server.sshGatewayHost` and `server.sshGatewayPort` to the hostname and port that CLI clients can reach: + +```shell +helm upgrade openshell \ + oci://ghcr.io/nvidia/openshell/helm-chart \ + --version \ + --namespace openshell \ + --set grpcRoute.enabled=true \ + --set grpcRoute.gateway.create=true \ + --set grpcRoute.gateway.className=eg \ + --set server.sshGatewayHost= \ + --set server.sshGatewayPort= +``` + +## Next Steps + +Return to [Setup](/kubernetes/setup) to complete the installation. diff --git a/docs/kubernetes/managing-certificates.mdx b/docs/kubernetes/managing-certificates.mdx new file mode 100644 index 000000000..dcea304d4 --- /dev/null +++ b/docs/kubernetes/managing-certificates.mdx @@ -0,0 +1,61 @@ +--- +# SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 +title: "Managing Certificates" +sidebar-title: "Managing Certificates" +description: "Configure the OpenShell Helm chart to use cert-manager for mTLS certificate issuance and automatic renewal." +keywords: "Generative AI, Cybersecurity, Kubernetes, cert-manager, PKI, TLS, mTLS, Certificates" +position: 2 +--- + +The OpenShell gateway requires mTLS certificates for sandbox supervisors and clients. The Helm chart supports two ways to provision and manage them: + +| Mode | When to use | +|---|---| +| Built-in `pkiInitJob` (default) | Simplest path. A pre-install Kubernetes Job generates a self-signed CA and certificates once at install time. No additional dependencies. | +| cert-manager | Production deployments that need automatic certificate rotation managed by a running controller. | + +The rest of this page covers switching to cert-manager. The built-in mode requires no configuration. + + +cert-manager and `pkiInitJob` are mutually exclusive. The chart will fail if both are enabled at the same time. + + +## Install cert-manager + +Add the Jetstack Helm repository and install cert-manager with CRD support enabled: + +```shell +helm repo add jetstack https://charts.jetstack.io +helm repo update +helm upgrade --install cert-manager jetstack/cert-manager \ + --namespace cert-manager \ + --create-namespace \ + --set crds.enabled=true \ + --wait +``` + +Verify the cert-manager pods are running: + +```shell +kubectl -n cert-manager get pods +``` + +## Install OpenShell with cert-manager PKI + +Pass the cert-manager values override when installing or upgrading the chart: + +```shell +helm upgrade --install openshell \ + oci://ghcr.io/nvidia/openshell/helm-chart \ + --version \ + --namespace openshell \ + --set certManager.enabled=true \ + --set pkiInitJob.enabled=false +``` + +The chart creates a self-signed CA, issues server and client certificates from it, and cert-manager handles renewal before expiry. + +## Next Steps + +Return to [Setup](/kubernetes/setup) to complete the installation. diff --git a/docs/kubernetes/openshift.mdx b/docs/kubernetes/openshift.mdx new file mode 100644 index 000000000..151bf27a6 --- /dev/null +++ b/docs/kubernetes/openshift.mdx @@ -0,0 +1,88 @@ +--- +# SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 +title: "OpenShift" +sidebar-title: "OpenShift" +description: "Install the OpenShell Helm chart on OpenShift, including the SCC binding and chart overrides required by OpenShift's Security Context Constraints." +keywords: "Generative AI, Cybersecurity, Kubernetes, OpenShift, SCC, Security Context Constraints, Helm, Gateway, Installation" +position: 5 +--- + + +The OpenShift install path is experimental. It currently requires running sandbox pods under the `privileged` SCC and installing the gateway with TLS and the PKI init job 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 default service account, and overriding a few chart values so the cluster admission controller can assign UIDs and FS groups itself. + +## 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 `default` service account in the `openshell` namespace and require the `privileged` SCC: + +```shell +oc adm policy add-scc-to-user privileged -z default -n openshell +``` + +## Install the chart with OpenShift overrides + +```shell +helm install openshell oci://ghcr.io/nvidia/openshell/helm-chart \ + --version \ + --namespace openshell \ + --set pkiInitJob.enabled=false \ + --set server.disableTls=true \ + --set podSecurityContext.fsGroup=null \ + --set securityContext.runAsUser=null +``` + +| Override | Reason | +|---|---| +| `pkiInitJob.enabled=false` | The PKI init Job runs as a non-root user with a fixed UID, which the SCC admission rewrites or rejects. Disabling it skips the Job; TLS must also be disabled. | +| `server.disableTls=true` | The gateway has no certificates without `pkiInitJob`, so it must run plaintext. | +| `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 +``` + + + +## 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 +``` + +## Next Steps + +- For TLS-enabled deployments, see [Managing Certificates](/kubernetes/managing-certificates) once SCC-compatible PKI is supported. +- To expose the gateway externally, see [Ingress](/kubernetes/ingress). +- To configure OIDC authentication, see [Access Control](/kubernetes/access-control). diff --git a/docs/kubernetes/setup.mdx b/docs/kubernetes/setup.mdx new file mode 100644 index 000000000..c5aa00fba --- /dev/null +++ b/docs/kubernetes/setup.mdx @@ -0,0 +1,155 @@ +--- +# SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 +title: "Get Started on Kubernetes" +sidebar-title: "Setup" +description: "Deploy the OpenShell gateway to a Kubernetes cluster using the official Helm chart from GHCR." +keywords: "Generative AI, Cybersecurity, Kubernetes, Helm, Gateway, Deployment, OCI, GHCR, Installation" +position: 1 +--- + + +The OpenShell Helm chart is experimental and under active development. Templates, values, and defaults may change between releases. Do not use it in production. + + +Use the Kubernetes deployment when the gateway should run on a shared cluster, in a cloud environment, or as part of team infrastructure. The Helm chart deploys the gateway as a StatefulSet and handles PKI bootstrap, RBAC, and sandbox namespace setup automatically. + +## Prerequisites + +Make sure the following are in place before you install. + +| Prerequisite | Required | Notes | +|---|---|---| +| Kubernetes 1.29+ with RBAC enabled | Yes | — | +| Helm 3.x | Yes | — | +| Agent Sandbox controller and CRDs | Yes | Install before the OpenShell chart — see [Install Agent Sandbox](#install-agent-sandbox) below | +| cert-manager | No | See [Managing Certificates](/kubernetes/managing-certificates) — only needed if you prefer cert-manager over the built-in PKI job | +| Kubernetes Gateway API | No | See [Ingress](/kubernetes/ingress) — only needed for external access without port-forwarding | + +## Install Agent Sandbox + +OpenShell uses the [Agent Sandbox](https://agent-sandbox.sigs.k8s.io) Kubernetes SIG project to provision sandbox pods. Install the Agent Sandbox controller and its CRDs on your cluster before installing the OpenShell Helm chart. + +Fetch the latest release tag and apply the manifest: + +```shell +VERSION=$(curl -s https://api.github.com/repos/kubernetes-sigs/agent-sandbox/releases/latest | jq -r '.tag_name') +kubectl apply -f https://github.com/kubernetes-sigs/agent-sandbox/releases/download/${VERSION}/manifest.yaml +``` + +This creates the `agent-sandbox-system` namespace, installs the CRDs, and starts the controller. + +Confirm the controller pod is running before proceeding: + +```shell +kubectl -n agent-sandbox-system get pods +``` + +The controller pod should reach `Running` status within a few seconds. For cluster-specific setup instructions, including KinD and GKE walkthroughs, refer to the [Agent Sandbox getting started guide](https://agent-sandbox.sigs.k8s.io/docs/getting_started/). + +## Install OpenShell + + + +## Create the namespace + +```shell +kubectl create namespace openshell +``` + +## Install the chart + +Install from the OCI registry on GHCR. Replace `` with the chart version you want to install. + +```shell +helm upgrade --install openshell \ + oci://ghcr.io/nvidia/openshell/helm-chart \ + --version \ + --namespace openshell +``` + +To use the latest development build instead of a stable release: + +```shell +helm upgrade --install openshell \ + oci://ghcr.io/nvidia/openshell/helm-chart \ + --version 0.0.0-dev \ + --namespace openshell +``` + +The chart automatically generates PKI secrets and an SSH handshake secret on first install using pre-install Helm hooks. No manual secret creation is required. + +## Wait for the gateway to be ready + +```shell +kubectl -n openshell rollout status statefulset/openshell +``` + +## Connect to the gateway + +For local evaluation, use a port-forward: + +```shell +kubectl -n openshell port-forward svc/openshell 8080:8080 +``` + + +The port-forward is for local evaluation only. For shared environments, expose the gateway through your ingress controller or access proxy. See [Ingress](/kubernetes/ingress) for an external access option. + + +## Install the client mTLS certificate + +The default installation runs with mTLS enabled by default. The CLI needs the client certificate, key, and CA that the chart's PKI hook generated. Extract them from the `openshell-client-tls` secret and place them where the CLI expects them for a gateway named `k8s`: + +```shell +mkdir -p ~/.config/openshell/gateways/k8s/mtls +kubectl -n openshell get secret openshell-client-tls \ + -o jsonpath='{.data.ca\.crt}' | base64 -d > ~/.config/openshell/gateways/k8s/mtls/ca.crt +kubectl -n openshell get secret openshell-client-tls \ + -o jsonpath='{.data.tls\.crt}' | base64 -d > ~/.config/openshell/gateways/k8s/mtls/tls.crt +kubectl -n openshell get secret openshell-client-tls \ + -o jsonpath='{.data.tls\.key}' | base64 -d > ~/.config/openshell/gateways/k8s/mtls/tls.key +``` + +The server certificate SANs include `localhost` and `127.0.0.1`, so hostname verification passes over the port-forward without extra flags. + +## Register with the CLI + +In another terminal, register the gateway and verify it is reachable: + +```shell +openshell gateway add https://127.0.0.1:8080 --local --name k8s +openshell status +``` + + + +## Configure Chart Values + +The most commonly changed values are: + +| Value | Purpose | +|---|---| +| `image.repository` / `image.tag` | Gateway container image. Defaults to `ghcr.io/nvidia/openshell/gateway:latest`. | +| `server.sandboxNamespace` | Namespace where sandbox pods are created. | +| `server.sandboxImage` | Default sandbox image used when a sandbox does not specify one. | +| `server.grpcEndpoint` | Endpoint that sandbox supervisors use to call back to the gateway. Must be reachable from inside the cluster. | +| `server.sshGatewayHost` / `server.sshGatewayPort` | Public host and port returned to CLI clients for SSH proxy connections. Required when the gateway is exposed externally. | +| `server.disableTls` | Run the gateway over plaintext HTTP. Use only behind a trusted transport. | + +Use a values file for repeatable deployments: + +```shell +helm upgrade --install openshell \ + oci://ghcr.io/nvidia/openshell/helm-chart \ + --version \ + --namespace openshell \ + --values my-values.yaml +``` + +## Next Steps + +- To enable automatic certificate rotation with cert-manager, see [Managing Certificates](/kubernetes/managing-certificates). +- To expose the gateway externally without port-forwarding, see [Ingress](/kubernetes/ingress). +- To configure OIDC or reverse-proxy authentication, see [Access Control](/kubernetes/access-control). +- To create your first sandbox, see [Manage Sandboxes](/sandboxes/manage-sandboxes).