---
title: "Conditional Mappings"
description: "Conditional mappings add restrictions to when an external role maps to an Enterprise role. This enables fine-grained control over permission assignment."
stack: "Enterprise Stack (commercial) — version 0.21.0"
stack_version: "0.21.0"
stack_comparison: https://docs.walt.id/community-vs-enterprise.md
canonical_url: https://docs.walt.id/enterprise-stack/administration/access-and-permissions/external-role-mapping/conditional-mappings
generated: 2026-07-20
---
# Conditional Mappings

Conditional mappings add restrictions to when an external role maps to an Enterprise role. This enables fine-grained control over permission assignment.

## Use Cases

- **Email domain restrictions** — Only map roles for users from specific domains
- **Provider restrictions** — Only map roles from specific Identity Providers
- **Claim-based restrictions** — Map based on additional token claims

## Email Domain Conditions

Restrict a mapping to users with specific email domains:

**Option: CURL**

```bash
curl -X PUT \
  'https://{host}/v1/waltid.tenant1.BW_ADMIN/roles-api/roles/external-mappings/admin' \
  -H 'Authorization: Bearer {token}' \
  -H 'Content-Type: application/json' \
  -d '{
    "enabled": true,
    "conditions": {
      "emailDomains": ["company.com", "subsidiary.com"]
    }
  }'
```

**Option: Request Body**

```json
{
  "enabled": true,
  "conditions": {
    "emailDomains": ["company.com", "subsidiary.com"]
  }
}
```

With this mapping:
- User `alice@company.com` with role `admin` → Gets `BW_ADMIN`
- User `bob@subsidiary.com` with role `admin` → Gets `BW_ADMIN`
- User `eve@contractor.io` with role `admin` → **No mapping** (domain not allowed)

## Provider Restrictions

Restrict a mapping to a specific Identity Provider:

```bash
curl -X PUT \
  'https://{host}/v1/waltid.tenant1.BW_ADMIN/roles-api/roles/external-mappings/admin' \
  -H 'Authorization: Bearer {token}' \
  -d '{
    "enabled": true,
    "providerId": "keycloak-production"
  }'
```

With this mapping:
- User logging in via `keycloak-production` with role `admin` → Gets `BW_ADMIN`
- User logging in via `azure-ad` with role `admin` → **No mapping**

**Info:**

Use provider restrictions when you have the same role name across different IdPs but want different Enterprise mappings.

## Combining Conditions

Combine multiple conditions — all must be met:

```bash
curl -X PUT \
  'https://{host}/v1/waltid.tenant1.BW_ADMIN/roles-api/roles/external-mappings/admin' \
  -H 'Authorization: Bearer {token}' \
  -d '{
    "enabled": true,
    "providerId": "keycloak-production",
    "conditions": {
      "emailDomains": ["company.com"]
    }
  }'
```

This mapping applies only when:
1. User authenticates via `keycloak-production` **AND**
2. User's email ends with `@company.com` **AND**
3. User has the `admin` role

## Required Claims Conditions

Require specific claims in the token:

```bash
curl -X PUT \
  'https://{host}/v1/waltid.tenant1.BW_ADMIN/roles-api/roles/external-mappings/admin' \
  -H 'Authorization: Bearer {token}' \
  -d '{
    "enabled": true,
    "conditions": {
      "requiredClaims": {
        "department": "engineering",
        "level": "senior"
      }
    }
  }'
```

The user's ID token must contain:
```json
{
  "department": "engineering",
  "level": "senior"
}
```

## Practical Examples

### Example 1: Partner Access

Allow partners to access a limited role, but only from their domain:

```bash
# Partners get BW_VIEWER, restricted to their domains
curl -X PUT \
  'https://{host}/v1/waltid.tenant1.BW_VIEWER/roles-api/roles/external-mappings/partner' \
  -H 'Authorization: Bearer {token}' \
  -d '{
    "enabled": true,
    "conditions": {
      "emailDomains": ["partner1.com", "partner2.com"]
    }
  }'
```

### Example 2: Multi-Provider Setup

Different IdPs map the same external role to different Enterprise roles:

```bash
# Keycloak 'admin' → Full admin
curl -X PUT \
  'https://{host}/v1/waltid.tenant1.BW_ADMIN/roles-api/roles/external-mappings/admin' \
  -H 'Authorization: Bearer {token}' \
  -d '{
    "enabled": true,
    "providerId": "keycloak"
  }'

# Azure AD 'admin' → Limited admin
curl -X PUT \
  'https://{host}/v1/waltid.tenant1.BW_LIMITED_ADMIN/roles-api/roles/external-mappings/admin' \
  -H 'Authorization: Bearer {token}' \
  -d '{
    "enabled": true,
    "providerId": "azure-ad"
  }'
```

### Example 3: Contractor Restrictions

External contractors get access, but only during their contract period:

```bash
# Contractors with valid department claim
curl -X PUT \
  'https://{host}/v1/waltid.tenant1.BW_CONTRACTOR/roles-api/roles/external-mappings/contractor' \
  -H 'Authorization: Bearer {token}' \
  -d '{
    "enabled": true,
    "conditions": {
      "emailDomains": ["contractor-agency.com"],
      "requiredClaims": {
        "contract_status": "active"
      }
    }
  }'
```

### Example 4: Department-Based Access

Map based on department from IdP:

```bash
# Engineering department → Developer role
curl -X PUT \
  'https://{host}/v1/waltid.tenant1.DEVELOPER/roles-api/roles/external-mappings/employee' \
  -H 'Authorization: Bearer {token}' \
  -d '{
    "enabled": true,
    "conditions": {
      "requiredClaims": {
        "department": "engineering"
      }
    }
  }'

# Finance department → Finance role
curl -X PUT \
  'https://{host}/v1/waltid.tenant1.FINANCE/roles-api/roles/external-mappings/employee' \
  -H 'Authorization: Bearer {token}' \
  -d '{
    "enabled": true,
    "conditions": {
      "requiredClaims": {
        "department": "finance"
      }
    }
  }'
```

## Testing Conditional Mappings

Use the resolution endpoint to test conditions:

```bash
# Test with matching email domain
curl -X POST \
  'https://{host}/v1/waltid/roles-api/roles/external-mappings/resolve' \
  -H 'Authorization: Bearer {token}' \
  -d '{
    "externalRoles": ["admin"],
    "email": "user@company.com"
  }'

# Test with non-matching email domain
curl -X POST \
  'https://{host}/v1/waltid/roles-api/roles/external-mappings/resolve' \
  -H 'Authorization: Bearer {token}' \
  -d '{
    "externalRoles": ["admin"],
    "email": "user@other.com"
  }'
```

## Condition Reference

| Condition | Type | Description |
|-----------|------|-------------|
| `emailDomains` | string[] | User email must end with one of these domains |
| `requiredClaims` | object | Token must contain these claim key-value pairs |
| `providerId` | string | Must authenticate via this specific provider |

## Best Practices

1. **Start simple** — Add conditions only when needed
2. **Test thoroughly** — Use resolution endpoint before deploying
3. **Document conditions** — Keep track of why each condition exists
4. **Audit regularly** — Review conditions to ensure they're still needed
5. **Fail securely** — When in doubt, use stricter conditions

## Related

- [Create Mappings](https://docs.walt.id/enterprise-stack/administration/access-and-permissions/external-role-mapping/create-mappings.md) — Basic mapping creation
- [Test Mappings](https://docs.walt.id/enterprise-stack/administration/access-and-permissions/external-role-mapping/test-mappings.md) — Verify mappings work
- [Manage Mappings](https://docs.walt.id/enterprise-stack/administration/access-and-permissions/external-role-mapping/manage-mappings.md) — Update and delete mappings
