Skip to content

Commit 919cc7c

Browse files
committed
docs(gateway): consolidate gateway TOML examples into docs reference
Replaces the per-driver example files under examples/gateway/ with a single published reference page at docs/reference/gateway-config.mdx covering source precedence, layout, the full example, and the four per-driver examples (Kubernetes, Docker, Podman, microVM). Drew flagged during PR #1317 review that the examples belong with the user-facing docs rather than in a sibling examples/ directory. The cross-references in architecture/gateway.md and RFC 0003 are updated to point at the new docs page; the round-trip test in config_file.rs is removed (schema coverage stays on the inline parses_full_example test and per-field merge tests — doc-snippet drift belongs in a separate docs-lint, not in a cross-tree Rust unit test).
1 parent 9ea5ad8 commit 919cc7c

10 files changed

Lines changed: 217 additions & 237 deletions

File tree

architecture/gateway.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -204,8 +204,8 @@ CLI flag > OPENSHELL_* env var > TOML file > built-in default
204204

205205
The TOML file is opt-in via `--config <PATH>` / `OPENSHELL_GATEWAY_CONFIG`.
206206
When unset, the gateway behaves exactly as before — CLI flags and env vars
207-
drive every setting. See `examples/gateway/gateway.example.toml` for a
208-
worked example and RFC 0003 for the full schema.
207+
drive every setting. See `docs/reference/gateway-config.mdx` for worked
208+
per-driver examples and RFC 0003 for the full schema.
209209

210210
`database_url` is env-only and rejected when present in the file
211211
(`OPENSHELL_DB_URL` / `--db-url`).

crates/openshell-server/src/config_file.rs

Lines changed: 0 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -479,25 +479,4 @@ version = 2
479479
.expect_err("missing file must be io error");
480480
assert!(matches!(err, ConfigFileError::Io { .. }));
481481
}
482-
483-
/// Lock in that every checked-in example under `examples/gateway/`
484-
/// round-trips through the loader. Catches schema drift the moment a
485-
/// field is renamed or a doc snippet falls out of date.
486-
#[test]
487-
fn checked_in_examples_parse() {
488-
let repo_root = Path::new(env!("CARGO_MANIFEST_DIR"))
489-
.parent()
490-
.and_then(Path::parent)
491-
.expect("crate manifest has grandparent");
492-
for name in [
493-
"gateway.example.toml",
494-
"kubernetes.example.toml",
495-
"docker.example.toml",
496-
"podman.example.toml",
497-
"microvm.example.toml",
498-
] {
499-
let path = repo_root.join("examples/gateway").join(name);
500-
load(&path).unwrap_or_else(|e| panic!("{name} failed to parse: {e}"));
501-
}
502-
}
503482
}

docs/reference/gateway-config.mdx

Lines changed: 212 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,212 @@
1+
---
2+
# SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
3+
# SPDX-License-Identifier: Apache-2.0
4+
title: "Gateway Configuration File"
5+
sidebar-title: "Gateway Config"
6+
description: "Reference for the OpenShell gateway TOML configuration file (RFC 0003)."
7+
keywords: "Generative AI, Cybersecurity, AI Agents, Sandboxing, Gateway, Configuration, TOML, Reference"
8+
position: 5
9+
---
10+
11+
The OpenShell gateway reads its configuration from a TOML file when `--config` or `OPENSHELL_GATEWAY_CONFIG` is set. CLI flags and `OPENSHELL_*` environment variables always override the file. See [RFC 0003](https://github.com/NVIDIA/OpenShell/blob/main/rfc/0003-gateway-configuration/README.md) for the full schema.
12+
13+
## Source Precedence
14+
15+
```text
16+
CLI flag > OPENSHELL_* env var > TOML file > built-in default
17+
```
18+
19+
`database_url` and `ssh_handshake_secret` are env-only. The loader rejects them when they appear in the file.
20+
21+
## Layout
22+
23+
The file is rooted at `[openshell]`. Gateway-wide settings live under `[openshell.gateway]`. Each compute driver owns its own `[openshell.drivers.<name>]` table. Shared keys set at gateway scope are inherited into driver tables when not overridden.
24+
25+
```toml
26+
[openshell]
27+
version = 1
28+
29+
[openshell.gateway]
30+
# ... gateway-wide settings ...
31+
32+
[openshell.gateway.tls]
33+
# ... gateway listener TLS ...
34+
35+
[openshell.gateway.oidc]
36+
# ... JWT bearer auth ...
37+
38+
[openshell.drivers.kubernetes]
39+
# ... driver-specific settings ...
40+
```
41+
42+
## Full Example
43+
44+
A complete gateway configuration covering every section. Trim to the fields you need.
45+
46+
```toml
47+
# SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
48+
# SPDX-License-Identifier: Apache-2.0
49+
50+
[openshell]
51+
version = 1
52+
53+
[openshell.gateway]
54+
bind_address = "0.0.0.0:8080"
55+
health_bind_address = "0.0.0.0:8081"
56+
metrics_bind_address = "0.0.0.0:9090"
57+
58+
log_level = "info"
59+
60+
# When empty the gateway auto-detects (Kubernetes -> Podman -> Docker). VM is
61+
# never auto-detected and requires an explicit entry here.
62+
compute_drivers = ["kubernetes"]
63+
64+
sandbox_namespace = "openshell"
65+
sandbox_ssh_port = 2222
66+
ssh_gateway_host = "127.0.0.1"
67+
ssh_gateway_port = 8080
68+
69+
# Subject Alternative Names baked into the gateway server certificate.
70+
# Wildcard DNS SANs (e.g. "*.dev.openshell.localhost") also enable sandbox
71+
# service URLs under that domain.
72+
server_sans = ["openshell", "*.dev.openshell.localhost"]
73+
# Allow plaintext HTTP routing for loopback sandbox service URLs.
74+
enable_loopback_service_http = true
75+
76+
# Shared driver defaults — inherited into [openshell.drivers.<name>] tables
77+
# when the driver-specific table does not override them.
78+
default_image = "ghcr.io/nvidia/openshell/sandbox:latest"
79+
supervisor_image = "ghcr.io/nvidia/openshell/supervisor:latest"
80+
client_tls_secret_name = "openshell-client-tls"
81+
82+
# Gateway listener TLS (distinct from the per-driver guest_tls_*).
83+
[openshell.gateway.tls]
84+
cert_path = "/etc/openshell/certs/gateway.pem"
85+
key_path = "/etc/openshell/certs/gateway-key.pem"
86+
client_ca_path = "/etc/openshell/certs/client-ca.pem"
87+
allow_unauthenticated = false
88+
89+
[openshell.gateway.oidc]
90+
issuer = "https://idp.example.com/realms/openshell"
91+
audience = "openshell-cli"
92+
jwks_ttl_secs = 3600
93+
roles_claim = "realm_access.roles"
94+
admin_role = "openshell-admin"
95+
user_role = "openshell-user"
96+
```
97+
98+
`image_pull_policy` is intentionally not a shared gateway key. Kubernetes uses `Always | IfNotPresent | Never` while Podman uses `always | missing | never | newer`. Set it inside the relevant driver table.
99+
100+
## Per-Driver Examples
101+
102+
### Kubernetes
103+
104+
The gateway runs as a Pod and creates sandbox Pods in another namespace. mTLS material for sandboxes is delivered via a Kubernetes Secret rather than host-side file paths.
105+
106+
```toml
107+
[openshell]
108+
version = 1
109+
110+
[openshell.gateway]
111+
bind_address = "0.0.0.0:8080"
112+
health_bind_address = "0.0.0.0:8081"
113+
metrics_bind_address = "0.0.0.0:9090"
114+
log_level = "info"
115+
compute_drivers = ["kubernetes"]
116+
117+
default_image = "ghcr.io/nvidia/openshell/sandbox:latest"
118+
supervisor_image = "ghcr.io/nvidia/openshell/supervisor:latest"
119+
client_tls_secret_name = "openshell-client-tls"
120+
121+
[openshell.gateway.tls]
122+
cert_path = "/etc/openshell-tls/server/tls.crt"
123+
key_path = "/etc/openshell-tls/server/tls.key"
124+
client_ca_path = "/etc/openshell-tls/client-ca/ca.crt"
125+
126+
[openshell.drivers.kubernetes]
127+
namespace = "agents"
128+
grpc_endpoint = "https://openshell-gateway.agents.svc:8080"
129+
image_pull_policy = "IfNotPresent"
130+
# Use the image volume on K8s >= 1.35 (GA in 1.36); switch to "init-container"
131+
# on older clusters or where the ImageVolume feature gate is off.
132+
supervisor_sideload_method = "image-volume"
133+
```
134+
135+
### Docker
136+
137+
Sandboxes run as containers on a local bridge network. The supervisor binary is bind-mounted from the host (no in-cluster image pull required); guest mTLS material is supplied as host paths.
138+
139+
```toml
140+
[openshell]
141+
version = 1
142+
143+
[openshell.gateway]
144+
bind_address = "127.0.0.1:8080"
145+
log_level = "info"
146+
compute_drivers = ["docker"]
147+
148+
supervisor_image = "ghcr.io/nvidia/openshell/supervisor:latest"
149+
guest_tls_ca = "/etc/openshell/certs/ca.pem"
150+
guest_tls_cert = "/etc/openshell/certs/client.pem"
151+
guest_tls_key = "/etc/openshell/certs/client-key.pem"
152+
153+
[openshell.drivers.docker]
154+
network_name = "openshell-docker"
155+
# Skip the image-pull-and-extract step by pointing at a locally built binary.
156+
supervisor_bin = "/usr/local/libexec/openshell/openshell-sandbox"
157+
```
158+
159+
### Podman
160+
161+
Sandboxes run as Podman containers on a user-mode bridge network. The supervisor image is mounted read-only via Podman's `type=image` mount; guest mTLS material is supplied as host paths.
162+
163+
```toml
164+
[openshell]
165+
version = 1
166+
167+
[openshell.gateway]
168+
bind_address = "127.0.0.1:8080"
169+
log_level = "info"
170+
compute_drivers = ["podman"]
171+
172+
default_image = "ghcr.io/nvidia/openshell/sandbox:latest"
173+
supervisor_image = "ghcr.io/nvidia/openshell/supervisor:latest"
174+
guest_tls_ca = "/etc/openshell/certs/ca.pem"
175+
guest_tls_cert = "/etc/openshell/certs/client.pem"
176+
guest_tls_key = "/etc/openshell/certs/client-key.pem"
177+
178+
[openshell.drivers.podman]
179+
# Rootless socket path. For root Podman use /run/podman/podman.sock.
180+
socket_path = "/run/user/1000/podman/podman.sock"
181+
network_name = "openshell"
182+
stop_timeout_secs = 10
183+
image_pull_policy = "missing" # Podman vocabulary: always | missing | never | newer
184+
```
185+
186+
### MicroVM
187+
188+
Each sandbox runs inside its own libkrun microVM managed by the standalone `openshell-driver-vm` subprocess. Use this driver when you want stronger isolation than container namespaces alone.
189+
190+
```toml
191+
[openshell]
192+
version = 1
193+
194+
[openshell.gateway]
195+
bind_address = "127.0.0.1:8080"
196+
log_level = "info"
197+
# VM is never auto-detected; an explicit entry here is required.
198+
compute_drivers = ["vm"]
199+
200+
default_image = "ghcr.io/nvidia/openshell/sandbox:latest"
201+
guest_tls_ca = "/var/lib/openshell/guest-tls/ca.pem"
202+
guest_tls_cert = "/var/lib/openshell/guest-tls/client.pem"
203+
guest_tls_key = "/var/lib/openshell/guest-tls/client-key.pem"
204+
205+
[openshell.drivers.vm]
206+
state_dir = "/var/lib/openshell/vm"
207+
# Where the gateway looks for the openshell-driver-vm subprocess binary.
208+
driver_dir = "/usr/local/libexec/openshell"
209+
vcpus = 2
210+
mem_mib = 2048
211+
krun_log_level = 1
212+
```

docs/reference/sandbox-compute-drivers.mdx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ Common gateway options:
3232
| `--sandbox-image <image>` | `OPENSHELL_SANDBOX_IMAGE` | Set the default sandbox image used when a sandbox create request does not specify one. |
3333
| `--grpc-endpoint <url>` | `OPENSHELL_GRPC_ENDPOINT` | Set the gateway callback endpoint that sandbox workloads use to connect back to OpenShell. |
3434

35+
For the full file-based configuration surface — including gateway-wide settings, TLS, OIDC, and per-driver tables — see the [Gateway Configuration File](./gateway-config) reference. Each driver section below documents the CLI flags and environment variables; their TOML equivalents live in the `[openshell.drivers.<name>]` tables on that page.
36+
3537
Sandbox create supports `--cpu` and `--memory` for per-sandbox compute sizing.
3638
Docker and Podman apply them as runtime limits. Kubernetes applies them as both
3739
container requests and limits. The VM driver accepts the fields but currently

examples/gateway/docker.example.toml

Lines changed: 0 additions & 27 deletions
This file was deleted.

examples/gateway/gateway.example.toml

Lines changed: 0 additions & 89 deletions
This file was deleted.

0 commit comments

Comments
 (0)