feat(settings): activate Security authentication policy (Phase 3b)#557
Merged
Conversation
Promote the workspace authentication policy (require-MFA + session idle/absolute timeouts) from hard-coded identity constants to data, editable from Settings -> Security. Backend: - migration 0033 auth_policy: singleton row (BOOLEAN PK pinned TRUE), seeded with the behaviour-preserving defaults (require_mfa false, 900s idle, 43200s absolute) - internal/authpolicy: Get/Update with bounds validation (idle 5m..24h, absolute 1h..30d, absolute >= idle); Update + startup Prime re-prime the identity session windows so changes take effect without a restart - identity session windows are now runtime-swappable (SetSessionWindows / CurrentWindows); the 15m/12h constants become Default* fallbacks. A non-positive window coerces to the default so a malformed policy can never disable session expiry - soft require-MFA: a password-valid but non-enrolled user is still issued a session (so they can reach the auth-gated enrollment endpoint) and the login response flags mfa_enrollment_required; no hard block = no lockout - new system:auth_policy_read / system:auth_policy_write perms (granted to admin + security_admin); auth.policy.updated audit event - GET/PUT /api/v1/auth-policy (always wired; never 503) Frontend: - SecurityPage: live Authentication policy section (require-MFA toggle + idle/absolute timeout steppers, save), perm-gated; SSO stays pending - LoginPage routes a non-enrolled user to /settings/profile when the login response sets mfa_enrollment_required - system:auth_policy_* added to the admin permission baselines Specs: system-auth-policy (tier1) + api-auth-policy (tier2); amend system-auth-identity C-06 (defaults now policy-overridable); frontend-settings -> v1.7.0 (AC-25). 103 specs. Note: flagged for human security review — session-window promotion and the soft require-MFA login branch.
The Quality+security gates lint forbids bare slog.Warn (skips correlation_id); use slog.WarnContext with the prime context.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Phase 3b — Authentication policy (Settings -> Security)
Part of the sequenced /settings activation initiative. Promotes the workspace authentication policy (require-MFA + session idle/absolute timeouts) from hard-coded
identityconstants to data, editable from Settings -> Security. After this, the only remaining stubbed Security surface is SSO (Phase 3c); Integrations (Phase 4) is the last full stub page.Backend
auth_policy— singleton row (BOOLEAN PK pinnedTRUE), seeded with behaviour-preserving defaults (require_mfafalse, 900s idle, 43200s absolute).internal/authpolicy—Get/Updatewith bounds validation (idle 5m..24h, absolute 1h..30d, absolute ≥ idle).Update+ a startupPrimere-prime the identity session windows, so a change takes effect without a restart.identity.SetSessionWindows/CurrentWindows(atomic, lock-free read path). The 15m/12h constants becomeDefault*fallbacks; a non-positive window coerces to the default so a malformed policy can never disable session expiry.mfa_enrollment_required. No hard block = no lockout (the chosen enforcement model).system:auth_policy_read/system:auth_policy_write(granted toadmin+security_admin);auth.policy.updatedaudit event.GET/PUT /api/v1/auth-policy— always wired (never 503).Frontend
/settings/profilewhen the login response setsmfa_enrollment_required.system:auth_policy_*added to the admin permission baselines.Specs & tests
system-auth-policy(tier 1) +api-auth-policy(tier 2); amendedsystem-auth-identityC-06 (defaults now policy-overridable);frontend-settings-> v1.7.0 (AC-25). 103 specs,specter checkgreen,specter check --test0 errors.internal/authpolicy(DSN-gated behavioural + source-inspection) andinternal/serverapi-auth-policytests pass against real Postgres. Fullinternal/serversuite green (after refreshing the gitignoredopenapi_embed.yaml, which CI rebuilds viamake build).settings.test.ts25 tests pass.🤖 Generated with Claude Code