Documentation · Authentication
Authentication
Each Warden account can have more than one login identity. Password identities can optionally protect themselves with self-hosted TOTP two-factor authentication.
Password login
Passwords are stored as salted PBKDF2-SHA256 hashes. A login session records both the Warden account and the identity used to enter it, which preserves useful audit information when several people intentionally share one account.
A user signed in through a password identity can change that identity's password from System → Security. The current browser session is retained, while other sessions created through that login identity are revoked. Administrators can reset an individual password identity from System → Access; an administrative reset revokes every session using that identity.
Self-hosted TOTP
Open System → Security while signed in with a password identity. Warden generates the TOTP secret locally and shows both the secret and its otpauth:// URI so it can be added to any standard authenticator. A valid six-digit code must be supplied before TOTP is enabled.
The TOTP secret is encrypted at rest by Warden. It is not stored in users.json. Recovery codes are generated with high entropy, shown once, and only one-way hashes are stored. Using a recovery code consumes it.
Challenge replay protection
A password login protected by TOTP creates a five-minute challenge bound to the client address. The challenge is consumed by the first verification attempt, whether that attempt succeeds or fails. Reusing it or presenting it from another address cannot create a session; start a fresh password login instead.
Optional Google login
Administrators can configure a Google OAuth client from System → Warden. Register Warden's exact callback URL, ending in /api/oauth/google/callback, with the Google OAuth client. Non-loopback deployments require an HTTPS callback.
Warden does not offer open Google signup in the initial implementation. The authorization-code exchange uses state validation and PKCE in addition to the configured confidential client secret. A signed-in user explicitly links a Google account from System → Security; after that, Continue with Google can sign into the linked Warden account. The identity is keyed by Google's immutable provider subject. Email is retained only as useful display metadata.
The Google client secret is encrypted in secrets.json. authentication.json contains the non-secret enabled state, client ID and redirect URI so administrators can still inspect and edit the ordinary configuration as JSON.
OAuth state limits
OAuth state and PKCE verifier material are single-use, expire after ten minutes and are bounded to 128 pending flows. Warden requires both an immutable Google subject and a provider-verified email before linking or login can proceed.
Secrets at rest
Warden creates a mode-0600 master.key in the instance configuration directory and uses AES-GCM authenticated encryption for values in secrets.json. This same secrets layer stores optional Google OAuth client secrets and per-account/shared AI provider credentials. Secret mutations deliberately do not retain a decryptable secrets.json.bak; use an explicit password-encrypted Warden backup when recovery or migration is required.
Encryption protects secrets.json from casual disclosure and configuration exports, but anyone who can read both master.key and secrets.json has the same secret-reading authority as the Warden OS account.
Recovery and corruption boundary
master.key and secrets.json must be regular files and remain paired. Warden authenticates every encrypted value during reload and keeps the last known-good in-memory snapshot when a candidate file is corrupt. Losing the key is not recoverable from secrets.json; restore a password-encrypted Warden backup or re-enter credentials.
Second factor belongs to the identity
TOTP is attached to a password identity rather than the whole Warden account. If two people intentionally share one Warden account through separate login identities, each password identity can have its own authenticator and recovery codes.
Session lifecycle
Sessions last up to 12 hours and are stored server-side; the browser receives only an HttpOnly, SameSite=Strict cookie. Warden caps active sessions at 32 per account and evicts the oldest when that limit is reached. Each request rechecks both account and login-identity state. Logout, administrative revocation, password reset, account disable and identity removal invalidate the relevant server-side sessions.
Backup and migration
Ordinary configuration exports do not contain TOTP seeds or OAuth client secrets. Administrators can instead create a password-encrypted backup from System → Warden; on restore, secrets are decrypted in memory and re-encrypted under the destination Warden instance’s master key.