Skip to content

Generic OIDC Provider Support via Environment Variables #1213

@crivetimihai

Description

@crivetimihai

Overview

Add environment variable configuration support for generic OIDC providers (Keycloak, Auth0, Authentik, etc.) following the same pattern as existing SSO providers (GitHub, Google, Okta, Entra ID).

Currently, generic OIDC providers can only be configured via the Admin API. This enhancement adds first-class support for a configurable generic OIDC provider via environment variables, enabling:

  • 12-factor app compliance
  • Bootstrap-time provider configuration
  • Parity with other SSO providers
  • Support for common enterprise OIDC providers (Keycloak, Auth0, etc.)

Motivation

Problem: Organizations using Keycloak, Auth0, Authentik, or other OIDC providers must:

  1. Enable the Admin API
  2. Manually POST provider configuration
  3. Re-configure after container restarts if not using persistent storage

Solution: Environment variable configuration like other providers:

SSO_ENABLED=true
SSO_GENERIC_ENABLED=true
SSO_GENERIC_PROVIDER_ID=keycloak
SSO_GENERIC_CLIENT_ID=my-client-id
# ... other settings

User Stories

As a DevOps Engineer

  • I want to configure Keycloak SSO via environment variables
  • So that I can deploy the gateway with Infrastructure-as-Code (Terraform, Helm)
  • Without needing to make API calls post-deployment

As a Platform Administrator

  • I want Auth0 SSO to be configured at startup
  • So that users can log in immediately after deployment
  • Without manual provider registration

As a Security Engineer

  • I want OIDC provider configuration in environment variables
  • So that secrets can be managed via vault/secret management
  • Following the same pattern as GitHub/Google/Okta

Acceptance Criteria

Configuration

  • Add environment variables for generic OIDC configuration
  • Support customizable provider ID (e.g., keycloak, auth0)
  • Support customizable display name
  • Include all standard OIDC endpoints (authorization, token, userinfo, issuer)
  • Support custom scopes (default: openid profile email)
  • Use existing SSO_TRUSTED_DOMAINS and SSO_AUTO_CREATE_USERS settings

Bootstrap

  • Auto-create provider at startup when SSO_GENERIC_ENABLED=true
  • Use existing generic OIDC normalization code (already implemented)
  • Support alongside other SSO providers (GitHub, Google, Okta, Entra ID)

Security

  • Client secret encrypted in database (existing mechanism)
  • Secret excluded from support bundles
  • Support bundle tests updated

UI

  • Login button uses configurable display name
  • Icon configurable or generic OIDC icon
  • Provider appears in /auth/sso/providers list

Documentation

  • Update README.md with environment variables table
  • Update docs/config.schema.json
  • Update .env.example with commented examples
  • Add docs/docs/manage/sso-generic-oidc-tutorial.md
  • Update docs/docs/manage/sso.md
  • Update Helm chart values.yaml

Testing

  • Unit tests for normalization (already exist - generic OIDC tests)
  • Integration tests for bootstrap
  • Support bundle sanitization tests

Technical Implementation

1. Configuration (mcpgateway/config.py)

# Generic OIDC Provider
sso_generic_enabled: bool = Field(
    default=False,
    description="Enable generic OIDC provider (Keycloak, Auth0, etc.)"
)
sso_generic_provider_id: Optional[str] = Field(
    default=None,
    description="Provider ID (e.g., 'keycloak', 'auth0', 'authentik')"
)
sso_generic_display_name: Optional[str] = Field(
    default=None,
    description="Display name shown on login page"
)
sso_generic_client_id: Optional[str] = Field(
    default=None,
    description="Generic OIDC client ID"
)
sso_generic_client_secret: Optional[str] = Field(
    default=None,
    description="Generic OIDC client secret"
)
sso_generic_authorization_url: Optional[str] = Field(
    default=None,
    description="Authorization endpoint URL"
)
sso_generic_token_url: Optional[str] = Field(
    default=None,
    description="Token endpoint URL"
)
sso_generic_userinfo_url: Optional[str] = Field(
    default=None,
    description="Userinfo endpoint URL"
)
sso_generic_issuer: Optional[str] = Field(
    default=None,
    description="OIDC issuer URL"
)
sso_generic_scope: Optional[str] = Field(
    default="openid profile email",
    description="OAuth scopes (space-separated)"
)

2. Bootstrap (mcpgateway/utils/sso_bootstrap.py)

# Generic OIDC Provider
if (settings.sso_generic_enabled 
    and settings.sso_generic_client_id 
    and settings.sso_generic_provider_id):
    
    provider_id = settings.sso_generic_provider_id
    display_name = settings.sso_generic_display_name or provider_id.title()
    
    providers.append({
        "id": provider_id,
        "name": provider_id,
        "display_name": display_name,
        "provider_type": "oidc",
        "client_id": settings.sso_generic_client_id,
        "client_secret": settings.sso_generic_client_secret or "",
        "authorization_url": settings.sso_generic_authorization_url,
        "token_url": settings.sso_generic_token_url,
        "userinfo_url": settings.sso_generic_userinfo_url,
        "issuer": settings.sso_generic_issuer,
        "scope": settings.sso_generic_scope,
        "trusted_domains": settings.sso_trusted_domains,
        "auto_create_users": settings.sso_auto_create_users,
        "team_mapping": {},
    })

3. Normalization (NO CHANGES NEEDED)

The existing generic OIDC normalization in sso_service.py:615-623 already handles any provider that doesn't match hardcoded IDs.

4. Support Bundle (mcpgateway/services/support_bundle_service.py)

exclude_fields = {
    # ... existing fields ...
    "sso_generic_client_secret",
}

Configuration Examples

Keycloak

SSO_ENABLED=true
SSO_GENERIC_ENABLED=true
SSO_GENERIC_PROVIDER_ID=keycloak
SSO_GENERIC_DISPLAY_NAME="Keycloak"
SSO_GENERIC_CLIENT_ID=mcp-gateway
SSO_GENERIC_CLIENT_SECRET=your-secret-here
SSO_GENERIC_AUTHORIZATION_URL=https://keycloak.example.com/realms/master/protocol/openid-connect/auth
SSO_GENERIC_TOKEN_URL=https://keycloak.example.com/realms/master/protocol/openid-connect/token
SSO_GENERIC_USERINFO_URL=https://keycloak.example.com/realms/master/protocol/openid-connect/userinfo
SSO_GENERIC_ISSUER=https://keycloak.example.com/realms/master
SSO_GENERIC_SCOPE="openid profile email"
SSO_TRUSTED_DOMAINS=["example.com"]
SSO_AUTO_CREATE_USERS=true

Auth0

SSO_ENABLED=true
SSO_GENERIC_ENABLED=true
SSO_GENERIC_PROVIDER_ID=auth0
SSO_GENERIC_DISPLAY_NAME="Auth0"
SSO_GENERIC_CLIENT_ID=your-auth0-client-id
SSO_GENERIC_CLIENT_SECRET=your-auth0-client-secret
SSO_GENERIC_AUTHORIZATION_URL=https://your-tenant.auth0.com/authorize
SSO_GENERIC_TOKEN_URL=https://your-tenant.auth0.com/oauth/token
SSO_GENERIC_USERINFO_URL=https://your-tenant.auth0.com/userinfo
SSO_GENERIC_ISSUER=https://your-tenant.auth0.com/
SSO_GENERIC_SCOPE="openid profile email"

Authentik

SSO_ENABLED=true
SSO_GENERIC_ENABLED=true
SSO_GENERIC_PROVIDER_ID=authentik
SSO_GENERIC_DISPLAY_NAME="Authentik"
SSO_GENERIC_CLIENT_ID=your-client-id
SSO_GENERIC_CLIENT_SECRET=your-secret
SSO_GENERIC_AUTHORIZATION_URL=https://authentik.example.com/application/o/authorize/
SSO_GENERIC_TOKEN_URL=https://authentik.example.com/application/o/token/
SSO_GENERIC_USERINFO_URL=https://authentik.example.com/application/o/userinfo/
SSO_GENERIC_ISSUER=https://authentik.example.com/application/o/mcp-gateway/

Files to Update

Core

  • mcpgateway/config.py - Add configuration fields
  • mcpgateway/utils/sso_bootstrap.py - Add bootstrap logic
  • mcpgateway/services/support_bundle_service.py - Exclude secret

Tests

  • tests/unit/mcpgateway/services/test_support_bundle_service.py - Add assertion
  • tests/unit/mcpgateway/services/test_sso_user_normalization.py - Already has generic OIDC tests

Documentation

  • README.md - Add environment variables table
  • .env.example - Add configuration section
  • docs/config.schema.json - Add JSON schema entries
  • docs/docs/manage/sso.md - Add generic OIDC section
  • docs/docs/manage/sso-generic-oidc-tutorial.md - Create tutorial
  • docs/docs/manage/.pages - Add navigation
  • docs/docs/architecture/security-features.md - Update SSO list
  • charts/mcp-stack/values.yaml - Add Helm values

UI (Optional Enhancement)

  • mcpgateway/templates/login.html - Support configurable icon/color

Benefits

  1. Parity: Same configuration UX as GitHub/Google/Okta/Entra ID
  2. DevOps-Friendly: Infrastructure-as-Code via env vars
  3. No API Calls: Provider configured at startup
  4. Security: Secrets managed via vault/secret management
  5. Flexibility: Support any OIDC-compliant provider
  6. Common Providers: First-class support for Keycloak, Auth0, Authentik

Notes

  • Generic OIDC normalization already exists - no code changes needed
  • This is additive - doesn't affect Admin API provider creation
  • Can coexist with GitHub/Google/Okta/Entra ID
  • Multiple generic providers still require Admin API (by design)

Related Issues

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions