Skip to content

API tokens

API tokens are vaultbase’s long-lived bearer tokens for non-human principals — CI pipelines, cron scripts, integrations (n8n / Zapier / Make), AI agents, third-party tools. Distinct from short-lived user/admin JWTs which expire weekly.

Format on the wire:

Authorization: Bearer vbat_<jwt>

The vbat_ prefix is stable so secret-scanning tools can detect leaked tokens in source repos / logs. The underlying JWT is a standard signed HS256 with audience: "api".

Use caseChoose
Browser SPA, mobile app, end-user sessionUser JWT (short-lived, refreshable)
CI / cron / service-to-serviceAPI token
n8n / Zapier / Make / IFTTT integrationsAPI token
AI agents over MCP (Claude Desktop, Cursor)API token
Read-only auditor / consultant accessAPI token with read scope
Admin SPA itselfAdmin JWT (HttpOnly cookie)
Embedding in a public client appNeither — never embed long-lived tokens client-side

API tokens are for trusted automation. They’re not user identity.

Phase-1 ships a coarse set; per-collection scopes (collection:posts:read) are recognised in the wire format but enforcement lands in the RBAC sprint.

ScopeWhat it grants
adminfull admin equivalent — use sparingly
readany GET on records / files / logs
writePOST/PATCH/DELETE on records (collection rules still apply)
mcp:readMCP server: read-only tools
mcp:writeMCP server: mutating tools (records, hooks, settings)
mcp:adminMCP server: full admin tools (implies all mcp:*)
mcp:sqlMCP server: raw SQL tool

admin implies every other scope. mcp:admin implies every mcp:*. read and write are independent — a read token can’t write; a write token can’t read.

Fastest path. Reads the local DB directly, no HTTP round-trip.

Terminal window
vaultbase token mint --name "CI deploy bot" --scope write --scope read --ttl 1y
# ✓ minted as ops@example.com
# id: 7f9a3c1d-44e2-4b18-...
# expires: 2027-05-03T10:30:00.000Z (365 days)
# scopes: write, read
#
# TOKEN — save this, it will NEVER be shown again:
#
# vbat_eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ...

The token is shown once. Save it to your password manager / CI secret store immediately. The DB stores only the metadata — vaultbase cannot recover the value.

Other CLI commands:

Terminal window
vaultbase token list # human-readable table
vaultbase token list --json # for scripts
vaultbase token revoke <id> # by id from `list`

For programmatic management. Admin auth required.

POST /api/v1/admin/api-tokens
Authorization: Bearer <admin-jwt>
Content-Type: application/json
{
"name": "Cursor laptop",
"scopes": ["mcp:read"],
"ttl_seconds": 7776000
}
{
"data": {
"id": "7f9a3c1d-...",
"token": "vbat_eyJhbGc...",
"expires_at": 1745000000,
"warning": "Save this token now — it will never be shown again."
}
}

Other endpoints:

GET /api/v1/admin/api-tokens — list metadata (no token values)
GET /api/v1/admin/api-tokens/:id — single
GET /api/v1/admin/api-tokens/me — describe the current request's token
DELETE /api/v1/admin/api-tokens/:id — revoke

/_/api-tokens page lists existing tokens with name + scopes + status + last-used. “Mint new token” dialog → name + scope multi-select + TTL dropdown. Shown-once token modal with a “Copy” button.

Same as any bearer auth:

Terminal window
curl -H "Authorization: Bearer vbat_eyJ..." \
https://api.example.com/api/v1/posts
import { Vaultbase } from "@vaultbase/sdk";
const vb = new Vaultbase({ baseUrl: "https://api.example.com" });
vb.client.authStore.set({ token: "vbat_eyJ...", record: { id: "ci-bot" } });
import requests
r = requests.get(
"https://api.example.com/api/v1/posts",
headers={"Authorization": f"Bearer {os.environ['VB_TOKEN']}"},
)
DefaultMinMax
90 days60 seconds10 years

Best practices:

  • Rotate annually for any production token. Mint new → update consumer → revoke old.
  • Short-lived for CI: 90d is fine; CI tokens move with the project, so worst-case leak window is bounded.
  • Long-lived for AI agents: 1y is reasonable. Revoke on laptop loss.
  • Never ship in client apps: tokens in mobile/desktop binaries leak the moment one user reverse-engineers the bundle.

Every authenticated API-token request goes through the standard audit log path. Mutating requests record actor_id + actor_email of the minting admin, plus the token’s name in the summary field — so “which automation did this” is one query away.

One click in the admin UI. Or:

Terminal window
vaultbase token revoke 7f9a3c1d-44e2-4b18-...
DELETE /api/v1/admin/api-tokens/7f9a3c1d-... HTTP/1.1
Authorization: Bearer <admin-jwt>

Revocation is synchronous — the next request bearing that token returns 401 immediately. There is no eventual-consistency window.

Revoking a token does not force-log-out other sessions. Only the minting admin’s password reset (force-logout-all) does that, and it kills this token too as a side effect.

Each row records:

  • last_used_at — most recent authenticated use
  • last_used_ip — most recent client IP (respects VAULTBASE_TRUSTED_PROXIES)
  • last_used_ua — most recent User-Agent (truncated to 200 chars)
  • use_count — total successful authenticated requests

Updates are buffered in-memory and flushed every 30 s OR every 1000 events, whichever fires first. Worst-case data loss on hard crash: 30 s of usage telemetry — pure observability, never authoritative.

  • Vaultbase stores only the metadata (name, scopes, jti, expires_at). The token value never touches disk after the mint response is sent.
  • The vbat_ prefix is grep-able. GitHub’s secret-scanning partner program (future) can auto-revoke tokens leaked to public repos.
  • Refuse to commit tokens. Use .env in .gitignore, GitHub secrets, CI secret stores.
  • Consider IP allowlists per token (planned for v0.10).
  • Per-collection scopes (collection:posts:read)
  • Per-token IP allowlist
  • Per-token rate-limit override
  • GitHub secret-scanning partner integration (auto-revoke on leak)
  • Service-account principals (no minting admin)
  • Token rotation API (mint new + revoke old in one call)