Skip to content

Commit f99d0da

Browse files
Graham Ritterclaude
authored andcommitted
Add MFA docs and session profiles, adapted to new docs structure
Ports content from PR #619 (amir/mfa-docs) to the current docs structure: - Add MFA pages: overview, satisfying-mfa, enforcement-and-recovery, examples - Add session profiles page - Convert sessions.mdx to sessions/overview.mdx with scoped sessions section - Update docs.json navigation with Sessions and MFA groups - Fix all cross-references to use features/authentication/sessions/overview - Add redirects for old session paths - Fix internal links to use current paths (features/policies/, api-reference/, etc.) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 9ccbd38 commit f99d0da

15 files changed

Lines changed: 912 additions & 14 deletions

docs.json

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -335,7 +335,22 @@
335335
]
336336
},
337337
"features/authentication/auth-proxy",
338-
"features/authentication/sessions",
338+
{
339+
"group": "Sessions",
340+
"pages": [
341+
"features/authentication/sessions/overview",
342+
"features/authentication/sessions/session-profiles"
343+
]
344+
},
345+
{
346+
"group": "Multi-factor authentication (MFA)",
347+
"pages": [
348+
"features/authentication/mfa/overview",
349+
"features/authentication/mfa/satisfying-mfa",
350+
"features/authentication/mfa/enforcement-and-recovery",
351+
"features/authentication/mfa/examples"
352+
]
353+
},
339354
{
340355
"group": "Advanced",
341356
"pages": [
@@ -1056,7 +1071,7 @@
10561071
"redirects": [
10571072
{
10581073
"source": "/users/sessions",
1059-
"destination": "/features/authentication/sessions",
1074+
"destination": "/features/authentication/sessions/overview",
10601075
"permanent": true
10611076
},
10621077
{
@@ -1851,7 +1866,12 @@
18511866
},
18521867
{
18531868
"source": "/authentication/sessions",
1854-
"destination": "/features/authentication/sessions",
1869+
"destination": "/features/authentication/sessions/overview",
1870+
"permanent": true
1871+
},
1872+
{
1873+
"source": "/features/authentication/sessions",
1874+
"destination": "/features/authentication/sessions/overview",
18551875
"permanent": true
18561876
},
18571877
{
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
---
2+
title: "MFA Enforcement and Recovery"
3+
description: "Learn how to enforce multi-factor authentication (MFA) policies for end-users in your sub-organizations, and how to set up recovery mechanisms in case users lose access to their authentication methods."
4+
sidebarTitle: "Enforcement and Recovery"
5+
---
6+
7+
## Enforcing MFA for end users
8+
9+
Enforcing MFA for an end user on a sub-organization can be done using a [delegated access user](/features/policies/delegated-access/overview).
10+
11+
A delegated access user is a non-root user created in the sub-organization whose API key is controlled by the parent organization and has carefully scoped permissions to perform only specific actions.
12+
13+
To set this up:
14+
15+
1. The sub-organization's root user creates a delegated access user with an API key controlled by the parent org.
16+
2. The sub-organization's root user creates a policy that allows the delegated access user to manage MFA policies.
17+
3. The delegated access user can then create MFA policies for the sub-organization's root user.
18+
19+
The policy assigned to the delegated access user should be scoped to only allow MFA policy management:
20+
21+
``` ts
22+
// Policy condition: only allow MFA policy activities
23+
activity.resource == 'MFA_POLICY'
24+
```
25+
26+
Once this is in place, the delegated access user (controlled by the parent org) can create MFA policies on behalf of the end user. For example, to require MFA for all activities:
27+
28+
```json
29+
{
30+
"userId": "<suborg-root-user-id>",
31+
"mfaPolicyName": "MFA for everything",
32+
"condition": "true",
33+
"requiredAuthenticationMethods": /* The authentication methods you want to require */,
34+
"order": 1
35+
}
36+
```
37+
38+
## MFA recovery
39+
40+
If an end user loses access to one of their authentication methods, they may be unable to complete activities that require MFA. Because Turnkey cannot write to organizations directly, Turnkey is unable to recover access for end-users. **Organizations must set up a recovery mechanism in advance.**
41+
42+
One approach is to use [delegated access users](/features/policies/delegated-access/overview) to delete the MFA policy that is locking the user out. The delegated access user must have permission to delete MFA policies:
43+
44+
``` ts
45+
// Policy condition: only allow deleting MFA policies
46+
activity.resource == 'MFA_POLICY' && activity.action == 'DELETE'
47+
```
48+
49+
### Quorum-based recovery
50+
51+
It is strongly recommended that your Organization considers setting up **two or more delegated access users** for MFA recovery, with a consensus policy requiring both or more to approve before an MFA policy can be deleted. This prevents any single party from removing a user's MFA protections.
52+
53+
To set this up:
54+
55+
1. Create two delegated access users in the sub-organization, each with an API key controlled by different parties in the parent organization.
56+
2. Create a policy scoped to MFA policy deletion with a consensus requirement:
57+
58+
``` ts
59+
// Policy condition
60+
activity.resource == 'MFA_POLICY' && activity.action == 'DELETE'
61+
```
62+
63+
```ts
64+
// Consensus requirement: both delegated users must approve
65+
approvers.count() >= 2
66+
```
67+
68+
With this configuration, deleting an MFA policy requires both delegated access users to approve the `DeleteMfaPolicy` activity.

0 commit comments

Comments
 (0)