Skip to content

Sandbox can read Zero's own OAuth and provider credential stores #675

Description

@PierrunoYT

Summary

Sandboxed commands use a read-all/write-restricted filesystem posture, but the default credential deny list only covers ~/.aws, ~/.config/gcloud, ~/.azure, and the GOOGLE_APPLICATION_CREDENTIALS target. Zero's own credential-bearing files remain readable.

This exposes:

  • the default plaintext OAuth store at ~/.config/zero/oauth-tokens.json
  • credentials.json when plaintext provider-key storage is selected
  • both credentials.enc and its adjacent .secret AES key
  • user config.json, which can contain inline apiKey, authHeaderValue, and secret customHeaders

Relevant code

  • internal/sandbox/profile.go: permissionProfileReadRoots starts with the filesystem root; credentialDenyReadPaths does not include Zero files.
  • internal/oauth/store.go: the default storage case is the plaintext file backend.
  • internal/credstore/credstore.go: encrypted storage uses credentials.enc with securefile.NewCrypter(path + ".secret").
  • internal/config/types.go: provider profiles can persist inline keys and credential-bearing headers.

Observed at commit 6fc1220.

Impact

Environment scrubbing does not protect credentials stored on disk. Reading both the encrypted provider store and its co-located key is equivalent to reading plaintext.

Suggested fix

  1. Add exact default deny-read entries for user config.json, OAuth/MCP token stores, credentials.json, credentials.enc, and its .secret.
  2. Include overridden token-store locations.
  3. Add platform integration tests that attempt sandboxed reads of each store.

Metadata

Metadata

Assignees

No one assigned

    Labels

    issue-approvedReviewed and approved by the core team; community PRs may implement this issue.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions