Secrets
Store API keys and tokens in the project's encrypted vault.
The Secrets tab is an encrypted vault for the credentials your connectors and Root Functions need — API keys, tokens, connection strings. Plaintext is shown to you once, on creation, and never again.
How it works
You enter a value → gateway seals it (sealed box) → stored as ciphertext
│
engine container ◀── provisioner unseals + injects as env var ──┘ (at spawn)- The gateway holds only the public sealing key. On write it produces a
ciphertext and stores it in
project_secrets. It cannot read secrets back. - The provisioner holds the private key. At container spawn it unseals each secret and injects it as an environment variable into your engine.
- The API never returns plaintext —
GETlists names,last_rotated_at, andcreated_atonly.
Full details: Secrets encryption.
Set, rotate, delete
| Action | Endpoint |
|---|---|
| Create | POST /v1/projects/{id}/secrets { name, plaintext } → returns metadata only |
| List | GET /v1/projects/{id}/secrets → names + timestamps |
| Delete | DELETE /v1/projects/{id}/secrets/{secret_id} |
To rotate, set a new value for the same name and restart the engine so the new value is injected.
Secrets apply at the next engine start
Because secrets are injected at spawn, adding or rotating a secret takes effect after the engine (re)starts — there is no live reload. Connectors you install account for this automatically.
In your code
Inside a Root Function, a secret named RESEND_API_KEY is available as
env.RESEND_API_KEY. The same name works locally (where the engine reads
~/.config/thinkingroot/secrets.toml via root secrets set) and in the cloud
(where the provisioner injects it) — so code is portable between the two. See
Root Functions.