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 ciphertext field 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