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

# 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 theme={"system"}
  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 theme={"system"}
  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 theme={"system"}
  const result = await box.exec.command(
    'curl -s https://api.stripe.com/v1/charges?limit=1'
  )
  ```

  ```python box.py theme={"system"}
  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
