> ## Documentation Index
> Fetch the complete documentation index at: https://docs.declaw.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Environment Secrets

> Pass secrets to sandboxes securely using EnvSecurityConfig and SecureEnvVar to prevent leakage in logs and outbound traffic.

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.

<Note>
  **For the strongest isolation, use the [Credential Vault](/security/credential-vault) instead.** With env secrets the real value still lives *inside* the VM (these mechanisms only keep it out of logs and API responses). With the vault, the value never enters the VM at all — the sandbox sees only a `declaw:vault-managed` placeholder and the real credential is injected at the egress proxy, per allowed domain. Reach for env secrets when a process genuinely needs the value in-process; reach for the vault when the agent only needs to *make authenticated requests*.
</Note>

## Passing environment variables

```python theme={null}
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:

```python theme={null}
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.

```python theme={null}
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

```python theme={null}
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.

```python theme={null}
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:

```python theme={null}
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:

1. The sandbox can only reach `api.openai.com`
2. Any `sk-*` pattern in outbound request bodies is stripped before transmission
3. Audit logs mask the key name
4. All blocked connections are logged

<Warning>
  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.
</Warning>

## 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      |
