Skip to content

API tokens

Long-lived scoped bearer tokens for service-to-service auth, CI/CD, automation tools, and AI agents.

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)
Scripted admin work (collections, settings, hooks)API token over MCP with mcp:* scopes, or an Admin JWT
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 on the data API (records, files, batch, realtime, custom routes), acting as the minting admin; implies every mcp:* scope — use sparingly
readany GET on the data API — all data, collection rules don’t apply (a read-only admin)
writePOST/PATCH/DELETE on the data API as a signed-in non-admin (collection rules still apply)
mcp:readMCP server: read-only tools, over all data (collection rules don’t apply)
mcp:writeMCP server: mutating tools (records, hooks, settings), acting as an admin — collection rules don’t apply
mcp:adminMCP server: full admin tools (implies all mcp:*)
mcp:sqlMCP server: raw SQL tool, read-only (writes also need mcp:admin)

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. Needs an admin session (an API token can’t mint tokens). Returns 201.

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 os
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.

MCP tool calls made with a token are written to the audit log as action mcp.tool, with actor_id + actor_email of the minting admin and token=<name> in the summary field — so “which automation did this” is one query away.

Every state-changing admin call made with an admin session is audited too, collections included (actions such as collections.create, settings.update, hooks.create).

Record writes made with a token on the data API are not in the audit log. The request log attributes them to api:<token id>.

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 is no longer authenticated. There is no eventual-consistency window. On the data API a revoked (or unknown) token is treated as an anonymous caller: admin-only collections answer 403, public ones still answer 200.

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)