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

# Environment variables

> Plain variables for every shell in a machine, and where secrets go instead.

Set plain environment variables for the whole machine when you create it. Every login shell (`exec`,
SSH, the dashboard terminal) exports them, and so does every process those shells start. The variables
are there from the first command, and again after each start and resume.

```bash theme={null}
instabox create --name api --env NODE_ENV=production --env REGION=us-west-2
instabox create --name api --env-file ./app.env      # KEY=VALUE lines; - reads stdin; --env wins for the same name
instabox exec api --env NODE_ENV=test -- npm test    # for one command only
```

Over the API, send `"env": {"NODE_ENV": "production"}` in `POST /v1/machines`.

> [!WARNING]
>
> **Not for secrets.** Every process and user in the machine can read the values (`env`,
> `/run/instabox/env/env`), and so can anyone who can run a command in it. For an API key you want kept
> out of the machine, use [Org Secrets](https://instabox.sh/docs/security/secrets.md).

## How it works

* **Fixed at create.** A fork gets its source's variables. A machine created from a snapshot gets only
  the ones in its own create request.
* **What wins.** An exec's own `envs` (`--env`) win for that command. A Vault item or env Secret with
  the same name also wins over a machine variable.
* **Names only.** `instabox get --json` (`GET /v1/machines/{id}`) lists the names as `envNames`, never
  the values. The values are stored encrypted at rest.
* **Not for boot services.** Services that systemd starts at boot do not run a login shell, so they do
  not get the variables. Such a service can read `/run/instabox/env/env` itself.

> [accordion] Limits and refused names
>
> Names match `^[A-Za-z_][A-Za-z0-9_]{0,127}$`, up to 128 variables and 32 KiB in all. macOS and Windows
> machines take no env (`400 bad_request`). These names are refused with `400 bad_request`:
>
> * Set by the login shell: `PATH`, `HOME`, `USER`, `LOGNAME`, `SHELL`, `PWD`, `OLDPWD`, `SHLVL`,
>   `HOSTNAME`, `IFS`, `ENV`, `BASH_ENV`. Set them for one command with exec's `envs` (`--env`) instead.
> * Bash's readonly variables: `UID`, `EUID`, `PPID`, `SHELLOPTS`, `BASHOPTS`, `BASH_VERSINFO`.
> * Set by each session: `TERM`, `XDG_RUNTIME_DIR`, `DBUS_SESSION_BUS_ADDRESS`, and names starting
>   `SSH_`.
> * Names starting `INSTABOX_`.
> * The trust roots Org Secrets manage: `SSL_CERT_FILE`, `SSL_CERT_DIR`, `REQUESTS_CA_BUNDLE`,
>   `CURL_CA_BUNDLE`, `NODE_EXTRA_CA_CERTS`.

## Keep credentials in Org Secrets

Use [Org Secrets](https://instabox.sh/docs/security/secrets.md) for named credentials shared within an org. A machine sees
placeholders, and the outbound proxy adds the credentials to HTTPS headers sent to each Secret's
allowed hosts. Manage the values, and which machines get them, on the dashboard's **Secrets** page, in
the CLI, or over the API.

## Vault

The per-user Vault still supports environment variables, home files, and metadata selectors alongside
Org Secrets. Manage its items with `instabox vault set`, `set-file`, `import`, `ls`, `rm`, `show`, and
`push`.

> [!NOTE]
>
> Upgrading does not move Vault items into Org Secrets or enroll existing machines in Secrets.

> [card] [Org Secrets](https://instabox.sh/docs/security/secrets.md)
>
> Credentials a machine sees only as placeholders.

> [card] [Sizes and create options](https://instabox.sh/docs/machines/sizes.md)
>
> Every field create takes, `env` included.
