Environment variables are the standard way to pass secrets (API keys, database passwords, tokens) to sandbox workloads. Declaw provides two mechanisms for protecting these secrets: masking patterns that prevent sensitive values from appearing in audit logs, and SecureEnvVar markers that prevent secrets from being returned in get_info() responses.
Passing environment variables
sbx = Sandbox.create(
envs={
"OPENAI_API_KEY": "sk-...",
"DATABASE_URL": "postgres://user:password@host/db",
"ANTHROPIC_API_KEY": "sk-ant-...",
}
)
The variables are available inside the sandbox:
result = sbx.commands.run("echo $OPENAI_API_KEY")
# Returns the actual value — it's accessible inside the sandbox
result = sbx.commands.run("python3 -c 'import os; print(os.getenv(\"OPENAI_API_KEY\"))'")
EnvSecurityConfig
EnvSecurityConfig controls how secrets behave in logs and API responses.
from declaw import Sandbox, SecurityPolicy, EnvSecurityConfig
sbx = Sandbox.create(
envs={"OPENAI_API_KEY": "sk-...", "TEMP_VAR": "visible"},
security=SecurityPolicy(
env=EnvSecurityConfig(
mask_patterns=["*_KEY", "*_SECRET", "*_TOKEN", "*_PASSWORD"],
)
)
)
EnvSecurityConfig model
| Field | Type | Default | Description |
|---|
mask_patterns | list[str] | [] | Glob patterns for variable names to mask in audit logs |
secure_vars | list[SecureEnvVar] | [] | Variables to mark as secret (excluded from get_info()) |
Default masked patterns
Declaw automatically masks variables matching these patterns in audit logs, even without explicit configuration:
*_KEY
*_SECRET
*_TOKEN
*_PASSWORD
This means OPENAI_API_KEY, DATABASE_PASSWORD, and similar variables will not appear in audit log entries in plaintext.
SecureEnvVar
SecureEnvVar marks specific variables as secrets. Secret variables are passed to the sandbox but:
- Never returned in
get_info() or list() responses
- Never logged in plaintext in audit entries
- Not visible through the API after creation
from declaw import Sandbox, SecurityPolicy, EnvSecurityConfig, SecureEnvVar
sbx = Sandbox.create(
envs={
"OPENAI_API_KEY": "sk-...",
"MY_VISIBLE_VAR": "hello",
},
security=SecurityPolicy(
env=EnvSecurityConfig(
secure_vars=[
SecureEnvVar(name="OPENAI_API_KEY"),
]
)
)
)
info = sbx.get_info()
# info.envs will not contain OPENAI_API_KEY
# info.envs will contain MY_VISIBLE_VAR
SecureEnvVar model
| Field | Type | Description |
|---|
name | str | Exact name of the environment variable to protect |
Per-command environment variables
You can pass additional environment variables at the command level. These are also subject to masking rules.
result = sbx.commands.run(
"python3 script.py",
envs={
"TEMP_API_KEY": "sk-temp-...", # masked in audit logs
"DEBUG": "true", # visible in logs
}
)
Preventing credential exfiltration
Environment variables alone cannot prevent a compromised agent from exfiltrating secrets via outbound traffic. Use network policies and transformation rules to add defense-in-depth:
from declaw import Sandbox, SecurityPolicy, NetworkPolicy, TransformationRule, ALL_TRAFFIC
policy = SecurityPolicy(
# Only allow traffic to the intended API
network=NetworkPolicy(
allow_out=["api.openai.com"],
deny_out=[ALL_TRAFFIC],
),
# Strip any API key values from outbound request bodies
transformations=[
TransformationRule(
direction="outbound",
match=r"sk-[A-Za-z0-9]{20,}",
replace="[API_KEY_REDACTED]",
),
],
env=EnvSecurityConfig(
mask_patterns=["*_KEY", "*_SECRET"],
),
audit=True,
)
sbx = Sandbox.create(
envs={"OPENAI_API_KEY": "sk-..."},
security=policy,
)
In this configuration:
- The sandbox can only reach
api.openai.com
- Any
sk-* pattern in outbound request bodies is stripped before transmission
- Audit logs mask the key name
- All blocked connections are logged
Environment variables are accessible to all processes running inside the sandbox. If you run untrusted code inside a sandbox, the code can read OPENAI_API_KEY from its environment. The network policy and transformation rules above prevent the key from being exfiltrated, but the code can still read the key value.
Auto-injected Declaw variables
These variables are always present and cannot be masked:
| Variable | Value |
|---|
DECLAW_SANDBOX_ID | The sandbox’s unique ID |
DECLAW_TEMPLATE_ID | The template used to create the sandbox |
DECLAW_SANDBOX | "true" |
DECLAW_SECURITY_POLICY | JSON of the active security policy |