Skip to content

refactor: move secret values out of sandbox environment into supervisor-managed placeholders #112

@drew

Description

@drew

Summary

Secret values (provider credentials, inference route API keys, SSH handshake secret) are currently injected as plaintext environment variables into sandbox child processes. This means the agent process and anything it spawns has direct access to raw secret material via /proc/<pid>/environ or standard env var access.

We should restructure this so that the supervisor holds all secret values and the sandbox agent process only sees placeholder/reference values. The supervisor would intercept or mediate any operation that requires the real secret, keeping the actual credentials out of the agent's address space.

Current Behavior

  1. Provider credentials — Fetched by the supervisor via GetSandboxProviderEnvironment gRPC call, then injected directly as env vars into the child process (cmd.env(key, value) in process.rs:106-109) and SSH sessions (ssh.rs:565-637).

  2. Inference route API keys — Fetched via GetSandboxInferenceBundle, stored as ResolvedRoute.api_key in the sandbox process memory, and used by the proxy to replace outgoing Authorization/x-api-key headers.

  3. SSH handshake secret — Passed as NEMOCLAW_SSH_HANDSHAKE_SECRET env var in the pod spec, readable by the supervisor (intended) but also technically visible at the pod level.

Proposed Behavior

  1. Provider credentials — The supervisor should not inject real credential values into the agent's environment. Instead, inject placeholder values (e.g., ANTHROPIC_API_KEY=nemo-placeholder:provider:anthropic:api_key). The supervisor's proxy layer would intercept outgoing requests and swap placeholders for real values before forwarding.

  2. Inference route API keys — Already partially correct since the proxy strips and re-injects auth headers. Ensure the real API key never appears in the agent-accessible proxy config or memory space.

  3. SSH handshake secret — Keep this supervisor-only. Ensure it is not exposed to the agent process environment.

Key Files

  • crates/navigator-sandbox/src/process.rs — Child process env var injection
  • crates/navigator-sandbox/src/ssh.rs — SSH session env var injection
  • crates/navigator-sandbox/src/lib.rs — Supervisor startup, credential fetch orchestration
  • crates/navigator-sandbox/src/grpc_client.rs — gRPC calls to fetch credentials
  • crates/navigator-sandbox/src/proxy.rs — HTTP CONNECT proxy / inference interception
  • crates/navigator-server/src/sandbox/mod.rs — Pod spec construction, env var injection

Acceptance Criteria

  • Agent child processes do not have access to real secret values in their environment
  • Placeholder values are injected instead, following a consistent naming scheme
  • The supervisor mediates all secret usage (e.g., header injection in the proxy layer)
  • SSH handshake secret is not visible to the agent process
  • Existing provider and inference functionality continues to work end-to-end
  • Tests updated to cover placeholder injection and supervisor-mediated secret usage

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions