# Separation of Duties

Separation of duties constraints require [Advanced RBAC](/content/docs/platform/authentication/role-based-access-control/advanced-rbac/index.html) to be enabled.

Separation of duties (SoD) constraints prevent users from holding conflicting role combinations. This is a key security control for organizations that need to enforce compliance policies or reduce the risk of privilege abuse.

## Constraint types [Permalink for this section](/content/docs/platform/authentication/role-based-access-control/constraints#constraint-types/index.html)

### Static separation of duties [Permalink for this section](/content/docs/platform/authentication/role-based-access-control/constraints#static-separation-of-duties/index.html)

A **static SoD constraint** prevents a user from being assigned two specific roles simultaneously. The constraint is enforced at assignment time — if a user already holds one of the conflicting roles, attempting to assign the other will fail.

**Example:** A user cannot be both a "Privacy Request Approver" and a "Privacy Request Submitter", preventing someone from approving their own requests.

### Cardinality constraints [Permalink for this section](/content/docs/platform/authentication/role-based-access-control/constraints#cardinality-constraints/index.html)

A **cardinality constraint** limits how many users can hold a specific role. This is useful for restricting highly privileged roles.

**Example:** Limit the "Owner" role to no more than 3 users in the organization.

⚠️ Cardinality constraints are currently stored in the database but **not enforced** at role assignment time. This is a planned enhancement. Static SoD constraints are fully enforced.

## Managing constraints [Permalink for this section](/content/docs/platform/authentication/role-based-access-control/constraints#managing-constraints/index.html)

### Viewing constraints [Permalink for this section](/content/docs/platform/authentication/role-based-access-control/constraints#viewing-constraints/index.html)

#### From the API [Permalink for this section](/content/docs/platform/authentication/role-based-access-control/constraints#from-the-api/index.html)

```bash
curl https://your-fides-instance/api/v1/plus/rbac/constraints \
  -H "Authorization: Bearer $TOKEN"
```

**Response:**

```json
[\
  {\
    "id": "constraint-uuid",\
    "name": "Approver / Submitter SoD",\
    "description": "Users cannot approve their own requests",\
    "constraint_type": "static_sod",\
    "role_id_1": "approver-role-uuid",\
    "role_id_2": "submitter-role-uuid",\
    "max_users": null,\
    "is_active": true,\
    "created_at": "2026-01-15T10:00:00Z"\
  }\
]
```

### Creating a static SoD constraint [Permalink for this section](/content/docs/platform/authentication/role-based-access-control/constraints#creating-a-static-sod-constraint/index.html)

```bash
curl -X POST https://your-fides-instance/api/v1/plus/rbac/constraints \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{\
    "name": "Approver / Submitter SoD",\
    "description": "Users cannot approve their own requests",\
    "constraint_type": "static_sod",\
    "role_id_1": "approver-role-uuid",\
    "role_id_2": "submitter-role-uuid"\
  }'
```

Once created, any attempt to assign `role_id_2` to a user who already holds `role_id_1` (or vice versa) will be rejected with an error explaining the constraint violation.

### Creating a cardinality constraint [Permalink for this section](/content/docs/platform/authentication/role-based-access-control/constraints#creating-a-cardinality-constraint/index.html)

```bash
curl -X POST https://your-fides-instance/api/v1/plus/rbac/constraints \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{\
    "name": "Max 3 Owners",\
    "description": "Limit the number of users with full system access",\
    "constraint_type": "cardinality",\
    "role_id_1": "owner-role-uuid",\
    "max_users": 3\
  }'
```

### Deleting a constraint [Permalink for this section](/content/docs/platform/authentication/role-based-access-control/constraints#deleting-a-constraint/index.html)

Constraints are immutable after creation. To modify a constraint, delete it and create a new one.

```bash
curl -X DELETE https://your-fides-instance/api/v1/plus/rbac/constraints/{constraint_id} \
  -H "Authorization: Bearer $TOKEN"
```

## Disabling constraint enforcement [Permalink for this section](/content/docs/platform/authentication/role-based-access-control/constraints#disabling-constraint-enforcement/index.html)

If you need to temporarily bypass SoD enforcement (for example, during a migration), you can disable it:

```bash
FIDESPLUS__RBAC__ENFORCE_SOD_CONSTRAINTS=false
```

When disabled, SoD constraints remain in the database but are not checked during role assignment. Re-enable enforcement by setting the value back to `true` and restarting.

⚠️ Disabling constraint enforcement does not retroactively check existing role assignments. If you assign conflicting roles while enforcement is off, those assignments will persist after re-enabling. Review your assignments before turning enforcement back on.

## Best practices [Permalink for this section](/content/docs/platform/authentication/role-based-access-control/constraints#best-practices/index.html)

- **Start with key conflicts**: Identify the most critical role conflicts in your organization (e.g., request creator vs. approver) and create SoD constraints for those first.
- **Document your constraints**: Use descriptive names and descriptions so the purpose of each constraint is clear to other administrators.
- **Review before enabling**: If you're adding constraints to an existing deployment, review current role assignments first to identify any existing violations.
- **Use with role hierarchy**: When designing role hierarchies, consider SoD implications. If Role A inherits from Role B, and you create an SoD constraint between Role B and Role C, users with Role A will also be blocked from holding Role C.
