Secrets
Store values that reach the machine but never come back, and that a captured disk never carries.
Set
await machine.secrets.set("GITHUB_TOKEN", token);machine.secrets.set("GITHUB_TOKEN", token)A name must be an uppercase environment variable name — ^[A-Z_][A-Z0-9_]*$. Accepting a name a
guest cannot export would store a secret that silently never arrives. Values are up to 64 KB and
are stored encrypted.
Setting an existing name replaces the value and bumps its version, so you can tell a change from
a no-op.
A stored value is never returned
There is no read method, and the response shape has no field a value could travel in. That is not an omission: a product that can hand a secret back is a product whose secrets are in every response log, error report and browser cache that ever touched one.
for await (const s of machine.secrets.list()) {
console.log(s.name, s.version, s.delivered_at);
}for s in machine.secrets.list():
print(s["name"], s["version"], s["delivered_at"])delivered_at is null when a secret is stored and not yet delivered — the normal state for one set
on a machine that is not running. It lands on the next boot; a running machine takes delivery
within seconds.
Reading them inside the machine
Secrets arrive at /run/computer/secrets.env, mode 0600, and a login shell sources them:
const { stdout } = await machine.terminal.execShell("echo $GITHUB_TOKEN");stdout = machine.terminal.exec_shell("echo $GITHUB_TOKEN")["stdout"]/run is a tmpfs, which is the entire point: a disk capture cannot contain what was never on the
disk. A snapshot, fork or template does not carry a secret, and a machine
that restarts takes delivery again from storage.
Delete
await machine.secrets.delete("GITHUB_TOKEN");machine.secrets.delete("GITHUB_TOKEN")Removes it from storage and from the running machine. It cannot remove a copy the guest already made — a process that read the value and wrote it elsewhere still holds it. Revoking at the source is this product’s half; rotating at the issuer is yours.
Deployment requirement
Secrets need an encryption keyring configured. Without one the API raises unsupported_operation
rather than storing a value in a form it could be read back from.
Secrets versus the browser profile
The two are deliberately opposite, and picking the wrong one is the common mistake:
| Carried by a capture? | Use for | |
|---|---|---|
| A browser session | yes | a login every future machine should inherit |
| A secret | no | a credential that must not end up in a captured disk |