Skip to content

feat(settings): activate Security authentication policy (Phase 3b)#557

Merged
remyluslosius merged 2 commits into
mainfrom
feat/settings-auth-policy
Jun 15, 2026
Merged

feat(settings): activate Security authentication policy (Phase 3b)#557
remyluslosius merged 2 commits into
mainfrom
feat/settings-auth-policy

Conversation

@remyluslosius

Copy link
Copy Markdown
Contributor

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 identity constants 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

  • migration 0033 auth_policy — singleton row (BOOLEAN PK pinned TRUE), seeded with behaviour-preserving defaults (require_mfa false, 900s idle, 43200s absolute).
  • internal/authpolicyGet/Update with bounds validation (idle 5m..24h, absolute 1h..30d, absolute ≥ idle). Update + a startup Prime re-prime the identity session windows, so a change takes effect without a restart.
  • Configurable session windowsidentity.SetSessionWindows/CurrentWindows (atomic, lock-free read path). 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); the login response flags mfa_enrollment_required. No hard block = no lockout (the chosen enforcement model).
  • RBAC — new system:auth_policy_read / system:auth_policy_write (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 Backend 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 & tests

  • New system-auth-policy (tier 1) + api-auth-policy (tier 2); amended system-auth-identity C-06 (defaults now policy-overridable); frontend-settings -> v1.7.0 (AC-25). 103 specs, specter check green, specter check --test 0 errors.
  • Go: internal/authpolicy (DSN-gated behavioural + source-inspection) and internal/server api-auth-policy tests pass against real Postgres. Full internal/server suite green (after refreshing the gitignored openapi_embed.yaml, which CI rebuilds via make build).
  • Frontend: tsc + eslint clean; settings.test.ts 25 tests pass.

⚠️ Flagged for human security review: the session-window promotion and the soft require-MFA login branch.

🤖 Generated with Claude Code

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.
@remyluslosius remyluslosius merged commit 91e5999 into main Jun 15, 2026
13 checks passed
@remyluslosius remyluslosius deleted the feat/settings-auth-policy branch June 15, 2026 13:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant