Authoritative source: specs/platform/openshell-gateway.spec.md; specs/platform/openshell-gateway-sandbox-count.spec.md

Namespace-per-Gateway is the isolation and lifecycle boundary. The control plane owns the Kubernetes resources; the Gateway owns sandbox runtime state.

openshell-<gateway-id> tenant namespace --db-url, sslmode=require SSH :2222 gRPC gRPC Gateway PostgreSQL serverdatabase + role gw_id cert-manager Agent Sandbox controller OpenShell GatewayDeployment :8080 gRPC:8081 health · :9090 metrics Supervisor sidecar Sandbox 1 Sandbox 2 Sandbox N · dynamic openshell-gatewayClusterIP Service ConfigMapgateway.toml TLS Secretsserver + client CA JWT key Secret ServiceAccounts · RolesRoleBindings · SCC binding NetworkPolicies
View Mermaid source
graph TB
  subgraph NS[openshell-<gateway-id> tenant namespace]
    GW[OpenShell Gateway<br/>Deployment :8080 gRPC<br/>:8081 health · :9090 metrics]
    SUP[Supervisor sidecar]
    S1[Sandbox 1]
    S2[Sandbox 2]
    SN[Sandbox N · dynamic]
    SVC[openshell-gateway<br/>ClusterIP Service]
    CFG[ConfigMap<br/>gateway.toml]
    TLS[TLS Secrets<br/>server + client CA]
    JWT[JWT key Secret]
    RBAC[ServiceAccounts · Roles<br/>RoleBindings · SCC binding]
    NP[NetworkPolicies]
    GW --- SUP
    GW --> SVC
    GW --> CFG
    GW --> TLS
    GW --> JWT
    GW --> RBAC
    GW --> NP
    GW --> S1
    GW --> S2
    GW --> SN
    S1 -->|SSH :2222| GW
    S2 -->|gRPC| GW
    SN -->|gRPC| GW
  end
  DB[(Gateway PostgreSQL server<br/>database + role gw_id)]
  GW -->|--db-url, sslmode=require| DB
  CERT[cert-manager] -.-> TLS
  AGENT[Agent Sandbox controller] -.-> S1
  style NS fill:#f5f8fa
  style GW fill:#cce5ff
  style SUP fill:#fff3cd
  style DB fill:#d4edda
  style RBAC fill:#f8d7da
  style NP fill:#f8d7da

Edit this diagram in Craft Mermaid

Workspace mode: sandboxes run in per-workspace namespaces (default managed)

Newly provisioned gateways default to the OpenShell managed workspace mode: the gateway auto-creates one namespace per workspace (openshell-<gateway-id>-<workspace>, labeled openshell.ai/gateway-id) and runs that workspace's sandbox pods there with plain sandbox names, instead of packing every sandbox into the tenant namespace with <workspace>--<name> pod names (the shared mode legacy gateways keep). The control plane derives a per-gateway unique <gateway-id> (the hexadecimal suffix of the tenant namespace) so per-workspace namespaces never collide across gateways on one cluster, attributes managed-mode sandbox pods back to their gateway for active_sandbox_count, and deletes a deleted gateway's managed namespaces during gateway deletion cleanup. The mode is platform-managed: no caller can set or change it; the API server defaults it to managed at create, and legacy gateways (created before the field existed) keep the chart's shared behavior. See specs/platform/openshell-gateway.spec.md, "OSG-CORE-18 -- Gateway Workspace Mode".