# 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:

```sh
export FOLIO_BOARD_AUTH_CONNECTION_ENV=FOLIO_BOARD_DATABASE_URL
```

This 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](/docs/deployment/postgres) 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](https://supabase.com/docs/guides/platform/cost-control),
[Supabase pricing](https://supabase.com/pricing), [Render Free](https://render.com/docs/free).

[Authentication](/docs/deployment/auth) describes sign-in. [API tokens](/docs/deployment/tokens)
and [MCP](/docs/deployment/mcp) describe clients of the common API.
