Skip to content

fix(sandbox): reserve gateway-internal Secrets from session secret_refs - #675

Merged
xiaods merged 1 commit into
mainfrom
fix/sandbox-secret-refs-reserve-gateway-keyring
Oct 27, 2026
Merged

xiaods merged 1 commit into
mainfrom
fix/sandbox-secret-refs-reserve-gateway-keyring

Conversation

@xiaods

@xiaods xiaods commented Oct 27, 2026

Copy link
Copy Markdown
Owner

CreateSession's validateSecretRefs only validated ref shape (count, required
fields, env-var name, duplicates), never the target Secret's name. Any
authenticated caller could pass the gateway's own key ring as an ordinary
secret_ref (--secret KEY=sandbox-apikeys:keys.json); resolveSessionEnv then
read it with the gateway SA's RBAC and injected the whole keys.json map into
the sandbox env, where a trivial printenv returned the entire API key ring
via Exec stdout — an authenticated caller escalating from "use a sandbox" to
"read the gateway's credential store."

Add a name-based gate at both layers:

- env.go: reservedSessionSecretNames + isSessionSecretRefAllowed() fails
  closed on empty names, on the reserved sandbox-apikeys Secret
  (case-insensitive), and on the reserved ring key "keys.json" under any
  Secret name. validateSecretRefs rejects at CreateSession with
  InvalidArgument.
- server.go: readSecretKey re-checks the same gate before the K8s Get, a
  fail-closed backstop for sessions that persisted a forbidden ref before
  the gate existed (upgrades).

The gate works by exclusion, so caller-managed Secrets (e.g.
--secret OPENAI_API_KEY=my-llm-secret:api_key) stay referenceable — no
allowlist of operator secrets to maintain or drift on.

Regression tests (verified to fail without the fix): CreateSession-level
rejection incl. the ring key under a caller-managed Secret name; exec-time
refusal with the ring seeded so only the gate can refuse (plus a
caller-managed Secret still resolving); and a legacy pre-gate session CRD
written directly, asserting resolution errors, yields nil env, and never
echoes ring material in the error.

Also documents the reservation in the SecretRef proto contract
(sandbox.pb.go regenerated with the repo's documented protoc invocation —
diff is the 4 comment lines only), the KIP-12 boundary table and
sensitive-value-hygiene section, and the SKILL.md security red lines.
@xiaods xiaods added the bug Something isn't working label Oct 27, 2026
@sonarqubecloud

Copy link
Copy Markdown

@github-actions

Copy link
Copy Markdown
Contributor

Test Results

1 046 tests  +3   1 019 ✅ +3   7m 5s ⏱️ +3s
  121 suites ±0      27 💤 ±0 
    1 files   ±0       0 ❌ ±0 

Results for commit baf6a2c. ± Comparison against base commit bc95325.

@xiaods
xiaods merged commit d06b5f0 into main Oct 27, 2026
9 checks passed
@xiaods
xiaods deleted the fix/sandbox-secret-refs-reserve-gateway-keyring branch October 27, 2026 06:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant