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

# Env vars & secrets

> Set environment variables and secrets once — boxd injects them into every machine you own.

Set environment variables and secrets **once**, at the account (or org) level, and boxd injects them into every machine you own — into login shells, into the environment your `boxd machine exec` commands and coding agents run in, and into services your machine starts at boot. No per-VM setup, no `.env` files to copy around.

There are two kinds:

|               | `boxd env`                | `boxd env … --secret`                       |
| ------------- | ------------------------- | ------------------------------------------- |
| For           | non-sensitive config      | tokens, API keys, passwords                 |
| At rest       | cleartext                 | **sealed**                                  |
| Readable back | yes — `list` shows values | **never** — `list` shows names + scope only |

Both are injected into your machines the same way (as environment variables). The difference is at rest: env var values are stored in cleartext and shown by `list`; secret values are sealed and never returned by the API — not even to you. To change a secret you re-`set` it.

Manage them from any boxd CLI — the [laptop CLI](/reference/external-cli) or the [in-VM CLI](/reference/internal-cli) — or from the console.

## Environment variables

```bash theme={"theme":"github-dark"}
boxd env set DATABASE_URL postgres://user:pass@db.example.com/app   # create or update
boxd env list                                                       # list (values shown; alias: ls)
boxd env rm DATABASE_URL                                            # remove (alias: remove)
```

## Secrets

```bash theme={"theme":"github-dark"}
boxd env set OPENAI_API_KEY sk-... --secret   # create or rotate (sealed at rest)
boxd env list                                 # secrets print as (sealed) — never the value (alias: ls)
boxd env rm OPENAI_API_KEY --secret           # remove (alias: remove)
boxd env scope OPENAI_API_KEY private         # move a secret to a different scope (value preserved)
```

Secrets are **write-only**: there's no `get`, and `list` never returns a value. Rotate one by running `set` again with the new value.

## Naming

Names must be valid environment identifiers (letters, digits, underscores; not starting with a digit). The `BOXD_*` prefix is reserved for boxd's own variables.

## Scope (in an org context)

When you're working in an [org context](/organizations/overview#working-in-an-org-context), `--scope` decides which of the org's machines receive the variable:

| Scope     | Applies to                             |
| --------- | -------------------------------------- |
| `shared`  | shared org machines only (**default**) |
| `private` | your private, org-billed machines only |
| `all`     | both                                   |

```bash theme={"theme":"github-dark"}
boxd env set API_BASE https://api.internal --scope all
boxd env set DEPLOY_KEY ... --scope private --secret
```

In your **personal** context the scope is always `all` (your personal machines) — the `--scope` flag is ignored. `boxd env scope <name> <scope>` moves an existing secret between scopes without re-entering its value.

## How they reach a machine

On boot — and on every login shell — boxd resolves the env vars and secrets in scope for that machine and exports them. So they're present for:

* interactive shells (`ssh <vm>.boxd`),
* `boxd machine exec` commands,
* the pre-installed coding agents, and
* services your machine starts at boot.

Add or rotate a value and new machines pick it up immediately; already-running machines see it on their next boot profile refresh.
