Security
| Variable | Default | Description |
|---|---|---|
SESSION_SECRET |
— | Secret for signing session cookies and the shift calendar links — changing it invalidates every calendar link (employees renew theirs). Min 32 chars. Must be changed. Generate: openssl rand -hex 32 It only signs and protects no data — DATA_KEY does that. |
CSRF_KEY |
— | Secret for CSRF token signing. Min 32 chars. Must be changed. Generate: openssl rand -hex 32 |
DATA_KEY Required |
— | Encrypts the database. With SQLite the whole file including its journal — Klokk converts an existing database automatically, with checks, at the first start with DATA_KEY. With PostgreSQL Klokk also seals all free texts. Klokk does not start without DATA_KEY — existing installations set it before updating to 1.1.0. At least 32 characters, a value of its own (not that of SESSION_SECRET or CSRF_KEY). Once set, never change or lose it — without it the database cannot be opened any more, not even from a backup. Generate: openssl rand -hex 32. See Encryption. |
SESSION_SECURE_COOKIE |
true in production | Defaults to true when APP_ENV is production (requires HTTPS). Set false for plain HTTP, e.g. on localhost. |
SESSION_SAME_SITE |
lax | Cookie SameSite policy: strict, lax, or none. |
SESSION_MAX_AGE_HOURS |
8 | Session lifetime in hours. “Stay logged in” sessions last MFA_TRUST_DAYS instead. |
Authentication
Section titled “Authentication”| Variable | Default | Description |
|---|---|---|
REMEMBER_ME_ENABLED |
true | Show “Stay logged in” checkbox on the login page. |
MFA_TRUST_ENABLED |
true | Show “Trust this device” checkbox on the MFA page. |
MFA_TRUST_DAYS |
30 | Duration in days for remembered sessions and trusted MFA devices. |
DEFAULT_ADMIN_PASSWORD |
empty | Password for the initial admin account (username admin, email admin@localhost). Only used on first startup. Empty: Klokk generates a one-time password and prints it once in its log. Either way Klokk asks for a personal password at the first sign-in. |
PASSKEYS_ENABLED |
true | Allow sign-in with passkeys (WebAuthn / FIDO2). false hides passkeys everywhere and disables their endpoints. |
WEBAUTHN_RPID |
host of BASE_URL | Relying-party ID: the domain passkeys are bound to. Only set it when it must differ from the host in BASE_URL. Changing it later makes registered passkeys unusable. |
WEBAUTHN_RP_ORIGINS |
origin of BASE_URL | Comma-separated origins (scheme, host and port) allowed for passkey sign-in — needed when users reach Klokk under another public address than BASE_URL. |
WEBAUTHN_RP_NAME |
Klokk | Name the browser or password manager shows when a passkey is created. |
Admin Access Control
Section titled “Admin Access Control”| Variable | Default | Description |
|---|---|---|
ADMIN_IP_ALLOWLIST |
empty | Comma-separated IPs/CIDRs allowed to access /admin/*. Empty = no restriction. The client address behind reverse proxies is resolved as described under TRUSTED_PROXIES. |
SUPER_ADMIN_IP_ALLOWLIST |
empty | Additional allowlist for super_admin-only routes (/admin/settings, /admin/companies, /admin/audit). Stacks on top of ADMIN_IP_ALLOWLIST. |
TRUSTED_PROXIES |
empty | Client address behind reverse proxies, used by rate limits, IP allowlists and the audit log. Klokk reads X-Forwarded-For only from a private or loopback peer and, by default, believes just the entry that proxy added — a client cannot fake its address with its own header. With several proxies in a row, list the outer ones: addresses, CIDRs, cloudflare (its published ranges; CF-Connecting-IP is then trusted) or private, comma-separated. Set cloudflare behind Cloudflare. |
Password Policy
Section titled “Password Policy”| Variable | Default | Description |
|---|---|---|
PASSWORD_MIN_LENGTH |
12 | Minimum password length. |
PASSWORD_REQUIRE_UPPER |
true | Require at least one uppercase letter. |
PASSWORD_REQUIRE_LOWER |
true | Require at least one lowercase letter. |
PASSWORD_REQUIRE_NUMBER |
true | Require at least one digit. |
PASSWORD_REQUIRE_SPECIAL |
true | Require at least one special character. |
PASSWORD_MAX_HISTORY |
5 | Number of previous passwords to remember (prevent reuse). 0 = disabled. |
PASSWORD_EXPIRY_DAYS |
0 | Password expiry in days. 0 = never expires. |
Rate Limiting
Section titled “Rate Limiting”| Variable | Default | Description |
|---|---|---|
RATE_LIMIT_LOGIN_PER_MINUTE |
10 | Max login attempts per IP per minute. |
RATE_LIMIT_MFA_PER_MINUTE |
10 | Max MFA attempts per IP per minute. |
RATE_API_PER_MINUTE |
100 | Max API / general requests per IP per minute. |
AUTH_LOCKOUT_THRESHOLD |
5 | Failed login attempts before account lockout. 0 = disabled. |
AUTH_LOCKOUT_DURATION_MINUTES |
15 | Account lockout duration in minutes. |