Repository navigation
feat: v0.20 console: step-up on every admin write, staged policy page, v0.20 audit events - #314
Merged
Merged
Conversation
Bump @seamless-auth/types to ^0.31.0, which adds the recovery, account recovery, break-glass, policy and step-up event types. - New Break-Glass, Account Recovery and Policy categories, so the event filters and summary charts no longer drop these into Other. - session_evicted and admin_last_admin_change_refused join their neighbouring categories. - Event tables show a readable name with the raw type beneath it. - break_glass_sign_in and break_glass_enrollment, and any event whose metadata carries severity "high", show a High severity badge and count as security signals on the Events page.
…equired The API now requires a fresh step-up on every admin write. - Organization create and update, and saving your own profile (PATCH /admin/users/:userId), now step up first like the other writes. - apiFetch handles 403 step_up_required centrally: it opens the step-up prompt and retries the request once. Concurrent refusals share one prompt. A declined prompt reports that verification is needed instead of "You do not have permission". - ApiError carries the API's error code so callers can branch on it.
The policy page edits the same sign-in policy keys as System Configuration, so the field controls and their option lists move to src/components/ConfigFields.tsx and src/lib/configFields.ts. No behaviour change.
Adds the Sign-in Policy page at /policy for the API's staged policy routes. - Published version against the draft, as a per-setting diff, with a warning when the draft was started from an older version. - Edit and save the draft, or discard it. - Dry run of the draft, or of unsaved edits, over the last 1 to 30 days: refused sign-ins and accounts, accounts with no remaining method, break-glass accounts counted apart, and a notice when the run may have reached the API's 10,000 account limit. - Publish with expectedVersion. A 409 policy_version_conflict reloads the policy and tells the operator. - Version history with source, time and author, a diff of any version against the policy in force, and rollback. - Publish and rollback step up first. Writes are hidden from read-only admins, who can still review and dry run.
PATCH /system-config/admin still applies policy keys at once, and the API records each such save as a config_patch policy version. - The Login Policy section says so and links to Sign-in Policy. - A staged draft is flagged, and saving a policy setting while one is staged asks for confirmation, since publishing the draft later would replace the saved settings. - A save refreshes the policy queries so the Sign-in Policy page shows the new version.
This was referenced Oct 26, 2026
Merged
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.
Console support for the v0.20 Seamless Auth API.
Closes #310
Closes #295
#310: step up before every admin write
handleCreateOrganization,handleUpdateOrganization) now callensureStepUp()first./profile(PATCH /admin/users/:userId) was also unguarded and now steps up. Every other write the API guards already stepped up (user create, update, delete, device replacement, session revoke and revoke all, system config save, OAuth provider create, update, toggle and delete, organization delete, member add, update and remove, audit export). The console has no user import or provider retirement UI. Enrollment invites and policy draft save and discard are not step-up routes on the API, so they stay on the role alone.apiFetchhandles403 { error: "step_up_required" }centrally (src/lib/api.ts,src/lib/stepUpRequired.ts,src/components/StepUpRequiredHandler.tsx): it runs the step-up prompt (forcing a fresh status check, since the cached one is known to be stale) and retries the request once. Concurrent refusals share one prompt. A declined prompt shows "This action needs a recent step-up verification..." instead of "You do not have permission".ApiErrornow carries the API'serrorcode (code).#295: staged policy UI
New Sign-in Policy page at
/policy, in the sidebar:src/components/ConfigFields.tsxandsrc/lib/configFields.ts(no behaviour change there).usersLockedOut, listed first), break-glass accounts counted separately, and a cap notice.expectedVersion. A409 policy_version_conflictreloads the policy and history and tells the operator.admin:read; edit, publish and rollback controls are hidden withoutadmin:write, matching the API.Audit events
@seamless-auth/typesbumped to^0.31.0(0.31.0 is the latest published version).session_evictedandadmin_last_admin_change_refusedjoin their neighbouring categories, so no 0.31.0 event type falls into Other.break_glass_sign_in,break_glass_enrollment, and any event withmetadata.severity: "high"get a High severity badge and count as security signals.Contract notes
cappedbefore answering and only records it in thepolicy_dry_runevent. The page shows the cap notice whenusersEvaluated + breakGlassAccountsreaches 10,000, and reads acappedfield if a later API sends one.usersWithNoRemainingMethodfield; the console usesusersLockedOutand the per-accountlockedOut.publishedByandupdatedByare user ids only, so the history links to the user rather than showing an email.Checks
New Playwright specs are in
e2e/tests/policy.spec.ts(including a publish refused withstep_up_requiredand retried), and the policy routes are seeded ine2e/personas.ts. The pinned Chromium build is not installed on this machine, so e2e ran in CI only:test (Node 22),test (Node 24),test (Node latest)ande2eall pass on 0bca7ae.