Vault — your secrets are yours.
AES-256-GCM with HKDF-derived per-project keys. Versioned and audit-logged. The agent_ids field is an intra-project label check, not proof that a particular identity made the call.
Default values are server-encrypted, not end-to-end encrypted. The running service derives their keys and can read them. Use agent_encrypted=true only when your client supplies ciphertext the server should not decrypt.
Model
- Per-project derived key. HKDF derives it from one platform-wide
VAULT_MASTER_KEYplus the project ID and fixedvault-v1context. There is no epoch rotation. Compromise of the platform master can expose all default server-encrypted vault values. - Versioned secrets. Every
PUTcreates a new version. Previous versions stay readable until explicitly deleted. - Access label. For HTTP reads,
agent_idsis compared with a caller-suppliedX-Agent-Idunder a project-root bearer. It is not identity-signature authentication. Hosted runtime reads currently bypass this check and the per-secret read audit. - Server-side at-rest encryption. Vault value columns store ciphertext. The running service receives plaintext for default-mode writes and reads and derives keys from
VAULT_MASTER_KEY; this is not end-to-end opacity or a whole-host no-plaintext guarantee.
Endpoints
Store or update a secret. Each PUT increments the version. Subsequent GETs return the latest unless ?version= is specified.
| Field | Type | Description |
|---|---|---|
| valuerequired | string | The plaintext secret. Encrypted server-side before write. |
| tagsoptional | string[] | Searchable tags — e.g. ["openai", "production"]. |
| descriptionoptional | string | Human-readable note. Surfaces in the wake's you_keep. |
| agent_idsoptional | uuid[] | HTTP read labels accepted through X-Agent-Id. Empty = any caller holding the project bearer. This does not authenticate the named identity. |
| rotation_due_atoptional | timestamptz | Optional rotation reminder. Surfaces in the wake. |
curl -X PUT https://api.agenttool.dev/v1/vault/openai-key \
-H "Authorization: Bearer $AT_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"value": "sk-...",
"tags": ["openai", "production"],
"description": "OpenAI API key for embeddings"
}'
Read a secret. Returns the current version unless ?version=N is passed. Each read appends to the audit log.
List secret names + metadata only. Values are never returned by list. Filter by tag.
Soft-delete the secret. The row and stored version ciphertext remain in the database; values are not zeroed.
List all versions of a secret with their write timestamps. Pair with GET ?version=N for rollback.
Ordinary access-log rows for HTTP vault operations: supplied agent_id, time, action, and success or denial. Rows are not signed, hash-chained, or database-immutable; hosted runtime reads are not recorded here.
Update the HTTP label policy without rotating the value. agent_ids relies on X-Agent-Id supplied by a project-root bearer.
Bulk operations
Atomic multi-secret write. Use for migrations and provisioning.
Vault and execute are separate
/v1/execute is disabled by default and does not inject vault values. Do not embed a project bearer or private provider key in hosted execute source, even when an operator explicitly enables the unsafe legacy path. Read the current process and network boundary at /public/safety.
Fetch and decrypt a secret on infrastructure you control and call the provider there. The optional legacy Python and bash path can make outbound calls from AgentTool infrastructure, so its code, traffic, and process memory are not an agent-only privacy boundary.
What to read next
- /v1/execute — disabled-by-default legacy host execution with no vault injection or tenant boundary.
- Memory: bring your own embeddings — compute embeddings on your chosen substrate, then store them.