> ## Documentation Index
> Fetch the complete documentation index at: https://mcp-server-langgraph.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Identity Federation Quick Start

> Integrate existing identity providers (LDAP, SAML, OIDC) with Keycloak for centralized authentication.

Integrate existing identity providers (LDAP, SAML, OIDC) with Keycloak for centralized authentication.

```mermaid theme={null}
flowchart TD
    subgraph Providers["Identity Providers"]
        LDAP["LDAP / Active Directory"]
        OIDC["OIDC Providers<br/>(Google, Microsoft, Okta)"]
        SAML["SAML IdPs<br/>(ADFS, Ping)"]
    end

    subgraph Keycloak["Keycloak Federation"]
        Broker["Identity Broker"]
        Mapper["Attribute Mapper"]
        Realm["langgraph-agent Realm"]
    end

    subgraph App["MCP Server"]
        JWT["JWT Token"]
        API["API Endpoints"]
    end

    LDAP -->|"Sync users/groups"| Broker
    OIDC -->|"OAuth2 redirect"| Broker
    SAML -->|"SAML assertion"| Broker

    Broker --> Mapper
    Mapper --> Realm
    Realm -->|"Issue"| JWT
    JWT --> API

    %% ColorBrewer2 Set3 palette - each component type uniquely colored
    classDef providerStyle fill:#8dd3c7,stroke:#2a9d8f,stroke-width:2px,color:#333
    classDef keycloakStyle fill:#bebada,stroke:#7e5eb0,stroke-width:2px,color:#333
    classDef appStyle fill:#b3de69,stroke:#7cb342,stroke-width:2px,color:#333

    class LDAP,OIDC,SAML providerStyle
    class Broker,Mapper,Realm keycloakStyle
    class JWT,API appStyle
```

See [ADR-0037](/architecture/adr-0037-identity-federation) for architecture details.

### Identity Federation Protocol Flow

The following diagram shows the detailed protocol flow for federating external identity providers (Azure AD, Okta, Google) through Keycloak, including SAML/OIDC exchanges, token handling, and JWT issuance:

```mermaid theme={null}
flowchart TB
    %% ColorBrewer2 Set3 palette - each component type uniquely colored

    subgraph External["External Identity Providers"]
        AzureAD["Azure AD<br/>(OIDC)"]
        Okta["Okta<br/>(SAML/OIDC)"]
        Google["Google Workspace<br/>(OIDC)"]
    end

    subgraph Protocol["Protocol Layer"]
        SAML["SAML 2.0<br/>Assertion"]
        OIDC["OIDC<br/>Authorization Code"]
    end

    subgraph Keycloak["Keycloak Identity Broker"]
        Broker["Identity Broker<br/>(Protocol Handler)"]
        Validator["Token/Assertion<br/>Validator"]
        Mapper["Attribute Mapper<br/>(Claims → Keycloak)"]
        TokenExchange["Token Exchange<br/>(External → Internal)"]
    end

    subgraph Session["Session Management"]
        UserSession["User Session<br/>Creation"]
        SessionStore["Session Store<br/>(Redis/Database)"]
    end

    subgraph JWT["JWT Issuance"]
        JWTGen["JWT Generator<br/>(Keycloak Signing)"]
        JWTToken["Keycloak JWT<br/>(Access + Refresh)"]
    end

    subgraph Client["Client Application"]
        App["MCP Server<br/>(API Consumer)"]
    end

    %% Protocol flows
    AzureAD -->|"1. OAuth2 redirect"| OIDC
    Okta -->|"1. SAML/OIDC redirect"| SAML
    Okta -->|"1. SAML/OIDC redirect"| OIDC
    Google -->|"1. OAuth2 redirect"| OIDC

    %% Broker handling
    SAML -->|"2. SAML Response<br/>(XML Assertion)"| Broker
    OIDC -->|"2. Authorization Code<br/>(+ ID Token)"| Broker

    %% Validation
    Broker -->|"3. Validate signature<br/>& assertions"| Validator
    Validator -->|"4. Extract claims<br/>(email, name, roles)"| Mapper

    %% Token exchange
    Mapper -->|"5. Map external claims<br/>to Keycloak attributes"| TokenExchange
    TokenExchange -->|"6. Create internal<br/>user representation"| UserSession

    %% Session creation
    UserSession -->|"7. Store session data"| SessionStore
    SessionStore -->|"8. Session ID"| JWTGen

    %% JWT generation
    JWTGen -->|"9. Sign JWT<br/>(RS256/ES256)"| JWTToken
    JWTToken -->|"10. Return tokens<br/>(access + refresh)"| App

    %% Styling
    classDef idpStyle fill:#8dd3c7,stroke:#2a9d8f,stroke-width:2px,color:#333
    classDef protocolStyle fill:#fb8072,stroke:#e76f51,stroke-width:2px,color:#333
    classDef keycloakStyle fill:#fdb462,stroke:#e67e22,stroke-width:2px,color:#333
    classDef tokenStyle fill:#bebada,stroke:#7e5eb0,stroke-width:2px,color:#333
    classDef clientStyle fill:#b3de69,stroke:#7cb342,stroke-width:2px,color:#333
    classDef sessionStyle fill:#ffffb3,stroke:#f1c40f,stroke-width:2px,color:#333

    class AzureAD,Okta,Google idpStyle
    class SAML,OIDC protocolStyle
    class Broker,Validator,Mapper,TokenExchange keycloakStyle
    class UserSession,SessionStore sessionStyle
    class JWTGen,JWTToken tokenStyle
    class App clientStyle
```

**Key Steps in the Federation Flow:**

1. **External IdP Redirect**: User authenticates with their existing identity provider (Azure AD, Okta, Google) using SAML or OIDC
2. **Protocol Response**: IdP returns SAML assertion (XML) or OIDC authorization code with ID token
3. **Signature Validation**: Keycloak broker validates signatures and assertions against IdP public keys
4. **Claim Extraction**: Broker extracts user claims (email, name, roles, groups) from the assertion/token
5. **Attribute Mapping**: External claims are mapped to Keycloak user attributes using configured mappers
6. **Token Exchange**: External tokens are exchanged for internal Keycloak user representation
7. **Session Creation**: Keycloak creates a new user session with federated identity information
8. **Session Storage**: Session data is persisted to Redis or database for scalability
9. **JWT Signing**: Keycloak generates and signs a new JWT (access + refresh tokens) using its own keys
10. **Client Response**: Signed Keycloak JWT is returned to the MCP server for API authentication

**Security Considerations:**

* **Signature Verification**: All external tokens/assertions are cryptographically verified
* **Token Exchange**: External tokens are never passed directly to clients - always exchanged for Keycloak JWTs
* **Session Isolation**: Federated sessions are isolated from local Keycloak sessions
* **Attribute Validation**: Mapped attributes are validated against Keycloak schema
* **Replay Protection**: SAML assertions include timestamp and ID validation to prevent replay attacks

### Quick Setup

#### LDAP/Active Directory

```bash theme={null}
## Set environment variables
export LDAP_CONNECTION_URL='ldap://ad.example.com:389'
export LDAP_BIND_DN='CN=Service Account,OU=Service Accounts,DC=example,DC=com'
export LDAP_BIND_PASSWORD='your-password'
export LDAP_USERS_DN='OU=Users,DC=example,DC=com'
export LDAP_GROUPS_DN='OU=Groups,DC=example,DC=com'

## Run setup script
python scripts/setup/setup_ldap_federation.py
```

See [setup\_ldap\_federation.py](/reference/setup-scripts#setup_ldap_federation-py) for full documentation.

#### Google Workspace

```bash theme={null}
## Set credentials
export GOOGLE_CLIENT_ID='your-client-id.apps.googleusercontent.com'
export GOOGLE_CLIENT_SECRET='your-secret'
export GOOGLE_HOSTED_DOMAIN='example.com'  # Optional

## Run setup
python scripts/setup/setup_oidc_idp.py --provider google
```

See [setup\_oidc\_idp.py](/reference/setup-scripts#setup_oidc_idp-py) for full documentation.

#### Microsoft 365 / Azure AD

```bash theme={null}
export MICROSOFT_CLIENT_ID='your-app-id'
export MICROSOFT_CLIENT_SECRET='your-secret'
export MICROSOFT_TENANT_ID='common'  # or specific tenant

python scripts/setup/setup_oidc_idp.py --provider microsoft
```

#### GitHub

```bash theme={null}
export GITHUB_CLIENT_ID='your-oauth-app-id'
export GITHUB_CLIENT_SECRET='your-secret'

python scripts/setup/setup_oidc_idp.py --provider github
```

#### Okta

```bash theme={null}
export OKTA_CLIENT_ID='your-app-id'
export OKTA_CLIENT_SECRET='your-secret'
export OKTA_DOMAIN='example.okta.com'

python scripts/setup/setup_oidc_idp.py --provider okta
```

#### ADFS (SAML)

```bash theme={null}
export SAML_ALIAS='adfs'
export SAML_SSO_URL='https://adfs.example.com/adfs/ls/'
export SAML_LOGOUT_URL='https://adfs.example.com/adfs/ls/'

python scripts/setup/setup_saml_idp.py
```

See [setup\_saml\_idp.py](/reference/setup-scripts#setup_saml_idp-py) for full documentation.

### Authentication Flow

#### Federated User Login

```mermaid theme={null}
%%{init: {'theme':'base', 'themeVariables': {
  'primaryColor':'#8dd3c7',
  'primaryTextColor':'#333',
  'primaryBorderColor':'#2a9d8f',
  'lineColor':'#fb8072',
  'secondaryColor':'#fdb462',
  'tertiaryColor':'#b3de69'
}}}%%
sequenceDiagram
    participant U as User
    participant A as App
    participant K as Keycloak
    participant IdP as External IdP<br/>(Google/LDAP/ADFS)

    U->>A: 1. Visit app.example.com
    U->>A: 2. Click "Sign in with Google"
    A->>K: 3. Redirect to Keycloak
    K->>IdP: 4. Redirect to external IdP
    U->>IdP: 5. Authenticate with IdP
    IdP-->>K: 6. Return assertion/token
    K->>K: 7. Map attributes
    K-->>A: 8. Issue Keycloak JWT
    A->>A: 9. Store JWT
    A->>A: 10. Use JWT for API calls
```

#### What Users See

All federated users receive standard Keycloak JWTs:

```json theme={null}
{
  "iss": "http://keycloak:8180/realms/langgraph-agent",
  "sub": "user:alice@example.com",
  "email": "alice@example.com",
  "given_name": "Alice",
  "family_name": "Smith",
  "realm_access": {
    "roles": ["admin", "premium", "user"]
  }
}
```

### Configuration Details

#### LDAP Attribute Mapping

Edit `config/ldap_mappers.yaml` ([reference](/reference/configuration-files#config-ldap_mappers-yaml)):

```yaml theme={null}
attribute_mappers:
  - name: email
    ldap_attribute: mail
    keycloak_attribute: email
  - name: department
    ldap_attribute: department
    keycloak_attribute: department
```

#### OIDC Provider Configuration

Edit `config/oidc_providers.yaml` ([reference](/reference/configuration-files#config-oidc_providers-yaml)):

```yaml theme={null}
providers:
  google:
    alias: google
    config:
      client_id: ${GOOGLE_CLIENT_ID}
      hosted_domain: ${GOOGLE_HOSTED_DOMAIN}
```

### Testing

#### Test LDAP Connection

```bash theme={null}
## In Keycloak Admin Console:
## User Federation → ldap → Test connection
## User Federation → ldap → Test authentication
## User Federation → ldap → Synchronize all users
```

#### Test OIDC Login

```bash theme={null}
## Visit Keycloak account console
https://keycloak.example.com/realms/langgraph-agent/account

## Click "Sign in with Google" (or other provider)
## Complete OAuth2 flow
## Verify user is created in Keycloak
```

#### Verify JWT Issuance

```bash theme={null}
## After federated login, get JWT
curl -X POST http://localhost:8080/auth/login \
  -d '{"username": "alice@example.com", "password": "federated-password"}'

## Should return Keycloak-issued JWT
```

### Troubleshooting

#### LDAP Connection Failed

**Check**:

* LDAP URL is accessible from Keycloak pod
* Bind DN and password are correct
* Users DN exists
* Firewall allows LDAP traffic (port 389/636)

#### SAML Metadata Import Failed

**Solutions**:

* Download SAML metadata from IdP
* Import manually in Keycloak Admin Console
* Verify SAML signature algorithm matches (RSA-SHA256)

#### OIDC Provider Not Found

**Check**:

* Client ID and secret are correct
* Redirect URI is configured in external IdP
* Scopes are correct (openid profile email)

### References

* ADR: [ADR-0037: Identity Federation](/architecture/adr-0037-identity-federation)
* LDAP Setup: `scripts/setup/setup_ldap_federation.py`
* SAML Setup: `scripts/setup/setup_saml_idp.py`
* OIDC Setup: `scripts/setup/setup_oidc_idp.py`
* Configuration: `config/ldap_mappers.yaml`, `config/oidc_providers.yaml`
