# Attach Headers

`attachHeaders` lets you inject HTTP headers into outbound HTTPS requests from a box without the secrets ever entering the container. This is useful for API keys, bearer tokens, and other credentials that should not be readable by code running inside the box.

## How it works

When a box is created with attach headers, a TLS-intercepting proxy on the host injects the configured headers into outbound HTTPS requests that match the configured host patterns.

- The secrets stay on the host
- They do not appear in environment variables, files, or process memory inside the container
- Traffic to hosts that do not match any rule passes through untouched

## Global attach headers

You can configure attach headers at the user or team level in the console Settings tab under **Attach Headers**. These global headers are applied automatically to new boxes.

When a box is created, global and per-box headers are merged:

- Per-box headers override global headers for the same host pattern
- Global headers for host patterns not specified per-box are included as-is

## Per-box attach headers

You can also configure attach headers per box with the SDK:

<CodeGroup>
```typescript box.ts
const box = await Box.create({
  runtime: "node",
  attachHeaders: {
    "api.stripe.com": {
      Authorization: "Bearer sk_live_...",
    },
    "*.supabase.co": {
      apikey: "eyJ...",
    },
    "api.anthropic.com": {
      "x-api-key": "sk-ant-...",
    },
  },
})
```

```python box.py
box = Box.create(
    runtime="node",
    attach_headers={
        "api.stripe.com": {
            "Authorization": "Bearer sk_live_...",
        },
        "*.supabase.co": {
            "apikey": "eyJ...",
        },
        "api.anthropic.com": {
            "x-api-key": "sk-ant-...",
        },
    },
)
```
</CodeGroup>

Any HTTPS request from inside the box to a matching host will automatically include the configured headers.

<CodeGroup>
```typescript box.ts
const result = await box.exec.command(
  'curl -s https://api.stripe.com/v1/charges?limit=1'
)
```

```python box.py
result = box.exec.command(
    "curl -s https://api.stripe.com/v1/charges?limit=1"
)
```
</CodeGroup>

The `Authorization` header is added by the proxy. The container never sees the secret itself.

## Host patterns

| Pattern | Matches |
|---|---|
| `api.stripe.com` | Exact match only |
| `*.supabase.co` | Any subdomain such as `xyz.supabase.co` or `db.supabase.co` |

- Patterns must be lowercase
- Only `*.` prefix wildcards are supported
- Most-specific match wins

## When to use attach headers vs env vars

| | Environment Variables | Attach Headers |
|---|---|---|
| **Visibility** | Visible to all code in the box | Never enters the container |
| **Use case** | Non-sensitive config, or when you trust all code in the box | API keys, tokens, credentials for untrusted code |
| **SDK compatibility** | Works with any SDK that reads from env | Works with any SDK that makes HTTPS requests |
| **Setup** | Pass in `env` | Pass in `attachHeaders` with host patterns |

## Limitations

- Attach headers are set at box creation time after merging global and per-box values
- They are not updated on a running box
- Only HTTPS traffic on port `443` is intercepted
- HTTP/2 connections through matched hosts are downgraded to HTTP/1.1
- Header values are encrypted at rest and never returned by API responses
