Skip to contentSkip to Content

SQLite

SQLite stores the board in one database on your server. The existing API reads cards and saves moves, fields, descriptions, criteria, comments and artifacts. Each write creates an immutable revision with its actor and message. No Git checkout is required. Choose authentication separately: the normal GitHub login works with SQLite, and token access remains an option for your own installation.

Compare storage methods for advantages, tradeoffs and the available CLI, skills and API tools.

Use GitHub login with SQLite and Git sources

One login can open both GitHub repositories and configured SQLite databases. GitHub sources use repository permissions; databases use their own access list. In the server’s agents.yaml:

board: auth: provider: github server: bind: "0.0.0.0:4350" origins: ["https://board.example.com"] hosted: public_url: "https://api.example.com" github_client_id: "YOUR_GITHUB_CLIENT_ID" sources: - id: roadmap title: Roadmap store: kind: sqlite path: /var/data/boards/roadmap.sqlite access: readers: ["github:1234"] writers: ["github:5678"]

Set FOLIO_BOARD_GITHUB_CLIENT_SECRET and FOLIO_BOARD_SESSION_KEY as in Authentication. The client uses kanban.api: {url: "https://api.example.com", auth: github}. Sign in normally, then add the database in Profile → Settings → Sources. Repository sources and SQLite cards share the same canvas and filters.

Access entries use stable provider subjects, such as github:1234, rather than changeable usernames. Find your GitHub id with gh api user --jq .id. Writers can also read. Access defaults to nobody; "*" explicitly allows every signed-in account in that list. Each read and write checks the source’s current permissions. Database writes record the signed-in person’s identity. Database paths stay on the server; clients select the stable source id.

Add more database entries to board.sources. An optional seed: board imports that source’s Markdown once. Neither cards nor their revisions are sent to GitHub merely because GitHub provides the login.

Configure standalone token access

In the server’s agents.yaml:

board: auth: provider: token store: kind: sqlite path: data/board.sqlite server: bind: "127.0.0.1:4350" origins: ["http://localhost:3000"]

The database path is relative to the project directory; an absolute path also works. A new database starts with empty Ideas, Todo, In progress, In review and Done columns. Add board.source: board to import an existing Markdown board once. That folder needs board.yaml and its cards; it does not need Git. Hidden files are excluded and symlinks are refused. On later starts the database is authoritative and the seed folder is not read.

folio-agents board and the board skills still operate Markdown files; they do not edit this database. The import is one-time, so later CLI edits to the seed folder do not change SQLite. Use the browser or HTTP API after importing.

Start the server:

folio-board-server api --project-dir .

Local mode prints a bearer token. In the site’s docs.yaml, select token authentication explicitly:

kanban: source: fixtures/board/board routes: public: "/board" api: url: "http://127.0.0.1:4350" auth: token

Build the page with folio-agents build. Connect to your board accepts the token. The page shows cards only after an authorized backend read. The token stays in the tab’s session storage, scoped to the API address. It is never placed in a query string or saved with browser preferences. Cards identify their database source, so the existing source: and project: filters work.

Create cards directly through the SQLite API, including on an empty database:

curl -X POST http://127.0.0.1:4350/v1/cards \ -H 'Authorization: Bearer <token>' \ -H 'Content-Type: application/json' \ --data '{"id":"first-idea","markdown":"---\ntitle: First idea\nstatus: ideas\n---\n"}'

The id is a lowercase slug. The server validates the Markdown and board relationships, refuses duplicate ids, and creates one atomic revision.

Run it behind HTTPS

Use a reverse proxy with TLS and configure the server’s public address:

board: auth: provider: token store: kind: sqlite path: /var/lib/folio/board.sqlite token_env: FOLIO_BOARD_TOKEN server: bind: "0.0.0.0:4350" origins: ["https://board.example.com"] hosted: public_url: "https://api.example.com"

Set FOLIO_BOARD_TOKEN in the server environment to a random hex token of at least 32 characters. The server requires it for HTTPS mode and does not print it. --token can also supply it. The site’s kanban.api.url becomes https://api.example.com; keep auth: token. No OAuth client id or GitHub secret is needed. Set the browser origin exactly, without a trailing slash.

Standalone token mode serves one database workspace. The bearer grants access to that workspace; writes use the SQLite service identity. board.server.read_only: true opens an initialized database without allowing changes. The API checks the configured host, the allowed browser origins and the bearer independently.

Keep the database on persistent storage

Mount a persistent volume at the database directory. Container rebuilds and server restarts reopen the same file. Hosting with an ephemeral filesystem does not preserve the board across redeployments.

SQLite uses WAL journaling, a busy timeout and transactions for writes. A revision and all its file changes commit together. A stale revision or file hash refuses the entire write; the normal API conflict response applies. Unchanged file contents are shared between revisions.

Use SQLite’s online backup  mechanism for backups while the server is running. Keep the database and its WAL files on the same persistent volume.

Filters, named filters, appearance and layout remain browser preferences. The database persists board content and revision history; it does not sync personal settings between devices. Backend synchronization appears in Settings.

Deploy the database with its backend

Render and Docker keeps SQLite and authorization on persistent storage, serves MCP and includes the remote CLI. Render uses a paid disk; Docker Compose uses a named volume. API tokens connect tools without replacing the normal web login.