How are secrets handled?

A deployed agent handles three kinds of credential, and they are kept apart. Your agent's own secrets, the third-party credentials a connector uses, and the two keys the container itself runs on.

An operator registers agent secrets, in Studio or from the terminal with stackbone secrets set NAME, and your agent's own database holds them encrypted. stackbone.secrets.get(name) reads them straight out of that database and decrypts locally with the per-agent key the runtime injects. There is no control-plane round trip, and the ciphertext at rest never leaves your agent. Values are not cached, so a rotation lands on the next read. Pass the value to the downstream client and never log it.

The CLI never reveals a value: stackbone secrets list prints names only, set is idempotent on the name (so it doubles as rotation), and remove wants --yes.

Third-party credentials go through Stackbone Connect instead. The operator installs a connection once, and a broker mints short-lived, install-scoped tokens for each call, so your agent code never sees the provider's secret.

Two keys belong to the container itself. STACKBONE_SECRET_KEY encrypts every secret the runtime stores. Keep it stable: changing it makes everything already stored unreadable, with no recovery. stackbone package mints one into the deploy folder's .env for you, so keep that file. The box mints the signing secret on its first boot and prints it once in its log at warning level. That is the value stackbone link asks for. Set HMAC_SECRET yourself when a vault should decide it before the container starts.

Note

Before CLI 0.3.3, a deployed box wrote secrets under a different key than the one the agent decrypts with, so stackbone.secrets.get() returned secrets_decrypt_failed for a secret that was there. Both sides now use the same per-agent STACKBONE_SECRET_KEY. You cannot recover anything written under the old key: set those secrets again after you upgrade.

Read more

BUILT WITH ❤️ FROM CANADA AND SPAIN