Compute Workspace
Vault
Per-workspace encrypted named secrets, the raw third-party API keys a skill's own code calls, injected into the sandbox env at run time.
What the vault is
The vault is a key-to-value secret store scoped to one business. Each entry is a free-form name (for example SERPER_API_KEY) and a value encrypted at rest with AES-GCM, using the same envelope every other per-business credential in the console uses. The plaintext never touches the table, only the ciphertext is stored.
These are not LLM or inference keys. They never go through the inference gateway. They are the raw provider keys a managed skill's own runtime code needs to authenticate directly to a third-party API, so, for example, the deep-research skill gets its SERPER_API_KEY without the key ever living in the gateway.
There is no CLI command for the vault. Secrets are managed from the console UI or the backend API below.
Store a secret
In the console, open the workspace and go to Vault, choose Set secret, and enter a name and value. Setting an existing name rotates its value in place. Values are write-only: once saved they are never shown again, the listing carries only the name, whether a value is present, and timestamps.
/api/v1/workspace/secrets| Parameter | Type | Description |
|---|---|---|
business_profile_idrequired | uuid | The business (workspace) the secret is scoped to. |
keyrequired | string | The secret name, e.g. SERPER_API_KEY. Unique per business; reusing a name rotates the value. |
valuerequired | string | The plaintext secret. Encrypted on store; never returned by any read path. |
curl -X PUT https://console.stimulir.com/api/v1/workspace/secrets \
-H "Authorization: Bearer <session-token>" \
-H "Content-Type: application/json" \
-d '{
"business_profile_id": "<workspace-id>",
"key": "SERPER_API_KEY",
"value": "<raw-provider-key>"
}'The response echoes the name, has_value, and timestamps, never the value you just sent.
List secrets
/api/v1/workspace/secrets?business_profile_id=<workspace-id>Returns one row per secret with its name, has_value, and created/updated timestamps. This path never decrypts and never returns a value.
curl https://console.stimulir.com/api/v1/workspace/secrets?business_profile_id=<workspace-id> \
-H "Authorization: Bearer <session-token>"Delete a secret
/api/v1/workspace/secrets/:key?business_profile_id=<workspace-id>| Parameter | Type | Description |
|---|---|---|
keyrequired | string | The secret name, in the path. |
business_profile_idrequired | uuid | The owning business (workspace), as a query parameter. |
curl -X DELETE \
"https://console.stimulir.com/api/v1/workspace/secrets/SERPER_API_KEY?business_profile_id=<workspace-id>" \
-H "Authorization: Bearer <session-token>"How skills consume secrets
A skill declares the vault names it needs in its SKILL.md frontmatter under required_secrets. When the skill runs, the console resolves those names against this workspace's vault, decrypts the present values in-process, and injects them into the sandbox env for that run only, so the skill's own code reads them as ordinary environment variables.
---
name: deep-research
description: Fan-out web research with adversarial verification.
required_secrets:
- SERPER_API_KEY
---Only declared names that are actually set are injected, a partially-configured vault still runs what it can, with missing names silently skipped. The decrypted plaintext stays in-process on its way to the sandbox env: it is never written to a response body, a log, or storage.
Values are never echoed back, not by the listing, not after saving, not to any agent. If you lose a secret, rotate it at the provider and set the new value; you cannot read the old one out of the vault.