# Multi-Provider Identity Provider (IdP) Support

> The MCP Gateway Registry supports multiple identity providers (IdPs) through a pluggable architecture.

- Skill: `tools-only/multi-provider-identity-provider-idp-support` (Agent Skill, multi-file: 3 files)
- Install (CLI): `npx skillmds@latest add tools-only/multi-provider-identity-provider-idp-support`
- Raw SKILL.md: https://api.skillmd.com/api/skills/tools-only/multi-provider-identity-provider-idp-support/raw
- Safety review: pending (external: skill-scanner PASS, skillspector PASS)
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: tools-only (https://skillmd.com/u/tools-only)
- Updated: 2026-09-29
- Page: https://skillmd.com/skills/tools-only/multi-provider-identity-provider-idp-support

---

# Multi-Provider Identity Provider (IdP) Support

**Version:** 1.0
**Last Updated:** 2026-01-18

## Related Documentation

- [Authentication Design](./authentication-design.md) - Auth flows for human users, programmatic access, and M2M workloads
- [Authentication & Authorization Guide](../auth.md) - Operational guide with setup instructions
- [Microsoft Entra ID Integration](../entra.md) - Entra ID-specific setup and configuration

## Overview

The MCP Gateway Registry supports multiple identity providers (IdPs) through a pluggable architecture. This design enables organizations to use their existing enterprise identity infrastructure (Keycloak, Microsoft Entra ID) for authentication and authorization.

## Architecture

### High-Level Component Diagram

```
+------------------+     +------------------+     +------------------+
|                  |     |                  |     |                  |
|   Registry UI    |     |   CLI Tools      |     |   AI Agents      |
|   (Frontend)     |     | (registry_mgmt)  |     |  (M2M Clients)   |
|                  |     |                  |     |                  |
+--------+---------+     +--------+---------+     +--------+---------+
         |                        |                        |
         |   HTTP + JWT Token     |   HTTP + JWT Token     |
         |                        |                        |
         v                        v                        v
+--------+------------------------+------------------------+---------+
|                                                                    |
|                         NGINX Gateway                              |
|                     (auth_request /validate)                       |
|                                                                    |
+--------+-----------------------------------------------------------+
         |
         | /validate
         v
+--------+-----------------------------------------------------------+
|                                                                    |
|                         Auth Server                                |
|                                                                    |
|  +----------------+    +------------------+    +----------------+  |
|  |                |    |                  |    |                |  |
|  | AuthProvider   |    | AuthProvider     |    | AuthProvider   |  |
|  | Factory        +--->+ Protocol         +--->+ Implementations|  |
|  |                |    | (Base Class)     |    |                |  |
|  +----------------+    +------------------+    +----------------+  |
|                                                      |             |
|                           +----------------+---------+             |
|                           |                |                       |
|                           v                v                       |
|                    +------+------+  +------+------+                |
|                    |             |  |             |                |
|                    |  Keycloak   |  |  Entra ID   |                |
|                    |  Provider   |  |  Provider   |                |
|                    |             |  |             |                |
|                    +-------------+  +-------------+                |
|                                                                    |
+--------------------------------------------------------------------+
         |
         | Group-to-Scope Mapping
         v
+--------+-----------------------------------------------------------+
|                                                                    |
|               MongoDB-CE / Amazon DocumentDB                       |
|                                                                    |
|  +---------------------------+  +---------------------------+      |
|  | mcp_scopes_default        |  | mcp_servers_default       |      |
|  |                           |  |                           |      |
|  | - scope definitions       |  | - server configurations   |      |
|  | - group_mappings          |  | - tool definitions        |      |
|  | - server_access rules     |  |                           |      |
|  | - ui_permissions          |  |                           |      |
|  +---------------------------+  +---------------------------+      |
|                                                                    |
+--------------------------------------------------------------------+
```

## Provider Selection

The active identity provider is determined by the `AUTH_PROVIDER` environment variable:

```
AUTH_PROVIDER=keycloak   # Use Keycloak
AUTH_PROVIDER=entra      # Use Microsoft Entra ID
```

### Provider Factory Pattern

```
+-------------------+     +--------------------------+
|                   |     |                          |
| AUTH_PROVIDER env +---->+  AuthProviderFactory     |
|                   |     |                          |
+-------------------+     +------------+-------------+
                                       |
                    +------------------+------------------+
                    |                                     |
                    v                                     v
          +---------+---------+              +-----------+-----------+
          |                   |              |                       |
          | KeycloakProvider  |              |  EntraIdProvider      |
          |                   |              |                       |
          | - OIDC endpoints  |              | - Microsoft Graph API |
          | - JWKS validation |              | - JWKS validation     |
          | - Realm-based     |              | - Tenant-based        |
          |                   |              |                       |
          +-------------------+              +-----------------------+
```

## IAM Manager Interface

For administrative operations (user/group CRUD), the system uses the IAM Manager abstraction:

```python
@runtime_checkable
class IAMManager(Protocol):
    """Protocol defining the IAM manager interface."""

    async def list_users(
        self,
        search: str | None = None,
        max_results: int = 500,
        include_groups: bool = True
    ) -> list[dict[str, Any]]: ...

    async def create_human_user(
        self,
        username: str,
        email: str,
        first_name: str,
        last_name: str,
        groups: list[str],
        password: str | None = None,
    ) -> dict[str, Any]: ...

    async def delete_user(self, username: str) -> bool: ...

    async def list_groups(self) -> list[dict[str, Any]]: ...

    async def create_group(
        self,
        group_name: str,
        description: str = ""
    ) -> dict[str, Any]: ...

    async def delete_group(self, group_name: str) -> bool: ...

    async def create_service_account(
        self,
        client_id: str,
        groups: list[str],
        description: str | None = None
    ) -> dict[str, Any]: ...
```

### Implementation Classes

```
+------------------+          +------------------+
|                  |          |                  |
| KeycloakIAM      |          | EntraIAM         |
| Manager          |          | Manager          |
|                  |          |                  |
+--------+---------+          +--------+---------+
         |                             |
         | Delegates to                | Delegates to
         v                             v
+--------+---------+          +--------+---------+
|                  |          |                  |
| keycloak_manager |          | entra_manager    |
| .py              |          | .py              |
|                  |          |                  |
| - Keycloak Admin |          | - Microsoft      |
|   REST API       |          |   Graph API      |
| - Realm mgmt     |          | - App registr.   |
| - Client mgmt    |          | - Service        |
|                  |          |   principals     |
+------------------+          +------------------+
```

## Provider-Specific Details

### Keycloak Provider

**Authentication Flow:**
- Uses OIDC Authorization Code flow
- Tokens issued by Keycloak realm
- JWKS endpoint: `{keycloak_url}/realms/{realm}/protocol/openid-connect/certs`

**Group Identifier in Tokens:**
- Group names (e.g., `registry-admins`, `public-mcp-users`)
- Stored in `groups` claim of JWT

**IAM Operations:**
- Uses Keycloak Admin REST API
- Requires admin credentials or service account with realm-admin role

### Microsoft Entra ID Provider

**Authentication Flow:**
- Uses OAuth2 Authorization Code flow (users)
- Uses OAuth2 Client Credentials flow (M2M)
- Tokens issued by Microsoft STS
- JWKS endpoint: `https://login.microsoftonline.com/{tenant_id}/discovery/v2.0/keys`

**Group Identifier in Tokens:**
- Group Object IDs (GUIDs) like `5f605d68-06bc-4208-b992-bb378eee12c5`
- Stored in `groups` claim of JWT
- Object IDs must be mapped to scope names in MongoDB

**IAM Operations:**
- Uses Microsoft Graph API
- Requires App Registration with appropriate permissions:
  - `Application.ReadWrite.All`
  - `Directory.ReadWrite.All`
  - `Group.ReadWrite.All`
  - `User.ReadWrite.All`

## Group-to-Scope Mapping

The mapping between IdP groups and registry scopes is stored in MongoDB-CE/Amazon DocumentDB (`mcp_scopes_default` collection):

```
+---------------------------------------------------+
| MongoDB-CE/Amazon DocumentDB: mcp_scopes_default  |
+---------------------------------------------------+
| Document Structure:                               |
|                                                   |
| {                                         |
|   "_id": "registry-admins",               |  <-- Scope name
|   "group_mappings": [                     |
|     "registry-admins",                    |  <-- Keycloak group name
|     "4c46ec66-a4f7-4b62-9095-..."         |  <-- Entra ID group Object ID
|   ],                                      |
|   "server_access": [ ... ],               |  <-- MCP server permissions
|   "ui_permissions": { ... }               |  <-- UI feature access
| }                                         |
+-------------------------------------------+
```

### Mapping Flow

```
+------------------+     +------------------+     +------------------+
|                  |     |                  |     |                  |
|  JWT Token       |     |  Scope           |     |  Access          |
|  from IdP        +---->+  Repository      +---->+  Decision        |
|                  |     |                  |     |                  |
+------------------+     +------------------+     +------------------+
        |                        |                        |
        | groups claim:          | Query:                 | Result:
        | ["5f605d68-..."]       | Find scopes where      | scopes=["public-
        |                        | group_mappings         |  mcp-users"]
        |                        | contains "5f605d68-"   |
        v                        v                        v

Keycloak example:              Entra ID example:
groups: ["public-mcp-users"]   groups: ["5f605d68-06bc-4208-b992-bb378eee12c5"]
        |                              |
        +------------------------------+
                      |
                      v
              +-------+-------+
              |               |
              | Mapped to:    |
              | public-mcp-   |
              | users scope   |
              |               |
              +---------------+
```

## Configuration

### Environment Variables

```bash
# Provider Selection
AUTH_PROVIDER=entra              # or "keycloak"

# Keycloak Configuration
KEYCLOAK_URL=https://keycloak.example.com
KEYCLOAK_REALM=mcp-gateway
KEYCLOAK_CLIENT_ID=mcp-registry
KEYCLOAK_CLIENT_SECRET=...

# Entra ID Configuration
ENTRA_TENANT_ID=6e6ee81b-6bf3-495d-a7fc-d363a551f765
ENTRA_CLIENT_ID=1bd17ba1-aad3-447f-be0b-26f8f9ee859f
ENTRA_CLIENT_SECRET=...

# Token Validation
SECRET_KEY=...                   # For self-signed tokens
JWT_ISSUER=mcp-auth-server
JWT_AUDIENCE=mcp-registry
```

### Scopes Configuration (scopes.yml or MongoDB)

```yaml
# Group mappings - maps IdP group identifiers to scope names
group_mappings:
  # Entra ID uses Object IDs (GUIDs)
  "4c46ec66-a4f7-4b62-9095-b7958662f4b6":
    - registry-admins
    - mcp-servers-unrestricted/read
    - mcp-servers-unrestricted/execute

  "5f605d68-06bc-4208-b992-bb378eee12c5":
    - public-mcp-users

  # Keycloak uses group names
  "registry-admins":
    - registry-admins

  "public-mcp-users":
    - public-mcp-users
```

## Adding a New Provider

To add support for a new identity provider:

1. **Create Provider Class** (`auth_server/providers/new_provider.py`):
   - Implement `AuthProvider` base class
   - Handle OIDC/OAuth2 flows
   - Implement token validation via JWKS

2. **Create IAM Manager** (`registry/utils/new_provider_manager.py`):
   - Implement user/group CRUD operations
   - Handle provider-specific API calls

3. **Update Factory** (`registry/utils/iam_manager.py`):
   - Add new provider case to `get_iam_manager()`

4. **Update Auth Factory** (`auth_server/providers/factory.py`):
   - Add new provider case to factory function

5. **Configure Group Mappings**:
   - Add group identifiers to `scopes.yml` or MongoDB-CE/Amazon DocumentDB
   - Document group identifier format (names vs IDs)

## Security Considerations

1. **Token Validation**: Always validate JWT signatures against provider JWKS
2. **Admin Credentials**: Store IdP admin credentials securely (environment variables, secrets manager)
3. **Principle of Least Privilege**: Request minimal permissions for IAM operations
4. **Eventual Consistency**: Handle Entra ID's eventual consistency with retry logic
5. **Token Expiry**: Respect token expiration times; implement refresh where needed

