Sensitive Action Protection
Step-up verification for dangerous actions after login, enforced server-side in Convex and built on Better Auth. Works for every account type, including OAuth and magic-link users.
Some actions are dangerous enough that a logged-in session should not be enough to perform them — deleting an organization, removing a member, deleting an account. The starter gates these behind step-up verification: a fresh proof of identity collected at the moment of the action.
This is deliberately separate from login-time 2FA. Better Auth only challenges credential (email + password) sign-in, so Google, Microsoft, and magic-link users are never challenged by app-level 2FA. Step-up verification fills that gap and works for every account type, whether or not 2FA is on.
This page is the conceptual overview. For the full implementation — the registry, enforcement helpers, and how to add a protected action — see the detailed guide: Sensitive Action Protection.
How it works
When a protected backend function runs, it calls requireSensitiveAction
server-side. The call succeeds only if the user has a fresh session (for
low-risk actions) or a valid, action-scoped grant from a recent explicit
check. Otherwise it throws SENSITIVE_VERIFICATION_REQUIRED, the UI opens a
verification dialog, and on success the backend mints a short-lived grant and
the original call is retried.
The check is always server-side — hiding the button is convenience only.
Risk levels
Each action has a risk level that decides which methods satisfy it:
| Level | Meaning | Methods |
|---|---|---|
| 1 | Fresh session is enough | fresh session |
| 2 | Medium | fresh session / password / email |
| 3 | High (no fresh-session bypass) | password / email |
| 4 | Critical (single-use grant) | password / email |
Verification methods
- Fresh Session — recent sign-in, low/medium-risk actions only.
- Password Confirmation — re-verify the current password through Better Auth.
- Email Verification Codes — a 6-digit, single-use, hashed code; the universal fallback that works for every account type.
Related
Verifications are recorded by the Audit Log and the abuse-prone steps are protected by Rate Limiting.