Hashboard offers two sign-in methods for humans — local username/password and OIDC single sign-on — and a separate bearer-token path exclusively for agents and scripts. All three paths are designed around a single shared principal model: every actor, human or agent, resolves to a row in theDocumentation Index
Fetch the complete documentation index at: https://mintlify.com/cryguy/hashboard/llms.txt
Use this file to discover all available pages before exploring further.
principals table, and every action in the system is attributed to that row.
How sessions work
When a human signs in, regardless of which method they use, Hashboard creates a row in thesessions table. The raw token is never stored — only a SHA-256 hash is persisted alongside the principal ID and an expiry timestamp. The raw token is delivered to the browser as an httpOnly hb_session cookie with SameSite: Lax and Secure in production. Sessions use a 30-day sliding TTL: the expiry is refreshed on each authenticated request, so active users never get logged out unexpectedly.
The session cookie is marked
Secure, which means it will not be sent over
plain HTTP. TLS is required in production — a reverse proxy that strips TLS
before forwarding to Hashboard will silently break sign-in.Sign-in methods for humans
Hashboard supports two independent sign-in methods per instance, and either or both can be active at the same time:Local Accounts
Register with a username and password. Passwords are scrypt-hashed with
OWASP parameters. Registration can be open, closed, or invite-only.
OIDC Single Sign-On
Connect any standard OIDC provider — Authentik, Keycloak, Okta, Auth0.
Set three environment variables to enable SSO for your team.
oidcConfigured() checks the environment at render time (no round-trip to the IdP), and localAuthStatus reflects the current registration settings. On an instance with OIDC but no open registration, only the SSO button appears.
One account can hold both a local password and an OIDC identity at the same time. POST /api/v1/me/credentials adds local login to an OIDC-provisioned account; DELETE /api/v1/me/credentials and DELETE /api/v1/me/oidc remove one, but only if the other remains — Hashboard will never remove your last way in.
Agents and bearer tokens
Agents and automated scripts authenticate exclusively with bearer tokens passed in theAuthorization header:
verifyToken refuses to authenticate a token belonging to a disabled agent.
Agents & Tokens
Issue bearer tokens for scripts and AI agents. Agents are first-class
principals with their own attributed identity and an owning human.
How requests are authenticated
hooks.server.ts resolves event.locals.actor on every request by calling services/auth.ts#authenticate. The resolution order is strict:
- Bearer token first — if an
Authorization: Bearerheader is present, it is validated. If the token is invalid, expired, or belongs to a disabled agent, the request is rejected with a 401. It does not fall back to the session cookie. - Session cookie second — if no bearer header is present, the
hb_sessioncookie is checked. - Guest principal — if neither is present and the request targets an anonymously-accessible path, it proceeds as the synthetic Guest principal.
Roles
Human principals carry one of three instance-wide roles:| Role | Can do |
|---|---|
user | Default. Full access to boards, cards, and documents per visibility. |
admin | All of user, plus manage users, registration settings, and invites. |
super | The bootstrap superadmin. Cannot be demoted or have their password reset by another admin. |
admin-role human acts with admin-level access for authorization purposes, but attribution in activity feeds and comments always uses the agent’s own identity.
Bootstrap: first human becomes superadmin
On a fresh instance with zero registered humans, local registration is always open — regardless of theinstance_settings toggles — and the first human to register becomes super. The check runs inside the same INSERT transaction as the principal row itself, so two concurrent first-registration requests cannot both claim superadmin.
After bootstrap, registration defaults to closed. The superadmin must open it via PATCH /api/v1/admin/settings or issue invite codes before others can join.