stackbone secrets
stackbone secretstargets a running agent installation. With no--agentit uses the local-dev installation linked to the current project, sostackbone devmust be running. See target resolution. Every verb accepts--jsonand emits the standard envelope.
Manage environment-scoped secrets bound to the targeted installation.
The CLI has no reveal verb: it never prints a plaintext value, on any verb
or in any output mode. Reading a stored secret back is a human-only action in
Studio. That rule holds across the whole CLI; see
secrets are never printed.
set is idempotent on the name (create and rotate are the same call).
| Command | Purpose |
|---|---|
stackbone secrets list |
List secret names (values always masked) and their last-rotated time. |
stackbone secrets set <name> |
Create or rotate a secret. Value from --value <v> or stdin; --description. |
stackbone secrets remove <name> |
Delete a secret. Requires --yes. |
remove is destructive and refuses to run without --yes, described under
destructive verbs.
A name is SHOUTY_SNAKE_CASE. It starts with an uppercase letter, then
carries uppercase letters, digits and underscores, up to 128 characters. A value
is at most 4 KiB, and a --description at most 256 characters.
When set refuses a name or a value, it names the field. It prints one
sentence, then one indented field: rule line per offending field. Three lines
at most, then a (+N more) count for the rest:
$ stackbone secrets set openai_api_key --value sk-...
stackbone: The secret is not valid.
- name: secret name must be SHOUTY_SNAKE_CASE (A-Z, 0-9, _)
→ Fix the field(s) above and run the command again.Those lines read the same whether the CLI caught the problem before the request
or the installation refused the body. Under --json the whole text rides in
error.message, and either way the command exits 1. A refusal the CLI caught
itself carries the error.code invalid_input.
set and remove reject any name that starts with STACKBONE_, and these as
well: DATABASE_URL,
AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, S3_ENDPOINT, S3_BUCKET,
MODEL_PROVIDER_API_KEY, MODEL_PROVIDER_BASE_URL, OPENROUTER_API_KEY,
OPENROUTER_BASE_URL, BROWSER_MODE, BROWSERBASE_API_KEY,
BROWSERBASE_PROJECT_ID. The install owns them. The runtime injects them
itself, and an operator writes the model provider and the browser provider from
their own Studio screens. list leaves them out too.
JSON payload
// secrets list: value_preview is a mask, never the plaintext
{
"schema_version": 1,
"items": [
{
"name": "OPENAI_API_KEY",
"description": "Billing account key",
"value_preview": "••••••",
"created_by_email": "[email protected]",
"created_at": "2026-05-20T09:00:00Z",
"last_rotated_at": "2026-06-01T10:00:00Z",
},
],
}
// secrets set: the same masked row, one level down under `secret`
{
"schema_version": 1,
"secret": {
"name": "OPENAI_API_KEY",
"description": "Billing account key",
"value_preview": "••••••",
"created_by_email": "[email protected]",
"created_at": "2026-05-20T09:00:00Z",
"last_rotated_at": "2026-06-05T11:30:00Z",
},
}
// secrets remove
{ "schema_version": 1, "name": "OPENAI_API_KEY", "status": "deleted" }Note
A deployed box locks each secret with the per-agent STACKBONE_SECRET_KEY in
its .env, the same key the agent decrypts with. See
what you set on the deployed container.
A box running an image older than CLI 0.3.3 wrote them under a different key,
so the agent read them as missing. You cannot recover those values: set them
again once the box runs a 0.3.3 image or newer. stackbone dev never had this
problem.
Exit codes: 0 ok · 4 not found (unknown secret, or a name remove
cannot parse) · 5 permission (remove without --yes) · 1 generic (empty
value, a set name or value that breaks a shape rule, a reserved name).
See exit codes.