Repository navigation
Supervisor ConnectSupervisor and RelayStream RPCs rejected when OIDC is enabled without mTLS #1470
Description
Summary
When the gateway is configured with OIDC authentication and TLS disabled (disable_tls = true), the supervisor's ConnectSupervisor and RelayStream gRPC calls are rejected because they are not listed in SANDBOX_METHODS and the supervisor does not (by design) send an OIDC Bearer token.
This makes sandbox connect and any SSH relay fail with:
supervisor relay failed: status: Unavailable, message: "supervisor session not connected"
Root Cause
In crates/openshell-server/src/auth/oidc.rs, SANDBOX_METHODS exempts sandbox-to-gateway RPCs from OIDC Bearer validation:
const SANDBOX_METHODS: &[&str] = &[
"/openshell.v1.OpenShell/ReportPolicyStatus",
"/openshell.v1.OpenShell/PushSandboxLogs",
"/openshell.v1.OpenShell/GetSandboxProviderEnvironment",
"/openshell.v1.OpenShell/SubmitPolicyAnalysis",
"/openshell.sandbox.v1.SandboxService/GetSandboxConfig",
"/openshell.inference.v1.Inference/GetInferenceBundle",
];ConnectSupervisor and RelayStream are missing from this list.
In crates/openshell-sandbox/src/grpc_client.rs (line 88-91), the supervisor explicitly documents that it does not present a Bearer token:
Sandboxes authenticate to the gateway via the mTLS client certificate configured by
connect_channel. They do not present an OIDC Bearer token; the gateway recognises sandbox-class callers by absence of a Bearer header on the request.
In crates/openshell-server/src/multiplex.rs (line 339), when mTLS is the only auth mode (oidc_cache.is_none() && has_client_ca), all requests pass because the TLS handshake is sufficient. But when OIDC is configured, non-exempt methods without a Bearer token are rejected (line 367-374).
Reproduction
-
Deploy gateway with OIDC enabled and TLS disabled (Kubernetes driver):
[openshell.gateway] disable_tls = true [openshell.gateway.oidc] issuer = "http://keycloak.example.com/realms/openshell" audience = "openshell-cli"
-
Create a sandbox:
openshell sandbox create --name test --no-auto-providers -- echo hello
-
Observe: sandbox reaches
Readyphase, supervisor connects repeatedly (eachConnectSupervisorreturns HTTP 200 but the gRPC stream is rejected), SSH relay never establishes.
Environment
- Gateway: 0.0.44 (Helm chart, Kubernetes driver, OpenShift cluster)
- Supervisor: 0.0.44
- CLI: 0.0.43-dev
- Auth: OIDC (Keycloak), TLS disabled, LoadBalancer service (no proxy)
Proposed Fix
Add ConnectSupervisor and RelayStream to SANDBOX_METHODS:
const SANDBOX_METHODS: &[&str] = &[
"/openshell.v1.OpenShell/ReportPolicyStatus",
"/openshell.v1.OpenShell/PushSandboxLogs",
"/openshell.v1.OpenShell/GetSandboxProviderEnvironment",
"/openshell.v1.OpenShell/SubmitPolicyAnalysis",
"/openshell.sandbox.v1.SandboxService/GetSandboxConfig",
"/openshell.inference.v1.Inference/GetInferenceBundle",
"/openshell.v1.OpenShell/ConnectSupervisor", // supervisor session relay
"/openshell.v1.OpenShell/RelayStream", // SSH data plane
];Alternatively, these could be DUAL_AUTH_METHODS if CLI users also call them with Bearer tokens.
Activity