Skip to content

feat: optional different deploy approver, and admin Reset MFA - #146

Merged
ndbroadbent merged 1 commit into
mainfrom
nathan/approver-mfa-reset
Oct 13, 2026
Merged

ndbroadbent merged 1 commit into
mainfrom
nathan/approver-mfa-reset

Conversation

@ndbroadbent

@ndbroadbent ndbroadbent commented Oct 13, 2026 •

Copy link
Copy Markdown
Member

Summary

#131 Require a different approver (optional, off by default)

  • New global setting deploy_approval_require_different_approver, in the Deploy Approvals group. It's on the Settings page and can be set with RGW_SETTING_DEPLOY_APPROVAL_REQUIRE_DIFFERENT_APPROVER.
  • When it's on, approving or extending a request is refused with a 403 for:
    • the user who created the request ("you created this request")
    • the owner of its target API token ("you own the API token this request is for")
  • It fails closed: if the setting can't be read, the request is refused.
  • The approval or extension's audit entry records different_approver_required: true.
  • Bug fix along the way: TargetUserID was never loaded, so the owner of a target token couldn't view a request that someone else created for it. Requests now load target_token.user_id.
  • The Settings card now keeps one pending-changes map instead of one state per field.

#135 Admin Reset MFA

  • New endpoint POST /api/v1/users/:email/mfa/reset (gateway:user:update, so MFA is needed on every request), shown as Reset MFA on another user's page when they have MFA.
  • One transaction (the existing, previously unused db.ResetUserMFA) does all of this:
    • deletes the user's MFA methods and backup codes
    • revokes their trusted devices with reason admin_mfa_reset
    • revokes their sessions, recording the admin who reset them
    • clears mfa_enrolled
  • API tokens are kept. The user is emailed, and the reset is audited as user.mfa_reset.
  • An admin can't reset their own MFA; they use Account Security.

Docs: Deploy Approvals (overview and workflow), SOC 2, environment variables, user management, backup codes, troubleshooting and the API reference.

Fixes #131, fixes #135

Test plan

  • task go:lint, task go:test:unit (1329 tests), duplication
  • task web:test, typecheck, task web:lint:fix
  • docs build (link check)
  • CI (including E2E)

Summary by CodeRabbit

  • New Features
    • Admins can reset another user’s MFA from the user-management page. The reset removes MFA methods, backup codes, and trusted devices, signs the user out, and preserves API tokens.
    • Deploy approvals can optionally require an approver other than the request creator or the owner of the associated API token. This setting is off by default.
  • Documentation
    • Updated recovery guidance, API references, and configuration documentation for MFA resets and the different-approver setting.

- A global setting, deploy_approval_require_different_approver (off by default), refuses
  approving or extending a deploy approval by the user who created the request or owns
  its API token, with a 403 that says which. It fails closed when the setting can't be
  read, and the approval's audit entry records that the rule applied. It's on the
  Settings page and settable with RGW_SETTING_*. Deploy approval requests now load
  their token's owner (TargetUserID was never set, so the owner of the target token
  couldn't view a request someone else created for it) (#131)
- Admins can reset another user's MFA (POST /api/v1/users/:email/mfa/reset, Reset MFA on
  the user's page): it removes their MFA methods, backup codes and trusted devices and
  revokes their sessions in one transaction, keeps their API tokens, needs MFA on the
  request, is audited as user.mfa_reset, and emails the user (#135)

Fixes #131, fixes #135

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Oct 13, 2026

Copy link
Copy Markdown

Review in Change Stack →

Note

Currently processing new changes in this PR. This may take a few minutes, please wait...

⚙️ Run configuration
  • Configuration used: Organization UI
  • Review profile: CHILL
  • Plan: Essentials
  • Run ID: eac3a8b5-a298-4a21-af63-24dab289dc82
📥 Commits

Reviewing files that changed from the base of the PR and between 5998d18 and 97cd2f8.

⛔ Files ignored due to path filters (3)
  • internal/gateway/openapi/generated/swagger.json is excluded by !**/generated/**
  • web/src/api/types.generated.ts is excluded by !**/*.generated.*
  • web/src/lib/generated/mfa-requirements.ts is excluded by !**/generated/**
📒 Files selected for processing (33)
  • docs/src/content/docs/configuration/environment-variables.mdx
  • docs/src/content/docs/development/api-reference.mdx
  • docs/src/content/docs/integrations/deploy-approvals/index.mdx
  • docs/src/content/docs/integrations/deploy-approvals/workflow.mdx
  • docs/src/content/docs/operations/troubleshooting.mdx
  • docs/src/content/docs/security/compliance/soc2.mdx
  • docs/src/content/docs/user-guide/mfa/backup-codes.mdx
  • docs/src/content/docs/user-guide/web-ui/user-management.mdx
  • internal/gateway/audit/constants.go
  • internal/gateway/db/deploy_approval_scan.go
  • internal/gateway/db/mfa.go
  • internal/gateway/handlers/admin_users_lock.go
  • internal/gateway/handlers/admin_users_mfa_reset.go
  • internal/gateway/handlers/admin_users_mfa_reset_test.go
  • internal/gateway/handlers/deploy_approval_admin.go
  • internal/gateway/handlers/deploy_approval_approver.go
  • internal/gateway/handlers/deploy_approval_approver_test.go
  • internal/gateway/rbac/audit_names.go
  • internal/gateway/rbac/gateway_routes.go
  • internal/gateway/routes/route_registration.go
  • internal/gateway/settings/defaults.go
  • internal/gateway/settings/groups.go
  • internal/gateway/settings/service_deploy.go
  • web/src/api/generated.ts
  • web/src/api/openapi.json
  • web/src/components/user-mfa-reset-dialog.test.tsx
  • web/src/components/user-mfa-reset-dialog.tsx
  • web/src/lib/api.ts
  • web/src/pages/settings-page.test.tsx
  • web/src/pages/settings/deploy-approvals-card.tsx
  • web/src/pages/user-page.tsx
  • web/src/pages/user/header-section.tsx
  • web/src/pages/user/use-user-danger-zone.ts
 _______________________________________
< We're gonna need a bigger bug zapper. >
 ---------------------------------------
  \
   \   \
        \ /\
        ( )
      .( o ).
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Comment @coderabbitai help to get the list of available commands.

@deepsource-io

deepsource-io Bot commented Oct 13, 2026 •

Copy link
Copy Markdown

DeepSource Code Review

We reviewed changes in 5998d18...97cd2f8 on this pull request. Below is the summary for the review, and you can see the individual issues we found as inline review comments.

See full review on DeepSource ↗

PR Report Card

Overall Grade   Security  

Reliability  

Complexity  

Hygiene  

Code Review Summary

Analyzer Status Updated (UTC) Details
JavaScript Oct 13, 2026 2:24a.m. Review ↗
Go Oct 13, 2026 2:24a.m. Review ↗

Important

AI Review is run only on demand for your team. We're only showing results of static analysis review right now. To trigger AI Review, comment @deepsourcebot review on this thread.

@ndbroadbent
ndbroadbent merged commit 6e60194 into main Oct 13, 2026
12 of 14 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Admins can't reset a user's MFA Optionally require a different person to approve a deploy

1 participant