How are secrets handled?
A deployed agent handles three kinds of credential, and they stay 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. HMAC_SECRET is the signing secret, the
value stackbone link and the registration wizard ask for. stackbone package
mints both into the deploy folder's .env for you, whichever target you package,
so keep that file. A box started without a signing secret mints one on its first
boot and prints it once in its log at warning level, the only time you can read
it. Set HMAC_SECRET yourself when a vault should decide it before the container
starts.
A self-host folder mints one more value beside those two:
STUDIO_STANDALONE_TOKEN, the token its bundled dashboard logs in with. Both
containers read the same line, and whoever holds the string holds the
deployment, so treat it like a root password:
a self-host box takes one operator token.
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
stackbone.secrets: the read surface and its error codes.stackbone secrets: listing, setting and removing them from the terminal.- Integrations: how the broker model keeps provider secrets out of your code.
- Connect your box: where the signing secret comes from and how it is proved.