Authorization storage
The board store saves cards. The authorization store saves opaque account handles, encrypted GitHub credentials and hashes of named API tokens. Choose each independently: GitHub cards can use Postgres authorization, and SQLite cards can use a separate authorization database.
The service owns encryption, token hashing, expiry and source permissions.
SQLite and Postgres implement the same AuthorizationStore contract. Neither
adapter provides a new login method or changes who can access a source.
| Adapter | Use | Requirements |
|---|---|---|
| SQLite | Local API or a server with a persistent volume. | Preserve the authorization file and signing key across restarts. An ephemeral API host discards the file. |
| Postgres | Ephemeral API host, vanilla Postgres or Supabase Free. | Private schema, verified TLS remotely, backups and a persistent signing key. Stay within the host’s free quotas. |
Configure standard Postgres
Set the database connection securely in FOLIO_BOARD_DATABASE_URL on the
server. Then select that environment variable for authorization:
export FOLIO_BOARD_AUTH_CONNECTION_ENV=FOLIO_BOARD_DATABASE_URLThis names a variable; it is not the database URL itself. To use separate
databases or roles for cards and authorization, name a different connection
variable. The URL never goes into agents.yaml or the browser.
The server creates a private folio_auth schema. The connection role must be
able to initialize it, or an owner must initialize it and grant the runtime
role access to its tables and sequence. Do not expose it through Supabase’s
Data API or grant anonymous or browser users access.
Supabase uses the same Postgres adapter as a vanilla server. Use the shared pooler in session mode for an IPv4 backend; a paid IPv4 add-on or dedicated pooler is not required. Postgres and Supabase covers connections, free quotas and board configuration.
Keep SQLite on persistent storage
When FOLIO_BOARD_AUTH_CONNECTION_ENV is absent, account mode uses SQLite.
Set FOLIO_BOARD_AUTH_DB to its file; the default is .auth/security.sqlite3
inside the server work directory. That file must be separate from card data.
Its existing schema and encrypted records remain compatible.
Switching the adapter does not import existing records. A new empty store requires fresh sign-in and new API tokens. Keep the old database backup until any required migration is completed.
Preserve the signing key
Keep FOLIO_BOARD_SESSION_KEY unchanged across restarts and deployments. It
signs sessions and derives the credential encryption key. The store contains
an authenticated marker: startup with the wrong key fails rather than silently
resetting accounts or revocations. Back up the key separately from the database.
GitHub credentials are authenticated ciphertext in both adapters. Personal token secrets are shown once and stored as SHA-256 digests. Revocation and expiry are checked on every request; quota checks and insertion run atomically. Browser sign-out and named token revocation have separate handles.
Database failures are backend failures, not expired sessions. They do not silently clear credentials or turn into a new sign-in requirement. Writes with an uncertain acknowledgement are not replayed automatically.
Use one API instance when GitHub credentials require refresh: refresh calls are coordinated within that process. Postgres card writes and token quotas use database transactions and remain protected against concurrent writers.
Free hosting still needs durable data
Render Free can execute the API while Postgres stores cards and authorization. Local Git clones are rebuildable cache. No persistent Render disk is needed for that combination; configure both stores before activating it.
Confirm the Supabase organization is on Free and check Render billing and usage limits before deployment. Supabase Free can pause or restrict service; Render Free sleeps when idle. References: Supabase costs , Supabase pricing , Render Free .
Authentication describes sign-in. API tokens and MCP describe clients of the common API.