farfield · docs

keys

keys.farfield.systems

The credential admin — the one place API keys for every farfield app are issued, scoped, and revoked. Keys minted here land in a shared SQLite store (keys.sqlite on the /data volume) that every keyed app reads through lib/keys: a new key works within a request, a revoked key stops within a request, no restarts, no redeploys.

Admin-issued keys are deliberately opaque random tokens, not JWTs. Everything runs on one host over one bind mount, so a database row gives instant revocation, per-key audit (created / last used), and scoping with zero new dependencies — where a signed token would need TTLs, refresh flows, or a revocation list to approximate the same thing. Only each token's SHA-256 is stored; the plaintext is shown exactly once, at mint time.

Scopes

A key names one app (or * for all) and carries one scope:

read
the token-gated read endpoints — lists, details, drafts stay hidden
upload
the library's book upload/regroup endpoints only — no delete, no catalog reads
write
full API writes; implies read (and upload, for the library)

An optional expiry (in days) auto-retires a key; revocation is immediate either way. Env keys (<APP>_API_KEY, <APP>_READ_KEY) keep working unchanged as the bootstrap / break-glass tier.

Authentication

The admin UI is session-gated behind the shared PASSWORD, with brute-force limiting on the login form. There is deliberately no JSON write API: a credential minter should not itself be drivable by a credential. /status stays public.

API

GET /status
{ "service", "ok", "keys", "active" }

Using an issued key

Send it exactly like an env key — X-API-Key: <token> or Authorization: Bearer <token> — against the app it was issued for. Tokens are recognizable by their ffk_ prefix.