Vault Quickstart
Get an API key, store a secret, fetch it back. No sign-up, no credit card, no waiting.
Prerequisites: curl, and either Node 18+, Bun, or Deno.
Step 1: Get an API key
No form. No email. One request.
curl -s -X POST https://api.agentlair.dev/v1/auth/keys
Response:
{
"api_key": "al_live_abc123...",
"backup_key": "al_bak_xyz789...",
"created_at": "2026-03-27T12:00:00Z"
}
Save both keys. The api_key is your primary credential. The backup_key is your recovery credential if you lose the primary. Neither can be retrieved again — if you lose them, you’ll need to create a new account.
# Save to environment
export AL_KEY="al_live_abc123..."
Step 2: Install the crypto library
# Bun
bun add @agentlair/vault-crypto
# npm
npm install @agentlair/vault-crypto
# pnpm
pnpm add @agentlair/vault-crypto
Why a library? Vault is zero-knowledge — encryption happens client-side before anything reaches the network. The library handles HKDF key derivation and AES-256-GCM encryption using the Web Crypto API (no native deps, works everywhere).
Step 3: Generate a seed
The seed is your 32-byte root key. All vault keys are derived from it. Back it up — if you lose the seed, your encrypted secrets are unrecoverable.
import { VaultCrypto } from '@agentlair/vault-crypto'
// Generate a random seed (do this once per agent)
const seed = VaultCrypto.generateSeed()
const vc = VaultCrypto.fromSeed(seed)
// Print the hex seed — save this somewhere safe
console.log('VAULT_SEED=' + vc.seedHex())
// VAULT_SEED=a3f1d7c2... (64 hex chars = 32 bytes)
Where to store the seed:
- Environment variable (
VAULT_SEED) in your agent’s runtime - A passphrase-encrypted backup in Vault itself (see Concepts → Seed backup)
- A secrets manager for your infrastructure (ironic but valid)
Step 4: Encrypt and store a secret
import { VaultCrypto } from '@agentlair/vault-crypto'
const vc = VaultCrypto.fromSeed(process.env.VAULT_SEED!)
// Encrypt the secret client-side
const ciphertext = await vc.encrypt('sk-proj-abc123-your-openai-key', 'openai-key')
// Store the ciphertext in Vault
const response = await fetch('https://api.agentlair.dev/v1/vault/openai-key', {
method: 'PUT',
headers: {
'Authorization': 'Bearer ' + process.env.AL_KEY,
'Content-Type': 'application/json',
},
body: JSON.stringify({ ciphertext }),
})
const result = await response.json()
console.log(result)
// { key: 'openai-key', stored: true, version: 1, ... }
The server receives ciphertext: "aeGx8kF..." — an opaque blob it cannot decrypt.
Step 5: Fetch and decrypt
import { VaultCrypto } from '@agentlair/vault-crypto'
const vc = VaultCrypto.fromSeed(process.env.VAULT_SEED!)
// Fetch the ciphertext from Vault
const response = await fetch('https://api.agentlair.dev/v1/vault/openai-key', {
headers: { 'Authorization': 'Bearer ' + process.env.AL_KEY },
})
const { ciphertext } = await response.json()
// Decrypt locally
const apiKey = await vc.decrypt(ciphertext, 'openai-key')
console.log(apiKey)
// sk-proj-abc123-your-openai-key
The decryption key is derived from your seed locally — the plaintext never touches the network.
Full example (TypeScript)
import { VaultCrypto } from '@agentlair/vault-crypto'
const API_BASE = 'https://api.agentlair.dev'
async function main() {
// --- Setup (run once per agent) ---
// 1. Create account
const { api_key } = await fetch(`${API_BASE}/v1/auth/keys`, { method: 'POST' })
.then(r => r.json())
// 2. Generate seed
const vc = VaultCrypto.fromSeed(VaultCrypto.generateSeed())
console.log('Save this seed:', vc.seedHex())
// --- Normal operation ---
// 3. Store a secret
const ciphertext = await vc.encrypt('my-secret-value', 'my-key')
await fetch(`${API_BASE}/v1/vault/my-key`, {
method: 'PUT',
headers: { 'Authorization': `Bearer ${api_key}`, 'Content-Type': 'application/json' },
body: JSON.stringify({ ciphertext }),
})
// 4. Retrieve and decrypt
const { ciphertext: stored } = await fetch(`${API_BASE}/v1/vault/my-key`, {
headers: { 'Authorization': `Bearer ${api_key}` },
}).then(r => r.json())
const plaintext = await vc.decrypt(stored, 'my-key')
console.log('Decrypted:', plaintext)
// Decrypted: my-secret-value
}
main()
curl-only (without the crypto library)
If you want to store plaintext (no encryption), or bring your own encryption:
# Store any string as ciphertext (plaintext storage — not recommended for secrets)
curl -X PUT https://api.agentlair.dev/v1/vault/my-key \
-H "Authorization: Bearer $AL_KEY" \
-H "Content-Type: application/json" \
-d '{"ciphertext": "my-raw-value"}'
# Retrieve
curl https://api.agentlair.dev/v1/vault/my-key \
-H "Authorization: Bearer $AL_KEY"
Note: The
ciphertextfield accepts any string. Vault stores it opaquely. If you don’t encrypt it, neither does Vault — “zero-knowledge” is a property of client-side encryption, not server enforcement.
What’s next
- Concepts — How seeds, key derivation, and versioning work
- API Reference — All endpoints, parameters, and error codes
- Security Model — The crypto stack and what we guarantee