Skip to content

Supervisor ConnectSupervisor and RelayStream RPCs rejected when OIDC is enabled without mTLS #1470

Description

@zanetworker

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:

constSANDBOX_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

  1. 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"
  2. Create a sandbox:

    openshell sandbox create --name test --no-auto-providers -- echo hello
  3. Observe: sandbox reaches Ready phase, supervisor connects repeatedly (each ConnectSupervisor returns 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:

constSANDBOX_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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions