CDX-301b · Module 2
Environment Variables & Secrets in the Sandbox
3 min read
Secrets management inside the Codex sandbox requires understanding three attack surfaces: environment variable exposure, command output capture, and file content reads. Environment variables set in your shell are inherited by Codex sessions — including API keys, database credentials, and tokens. Commands Codex runs can echo these values, and the output becomes part of the conversation context sent to the API. File reads of .env, credentials.json, or similar files have the same effect.
The defense-in-depth strategy for secrets has four layers. First, minimize the environment: launch Codex from a minimal shell that only exports the variables it needs. Second, scope MCP secrets: use the env block in config.toml to give each MCP server only its required secrets. Third, add AGENTS.md rules: explicitly forbid reading or displaying secret files. Fourth, use the sandbox: workspace-write mode prevents Codex from modifying credential files, even if it can read them.
#!/bin/bash
# Launch Codex with a minimal environment
# Only export what Codex actually needs
# Clear inherited secrets
unset AWS_SECRET_ACCESS_KEY
unset DATABASE_URL
unset GITHUB_TOKEN
# Set only what Codex needs
export OPENAI_API_KEY="${OPENAI_API_KEY}"
export PATH="/usr/local/bin:/usr/bin:/bin"
export HOME="${HOME}"
export CODEX_PROFILE="dev"
# Launch with explicit environment
exec codex "$@"
# For CI, use GitHub Actions secrets:
# env:
# OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
# No other secrets exposed to the Codex step
Do This
- Launch Codex from a minimal environment with only required variables
- Scope MCP secrets to individual servers via config.toml env blocks
- Add exec policy deny rules for env, printenv, and echo of variables
- Use a secrets manager (1Password CLI, AWS SSM, Vault) instead of .env files
Avoid This
- Inherit your full development environment into Codex sessions
- Store secrets in .env files inside the project directory where Codex can read them
- Assume the sandbox prevents secrets from being read — it only prevents writes
- Give MCP servers access to secrets they do not need via broad env blocks