Authentication, MFA and OIDC
View as MarkdownLocal accounts
Section titled “Local accounts”Local accounts sign in with email and password. Passwords must be between 12 and 1024 characters. Accounts created from Ajustes → Usuarios (Settings → Users) start with a temporary password that is valid for 24 hours (TEMP_PASSWORD_TTL) and must be changed at the first sign-in.
Sessions
Section titled “Sessions”The session lives in the database and the browser only holds an httpOnly cookie named __Host-iw_session (Secure, SameSite=Strict). Every write request also carries a CSRF token in the X-CSRF-Token header.
| Setting | Default | Variable |
|---|---|---|
| Absolute session lifetime | 12 hours | SESSION_TTL (300 s to 7 days) |
| Idle timeout | 2 hours | SESSION_IDLE_TTL |
| Login attempts per IP | 5 per minute, then blocked for a minute | LOGIN_THROTTLE_LIMIT, LOGIN_THROTTLE_TTL |
| Failed logins per account, from any IP | 10 per 5 minutes | LOGIN_ACCOUNT_THROTTLE_LIMIT, LOGIN_ACCOUNT_THROTTLE_TTL |
The per-account limit does not block networks from which the account signed in successfully in the last 30 days, so an attacker cannot lock the owner out.
Changing your password closes your other sessions and revokes your API tokens. When an administrator resets a user’s password, that user’s sessions and API tokens end too.
Two-factor authentication
Section titled “Two-factor authentication”InfraWard supports TOTP (RFC 6238) with any authenticator app.
- Administrators who sign in with a password must enable it. The first sign-in opens the setup screen and nothing else is reachable until it is done.
- Other roles can enable it from Ajustes → Perfil → Seguridad (Settings → Profile → Security).
- Setup shows ten single-use recovery codes. The profile page shows how many are left and can generate a new set.
- An administrator can reset another user’s second factor from Ajustes → Usuarios. That also closes the user’s sessions.
TOTP and recovery codes share the login rate limit, applied per user.
Re-authentication for sensitive actions
Section titled “Re-authentication for sensitive actions”Some actions ask you to confirm your identity again when the last confirmation is older than 10 minutes (REAUTH_MAX_AGE, 60 to 3600 seconds): purging assets, changing roles, deactivating users, creating write tokens, revealing a vault password, granting terminal access, opening a terminal and changing alert channels. Users with TOTP confirm with a code; OIDC users are sent to the provider again, which must ask for their credentials (InfraWard sends prompt=login and max_age=30).
Single sign-on with OIDC
Section titled “Single sign-on with OIDC”InfraWard works with any OpenID Connect provider: Keycloak, Authentik, Microsoft Entra ID, Google, Zitadel and others. Setting OIDC_ISSUER enables it and adds a button to the login page.
1. Register InfraWard in the provider
Section titled “1. Register InfraWard in the provider”Create a confidential client (or a public client with PKCE) with:
- Redirect URI:
https://infraward.example.com/api/auth/oidc/callback - Scopes:
openid email profile, plus whatever your provider needs to include group membership in the ID token or userinfo. - A claim that lists the user’s groups or roles (for example
groups, orrealm_access.rolesin Keycloak).
2. Store the client secret
Section titled “2. Store the client secret”The client secret never goes in an environment variable. Store it in the secrets provider and pass a reference. With the API running:
printf '{"client_secret":"PASTE-THE-SECRET-HERE"}' \ | docker compose exec -T api node dist/cli/secret-put.js secret://openbao/oidc/ssoThe JSON is read from standard input, so the secret does not appear in the process list or the shell history (the printf line does, so prefer reading it from a file or a password manager). Without OpenBao, use secret://local/oidc/sso instead.
For a public client with PKCE, skip this step and leave OIDC_CLIENT_SECRET_REF unset.
3. Configure the API
Section titled “3. Configure the API”Add the variables to api in compose.override.yml (and add the file to COMPOSE_FILE, see Install with Docker Compose):
services: api: environment: OIDC_ISSUER: https://sso.example.com/realms/main OIDC_CLIENT_ID: infraward OIDC_CLIENT_SECRET_REF: secret://openbao/oidc/sso#client_secret OIDC_REDIRECT_URI: https://infraward.example.com/api/auth/oidc/callback OIDC_PROVIDER_NAME: Company SSO OIDC_GROUPS_CLAIM: groups OIDC_ROLE_MAPPING: infraward-admins=admin,infraward-editors=editor,infraward-ops=operator,infraward-audit=auditor,infraward-users=viewer OIDC_UNMAPPED: denydocker compose up -d api| Variable | Default | Meaning |
|---|---|---|
OIDC_ISSUER |
unset | Issuer URL. Enables OIDC. Must be https in production. |
OIDC_CLIENT_ID |
unset | Client ID. Required with OIDC_ISSUER. |
OIDC_CLIENT_SECRET_REF |
unset | secret://…#field reference to the client secret. Unset means a public client with PKCE. |
OIDC_REDIRECT_URI |
unset | Must be <public URL>/api/auth/oidc/callback. |
OIDC_TOKEN_AUTH_METHOD |
client_secret_basic |
Or client_secret_post. |
OIDC_PROVIDER_NAME |
OIDC |
Text of the login button. |
OIDC_SCOPES |
openid email profile |
Must include openid. |
OIDC_GROUPS_CLAIM |
groups |
Claim with the groups. Dotted paths are accepted, such as realm_access.roles. |
OIDC_ROLE_MAPPING |
unset | group=role pairs separated by commas. With several matching groups, the role with the most permissions wins. |
OIDC_UNMAPPED |
deny |
What happens to a user with no mapped group: deny rejects the login, viewer lets them in read-only. |
OIDC_ALLOW_UNVERIFIED_SIGNUP |
false |
Create accounts even when the provider does not mark the email as verified. See below. |
How accounts are created and updated
Section titled “How accounts are created and updated”- The first OIDC sign-in creates the user automatically with the mapped role, but only if the provider marks the email as verified (
email_verified: true). Otherwise the sign-in is rejected and no account is created: someone who registered in the provider with another person’s email would take over that address in InfraWard. - Microsoft Entra ID and other providers that verify emails themselves but do not send
email_verifiedneedOIDC_ALLOW_UNVERIFIED_SIGNUP: "true". Without it, new users cannot sign in. Enable it only if every account in the provider has an email it has verified. - The role is recalculated from the groups at every sign-in, so role changes are made in the provider.
- An existing local account is linked to the OIDC identity when the provider reports the same email as verified.
OIDC_ALLOW_UNVERIFIED_SIGNUPnever changes this. - With OIDC enabled, users cannot change their own email; an administrator does it.
Disable password login
Section titled “Disable password login”When everyone signs in through the provider, turn off password login and keep one local account for emergencies:
LOCAL_LOGIN: "false"With LOCAL_LOGIN=false only the emergency account can use a password. Store its password and recovery codes offline: it is the way in if the provider is down.
Troubleshooting sign-in
Section titled “Troubleshooting sign-in”See Troubleshooting.