boxd machine exec commands and coding agents run in, and into services your machine starts at boot. Every machine picks the values up on its own, without .env files to copy around.
There are two kinds:
Both are injected into your machines the same way. The difference is what happens 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 the CLI, the in-VM CLI, or the console.
Environment variables
Secrets
Secrets bound to a host
A secret can be bound to the hosts it may be sent to. The machine then only holds an opaquebxds_… placeholder, and the real value is inserted into requests to those hosts on the way out, never anywhere else. It is set from the SDK:
- Nothing running inside can read it, log it, or send it elsewhere. Not an agent, not a prompt injection, not a compromised dependency.
env, shell history, and agent transcripts only ever contain the placeholder. - The placeholder is useless anywhere else. Sent to any host you did not name, it is a meaningless string.
- Rotating the value does not change the placeholder, so nothing inside needs to restart or know.
Host-bound secrets
A secret can be bound to the hosts it may be sent to. The machine then only ever holds a placeholder. The real value is substituted into requests to those hosts on the way out, and nowhere else.STRIPE_KEY is an opaque bxds_... string. A request to api.stripe.com carrying it, in a header, the query, the body or Basic auth, arrives at Stripe with the real key. A request anywhere else carries the useless placeholder. There is nothing to configure in the machine, the placeholder does not change when the value is rotated, and a process with root in the machine still cannot read the real value.
--domains takes hostnames or wildcards such as *.stripe.com, comma-separated or repeated. Provider-wide wildcards such as *.amazonaws.com are refused. The hosts of a bound secret are always reachable from the machine, on top of any egress allowlist it has.
The console offers the same on the Secrets page, as a hosts field on a secret and a Hosts column in the list, and the SDKs take domains on secrets.set. In the SDKs the list you pass is the complete set, so pass it again when rotating a value.
Naming
Names must be valid environment identifiers, made of letters, digits, and underscores, starting with a letter or an underscore. TheBOXD_* prefix is reserved for boxd’s own variables.
Scope
The--scope flag decides which of the org’s machines receive the variable:
How they reach a machine
On boot, and again 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 execcommands,- the pre-installed coding agents, and
- services your machine starts at boot.
exec and SSH sessions only, never at boot.