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".
When to use API tokens vs user JWT
Section titled “When to use API tokens vs user JWT”| Use case | Choose |
|---|---|
| Browser SPA, mobile app, end-user session | User JWT (short-lived, refreshable) |
| CI / cron / service-to-service | API token |
| n8n / Zapier / Make / IFTTT integrations | API token |
| AI agents over MCP (Claude Desktop, Cursor) | API token |
| Read-only auditor / consultant access | API token with read scope |
| Admin SPA itself | Admin JWT (HttpOnly cookie) |
| Embedding in a public client app | Neither — never embed long-lived tokens client-side |
API tokens are for trusted automation. They’re not user identity.
Scopes
Section titled “Scopes”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.
| Scope | What it grants |
|---|---|
admin | full admin equivalent — use sparingly |
read | any GET on records / files / logs |
write | POST/PATCH/DELETE on records (collection rules still apply) |
mcp:read | MCP server: read-only tools |
mcp:write | MCP server: mutating tools (records, hooks, settings) |
mcp:admin | MCP server: full admin tools (implies all mcp:*) |
mcp:sql | MCP 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.
Mint via CLI
Section titled “Mint via CLI”Fastest path. Reads the local DB directly, no HTTP round-trip.
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:
vaultbase token list # human-readable tablevaultbase token list --json # for scriptsvaultbase token revoke <id> # by id from `list`Mint via REST
Section titled “Mint via REST”For programmatic management. Admin auth required.
POST /api/v1/admin/api-tokensAuthorization: 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 — singleGET /api/v1/admin/api-tokens/me — describe the current request's tokenDELETE /api/v1/admin/api-tokens/:id — revokeMint via admin UI
Section titled “Mint via admin UI”/_/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.
Use a token
Section titled “Use a token”Same as any bearer auth:
curl -H "Authorization: Bearer vbat_eyJ..." \ https://api.example.com/api/v1/postsimport { 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 requestsr = requests.get( "https://api.example.com/api/v1/posts", headers={"Authorization": f"Bearer {os.environ['VB_TOKEN']}"},)Lifetime + rotation
Section titled “Lifetime + rotation”| Default | Min | Max |
|---|---|---|
| 90 days | 60 seconds | 10 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.
Audit trail
Section titled “Audit trail”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.
Revoke
Section titled “Revoke”One click in the admin UI. Or:
vaultbase token revoke 7f9a3c1d-44e2-4b18-...DELETE /api/v1/admin/api-tokens/7f9a3c1d-... HTTP/1.1Authorization: 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.
Last-used tracking
Section titled “Last-used tracking”Each row records:
last_used_at— most recent authenticated uselast_used_ip— most recent client IP (respectsVAULTBASE_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.
Storage + leakage protection
Section titled “Storage + leakage protection”- 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
.envin.gitignore, GitHub secrets, CI secret stores. - Consider IP allowlists per token (planned for v0.10).
What’s planned for later
Section titled “What’s planned for later”- 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)
See also
Section titled “See also”- Authentication concept — user/admin auth model
- Security — overall trust boundaries
- SDK Authentication — using tokens via the SDK