> ## Documentation Index
> Fetch the complete documentation index at: https://turnkey-0e7c1f5b-docs-time-based-policies-root-quorum-note.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# MFA Recovery

> Learn how to set up recovery mechanisms for MFA policies in case users lose access to their authentication methods.

## Overview

When a user can no longer satisfy their MFA requirements (whether they lose a passkey, phone number,
or access to another factor), they risk losing access to their account. Turnkey cannot bypass MFA
through customer support, because Turnkey has no write access to organizations.

Recovery is also the weak point in any authentication system. While passkey authentication is
phishing-resistant and frictionless in the happy path, the risk concentrates in recovery: when a
user loses their primary authenticator, they fall back to weaker factors, and recovery can attach
brand-new signing credentials to the account. An attacker who controls a user's email inbox can
complete a recovery flow and walk away with access to sensitive operations.
[NIST SP 800-63B](https://csrc.nist.gov/pubs/sp/800/63/b/4/final) is explicit that account recovery
must be at least as strong as primary authentication, because attackers reliably target the weakest
path in.

There is no single recovery pattern that fits all threat models. This page presents multiple valid
approaches as design choices, along with transferable best practices that apply across all patterns.

## Best practices for all recovery approaches

These principles apply regardless of which recovery strategy you choose.

**1. Require two independent factors for recovery, only for recovery.** Use a conditional MFA policy
scoped to recovery-path operations: email OTP AND a second factor (SMS OTP or OAuth). Email alone
never completes recovery. SMS should only ever be an ANDed factor, and never standalone due to SIM
swap risk. Also consider factor overlap: if the user's email and OAuth identity are the same Google
account, they are not independent channels.

**2. Land recovery in a scoped session that can only add a new authenticator.** Define a session
profile whose sole permitted action is registering a new credential. No signing, no exports, no
transfers. The recovery flow is: user satisfies recovery MFA, receives the recovery-scoped session,
enrolls a new authenticator, then logs in normally with it. Even a fully successful attack on
recovery factors yields a session incapable of moving funds.

**3. Gate higher-sensitivity operations with step-up sessions.** Default sessions can allow
low-friction actions like viewing balances, while fund transfers require a short-lived, MFA-gated
session. Use amount-based conditional MFA so large sends always re-prompt. A freshly recovered
account still faces the withdrawal gate before funds can leave.

**4. Make recovery rare.** Prompt users to enroll a backup passkey at onboarding. Collect email plus
phone (or a backup passkey) at signup so every user can satisfy the ANDed recovery requirement later
without friction.

**5. Treat recovery as a security event.** Recovery attaches a new credential; it does not reset a
password. Notify on all channels when recovery starts and when an authenticator is added, with a
fast "this wasn't me" freeze path. Detect recovery and authenticator-creation activities via
webhooks. Show the full authenticator list in account settings. For additional protection, consider
a 24–72 hour withdrawal hold after recovery.

**6. Maintain strict flow hygiene.** Use short OTP expiry, strict attempt limits, and rate-limit
recovery initiation. Deliver codes instead of magic links. Never use knowledge-based questions (NIST
prohibits them).

## Recovery approaches

### Recovery through new authenticator enrollment

This approach lets users regain access by proving identity through a strong, secondary channel
(email + SMS OTP), then immediately enrolling a new passkey. The new credential is scoped to a
recovery session that can only complete registration. It cannot sign, export, or perform other
sensitive actions until the user logs in again with the newly recovered passkey.

#### How it works

1. Ahead of time, you create a session profile scoped to authenticator enrollment only, plus a
   conditional MFA policy that applies to logins targeting that profile.
2. User initiates recovery, providing their email address.
3. Your backend begins an OTP login, passing the recovery profile's `sessionProfileId` on the login
   activity. This is what makes the resulting session scoped.
4. User satisfies the conditional MFA policy: email OTP + SMS OTP (or email OTP + OAuth).
5. On success, the login returns a session token bound to that profile. It can enroll a credential
   and nothing else — it cannot sign, export, or move funds.
6. User enrolls a new passkey using the `CREATE_AUTHENTICATORS_V2` activity, stamped with the
   recovery session.
7. User logs in normally with the new passkey to access their account.

#### Design rationale

The recovery session profile acts as a strong mitigation. Even if an attacker successfully
compromises both recovery factors (email and phone), they can only register a credential. They
cannot immediately use that credential to drain the account or transfer assets.

#### Implementation example:

First, create a session profile that permits only credential registration:

```json theme={null}
{
  "sessionProfileName": "recovery-authenticator-only",
  "scope": "activity.kind == 'CREATE_AUTHENTICATORS'",
  "expirationSeconds": 600
}
```

Then set up MFA policies on the sub-organization to require two factors for logging in to a recovery
session:

```json theme={null}
// MFA policy for recovery: email OTP + SMS OTP
mfaPolicy: {
  userId: "<user-id>",
  mfaPolicyName: "Recovery MFA",
  condition: "activity.resource == 'AUTH' && activity.params.session_profile_id == '<recovery-authenticator-only_ID>'",
  requiredAuthenticationMethods: [
    { any: [{ type: "AUTHENTICATION_TYPE_EMAIL_OTP" }] },
    { any: [{ type: "AUTHENTICATION_TYPE_SMS_OTP" }] }
  ],
  order: 0
}

// Standard login: email OTP + passkey
mfaPolicy: {
  userId: "<user-id>",
  mfaPolicyName: "Standard MFA",
  condition: "activity.resource == 'AUTH'",
  requiredAuthenticationMethods: [
    { any: [{ type: "AUTHENTICATION_TYPE_EMAIL_OTP" }] },
    { any: [{ type: "AUTHENTICATION_TYPE_PASSKEY" }] }
  ],
  order: 1
}
```

Once the user obtains the recovery-scoped session, they call
[CREATE\_AUTHENTICATORS\_V2](/api-reference/activities/create-authenticators) to register a new
passkey.

The user can now use this freshly registered passkey for normal login.

### Unlock via delegated-access quorum

This approach suits organizations that want recovery to go through a gated approval process.
Multiple users together hold the power to unlock MFA policies on behalf of locked-out users. A
quorum requirement ensures no single party can unilaterally remove a user's MFA.

This pattern is valuable when the user retains one MFA factor but has lost another — for example,
they still have their passkey but have lost SMS or email access. Support verifies identity
out-of-band, then proposes deletion of the MFA policy. A quorum of delegated-access users approves,
and the user regains access.

#### How it works:

1. User contacts support, claiming loss of a factor.
2. Support verifies identity through an out-of-band process.
3. A delegated-access user proposes deletion of the MFA policy.
4. A second delegated-access user, controlled by a different party, approves the deletion.
5. The MFA policy is deleted; the user can authenticate without the lost factor.

#### Design rationale:

This approach requires the user to still possess at least one valid authenticator. It does not
provision new credentials. The quorum prevents any single compromised key from bypassing MFA
protections. The threshold should be set lower than the total number of factors (e.g., 2-of-3 or
2-of-4). If all factors/users must approve, a single lost key makes recovery impossible.

#### Implementation example:

Create multiple delegated-access users on the sub-organization, then set up a consensus policy
governing MFA policy deletion:

```json theme={null}
{
  "policyName": "Quorum MFA recovery",
  "effect": "EFFECT_ALLOW",
  "condition": "activity.resource == 'MFA_POLICY' && activity.action == 'DELETE'",
  "consensus": "approvers.count() >= 2",
  "notes": "Requires at least 2 delegated-access users to approve before an MFA policy can be deleted"
}
```

To recover a locked-out user, one user proposes the deletion with
[DELETE\_MFA\_POLICY](/api-reference/activities/delete-mfa-policy), and a second user then approves
with [APPROVE\_ACTIVITY](/api-reference/activities/approve-activity) targeting the fingerprint.

## Hybrid and complementary patterns

You can combine these approaches for defense in depth.

**Recovery for lost passkey, quorum for lost second factor.** Route the user to the
new-authenticator-enrollment flow when they've lost their passkey but still hold their second
factor. Route them to the quorum unlock flow when they still hold their passkey but have lost the
second factor.

**Recovery with withdrawal hold.** Pair new-authenticator enrollment with an application-managed
24–72 hour withdrawal hold. Funds cannot leave the account immediately after recovery, giving the
legitimate user time to freeze the account if the recovery wasn't theirs.

**Time-boxed recovery sessions.** Keep the recovery-scoped session TTL short (10–60 minutes). After
it expires, the user must re-authenticate through a full MFA challenge for any sensitive operation.

## Avoiding common pitfalls

**Email alone is not enough.** Email is a low-confidence channel. An attacker who compromises the
recovery inbox receives both the recovery code and, if not paired with an independent factor,
everything else that follows. Always require email AND a second factor that does not depend on the
same inbox.

**Do not bypass MFA on recovery success.** Do not issue a fully-privileged session immediately after
recovery. Use the recovery-scoped session so the user must earn a full session through their newly
registered credential.

**Do not make recovery permanent access.** New credentials issued through recovery should behave
like any other credential — subject to step-up MFA on high-risk actions, subject to the withdrawal
hold if configured, revocable through the standard authenticator management flow.

**Do not allow unlimited recovery attempts.** Rate-limit recovery initiation per user (e.g., 3
attempts per 24 hours). Strictly limit OTP retries. Lock out recovery temporarily after repeated
failures and notify the user through all channels.
