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

# Profile variables

> CLI reference for vars — env variables stored on a profile and injected into every VM created with it, with optional write-only secrets.

<Warning>
  Profiles are an **experimental** feature. The `vars` commands are hidden by
  default — run `machine0 config set USE_EXPERIMENTAL_FEATURES=true` to enable
  them.
</Warning>

The `vars` commands manage the env variables stored on a [profile](/cli/profiles). They are stored encrypted and injected into every VM created with `machine0 new --profile <name>` — written to `/etc/environment` (services and non-login shells) and `/etc/profile.d/machine0-env.sh` (interactive sessions).

<Note>
  Not the same as [`machine0 env`](/cli/env): env sets are standalone,
  account-level groups of variables attached per VM with `--env <set>`. Profile
  variables ride along with everything else the profile injects (credentials,
  the MCP endpoint). A VM can use both.
</Note>

***

## vars ls

List a profile's variables. Secret values render masked.

```bash theme={"theme":"css-variables"}
machine0 vars ls <profile>
machine0 vars ls work --json
```

***

## vars set

Set env variables in a profile (`KEY=VALUE`, space-separated, values may contain `=`). Aliased as `vars add`.

```bash theme={"theme":"css-variables"}
machine0 vars set <profile> KEY=VALUE [KEY=VALUE ...] [--secret]
machine0 vars set work NODE_ENV=production API_URL=https://api.example.com
machine0 vars set work OPENAI_API_KEY=sk-... --secret
```

**Secret variables** — pass `--secret` to mark every key in that invocation as secret. Secret **values** are write-only: `vars ls` and `profiles get` (including `--json`) show them as `******** (secret)` and no API read ever returns them again — they stay readable only inside a VM (e.g. in `/etc/environment`). Key names and their existence remain visible, as for any variable. Details:

* Re-setting a key **without** `--secret` un-marks it (the new value displays in cleartext); re-setting with `--secret` keeps it masked.
* Masked `vars ls --json` output is **not round-trippable**: piping it back into `vars set` is rejected (it would overwrite the real value with the placeholder). The literal `********` can never be stored as a variable value.
* Variables set before this feature existed aren't retroactively masked — re-set them with `--secret` to mark them.

Two things to know when combining sources:

* **Precedence** — if a VM is created with both `--env <set>` and `--profile <name>` and they define the same key, **the env set wins** (it's the explicit per-machine choice).
* **When changes apply** — variables are written when a VM boots: at creation and on resume from suspend. A running VM does not pick up `vars set`/`unset` changes until its next suspend/resume cycle.

Profiles hold up to 100 variables (64KB serialized); keys are `[A-Za-z_][A-Za-z0-9_]*`, values up to 4096 characters with no newlines or double quotes. The combined variables of an env set and a profile attached to the same VM must also stay under 64KB.

***

## vars unset

Remove env variables from a profile by key. Unknown keys are ignored. Aliased as `vars rm`. Removal asks for confirmation — secret values are write-only, so a removed secret can't be recovered; pass `--yes` to skip the prompt (required in scripts).

```bash theme={"theme":"css-variables"}
machine0 vars unset <profile> KEY [KEY ...]
machine0 vars unset work API_URL
machine0 vars rm work API_URL --yes   # skip the confirmation prompt
```
