Skip to contentSkip to Content
DeploymentAuthentication

Authentication

ServerWho gets inWhose name a commit carries
LocalWhoever holds the bearer printed at startThe board checkout’s git user
Hosted account serverPeople signed in with GitHub, choosing their connected repositoriesThe signed-in person; the server commits
SQLite sourceGitHub sign-in with its own reader/writer policy, or explicit workspace bearer accessThe signed-in person; standalone bearer mode uses the SQLite service identity

Local: one bearer per start

The local server prints a random 256-bit token on every start and asks for it as Authorization: Bearer <token> on every route except the editor script. It answers loopback only and commits as the board checkout’s git user. Edit the board in the browser lists every limit.

Authentication is independent of storage

SQLite can use the same GitHub login as repository sources. board.auth.provider chooses sign-in independently of board.store and board.sources. Database access comes from its own readers and writers, checked on every request.

Explicit provider: token selects standalone access on loopback or behind HTTPS. The token grants access to one database workspace; server read-only mode disables writes. HTTPS servers read the bearer from an environment variable. The browser uses kanban.api.auth: token, keeps the credential in session storage for that API and disconnects when authorization is refused.

Hosted: your GitHub account and its connected repositories

A hosted server defaults to account mode (FOLIO_BOARD_MULTI_REPO=true). People sign in through one GitHub App. Sign-in identifies the person; it does not check access to the repository that hosts Folio Board.

  1. Sign in with GitHub goes through /auth/login and /auth/callback.
  2. A one-time code, valid 60 seconds, returns to the board. /auth/exchange exchanges it for a session, valid up to 8 hours.
  3. The board loads cards from every source configured by this account in this browser. An existing session supplies the first source when no configuration exists. The server checks each source before returning its cards. On a first visit without a source, or when none can be read, the entry page offers source configuration.
  4. Open the profile photo, then Settings → Sources, to add, edit or remove sources. A repository’s board branch is tried first, otherwise the board folder on its default branch. Branch and folder opens another location. Connect repositories opens the App’s installation screen; Refresh sources updates the available repositories after installation.

Every loaded card carries its source. The existing source: and project: filters control which cards are visible; adding a source does not switch the canvas or discard its filter. Writes go to that card’s own source, with its repository permissions. Identical card ids in different sources remain distinct.

Choosing a source opens existing files; it does not initialize a repository. Configured sources and view preferences are scoped to this account in this browser. Remembering a source grants no access: every reopening goes through the server. When an account session expires, the board reconnects through GitHub automatically and returns to the same page, sources and saved view. If another tab already has a fresh session, it uses that session first. Repeated sign-in failures stop automatic navigation and offer a retry; connection errors do not log the person out. This uses the existing eight-hour sign-in flow, without storing GitHub credentials in the browser or replaying card writes. Deployment modes compares what each mode can save and how it authenticates.

The browser receives a signed session with an opaque credential handle, never GitHub’s access token. GitHub credentials are encrypted in the persistent authorization database. Each account has its own clone for each selected branch and directory. Git reads and pushes use that person’s GitHub App user access token, so they cannot exceed either the person’s or the App’s access.

Repository access is checked on every request. Removing a repository from the installation or removing the person’s access stops subsequent reads and writes. Read permission opens the board; push permission enables edits. Every commit names the signed-in person as author and the server as committer.

Sign out invalidates all board sessions from that sign-in. Named API tokens have independent handles and must be revoked in Settings. Restarts retain authorized credentials when the authorization database and signing key are preserved on persistent storage.

The App must allow installation by Any account for people outside the owner’s account to connect repositories. A private App cannot provide that flow. Organizations may require an administrator to approve its installation. Deploy a hosted board lists the setup.

The server still validates its public Host, its allowed page origins, the signed OAuth state and the session on every request. No session is returned in a URL: the one-time code is consumed once.

Hosted with one configured repository

With FOLIO_BOARD_MULTI_REPO=false, board.store.repo, ref and path select one board for the whole server. Only collaborators can read it. This mode uses an installation token from the App’s private key, or the personal access token named by board.store.token_env, for its git operations.

Tools use their own tokens

Settings → API tokens issues expiring, revocable access to one source for the remote CLI and MCP. These credentials do not replace the normal web login and cannot manage account settings.

Authorization storage selects SQLite or standard Postgres for sessions, encrypted credentials and token revocations. This choice is independent of the source providers and login method.