Skip to content
Back to skills

3031 Sso Keycloak Tutorial Bc429daa

BSecurity

This tutorial walks you through setting up Keycloak Single Sign-On (SSO) authentication for ContextForge, enabling enterprise identity management with the popular open-source identity and access management solution.

  • 9 stars
  • 0 votes
  • 0 copies
  • 1 view
  • Added June 1, 2026
securityrustgobashdockerkubernetesazuretestinggitapidatabase

Works with

  • cli
  • api
  • mcp

Security analysis

B84/100
  • mediumUses curl or wget to download content
  • criticalExfiltrates credentials via HTTP — exact pattern from Snyk ToxicSkills study

Pro scans all 2 files and shows the line behind each finding

Scanned June 1, 2026

npx -y skills add tools-only/X-Skills --skill 3031-sso-keycloak-tutorial_bc429daa --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of 3031 Sso Keycloak Tutorial Bc429daa?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for 3031 Sso Keycloak Tutorial Bc429daa
[![Security: B — Skills Directory](https://www.skillsdirectory.com/api/skills/tools-only-3031-sso-keycloak-tutorial-bc429daa/badge)](https://www.skillsdirectory.com/skills/tools-only-3031-sso-keycloak-tutorial-bc429daa)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
# Keycloak OIDC Setup Tutorial

This tutorial walks you through setting up Keycloak Single Sign-On (SSO) authentication for ContextForge, enabling enterprise identity management with the popular open-source identity and access management solution.

## Quick Start (Docker Compose)

Use the preconfigured local SSO stack to test Keycloak end-to-end without external IdP setup:

```bash
make compose-sso
make sso-test-login
```

Or run directly with compose:

```bash
docker compose -f docker-compose.yml -f docker-compose.sso.yml --profile sso up -d
```

Preconfigured local endpoints and credentials:

- Gateway UI: `http://localhost:8080/admin/login`
- Keycloak admin console: `http://localhost:8180` (`admin` / `changeme`)
- Keycloak realm: `mcp-gateway`
- Keycloak client: `mcp-gateway`
- Callback URL: `http://localhost:8080/auth/sso/callback/keycloak`
- Compose wiring: internal Keycloak URL `http://keycloak:8080`, browser URL `http://localhost:8180`
- Test users (all password `changeme`):
  - `admin@example.com`
  - `developer@example.com`
  - `viewer@example.com`
  - `newuser@example.com`

## Prerequisites

- ContextForge installed and running
- Keycloak instance with admin access (self-hosted or cloud)
- Keycloak admin console access with appropriate permissions
- Access to your gateway's environment configuration

## Step 1: Access Keycloak Admin Console

### 1.1 Log into Keycloak

1. Navigate to your Keycloak admin console (typically at `https://keycloak.yourcompany.com/admin`)
2. Log in with your administrator credentials
3. Select the realm you want to use (or create a new one)

   - Default realm: `master`
   - For production, consider creating a dedicated realm

### 1.2 Create or Select Realm

**Creating a New Realm** (Optional):

1. Hover over the realm dropdown in the top-left corner
2. Click **Create Realm**
3. Enter realm details:

   - **Realm name**: `mcp-gateway` (or your preferred name)
   - **Enabled**: Yes

4. Click **Create**

**Using Existing Realm**:

- If using the default `master` realm or an existing realm, simply select it from the dropdown

## Step 2: Create Client in Keycloak

### 2.1 Navigate to Clients

1. In the left sidebar, click **Clients**
2. Click **Create client** button
3. You'll configure the client in the following steps

### 2.2 Configure Client Settings - General Settings

On the **General Settings** page:

**Client type**: `OpenID Connect`

**Client ID**: `mcp-gateway`
- This is your `SSO_KEYCLOAK_CLIENT_ID`
- Use a descriptive name for your organization

Click **Next**

### 2.3 Configure Client Settings - Capability Config

On the **Capability config** page:

**Client authentication**: `On` (required for confidential clients)

**Authorization**: `Off` (not needed for basic SSO)

**Authentication flow**: Select the following:

- ✅ **Standard flow** - Enables authorization code flow (required)
- ✅ **Direct access grants** - Enables direct access (optional, for API access)
- ❌ **Implicit flow** - Leave unchecked (deprecated)
- ❌ **Service accounts roles** - Leave unchecked (unless needed)

Click **Next**

### 2.4 Configure Client Settings - Login Settings

On the **Login settings** page:

**Root URL**: `https://gateway.yourcompany.com`
- For development: `http://localhost:8000`

**Home URL**: `https://gateway.yourcompany.com`

**Valid redirect URIs**: `https://gateway.yourcompany.com/auth/sso/callback/keycloak`
- For development, add: `http://localhost:8000/auth/sso/callback/keycloak`
- You can add multiple redirect URIs (one per line)

**Valid post logout redirect URIs**: `https://gateway.yourcompany.com/admin/login`
- Redirects users after logout

**Web origins**: `https://gateway.yourcompany.com`
- For CORS support
- Use `+` to allow all valid redirect URIs

Click **Save**

### 2.5 Note Client Credentials

After creating the client:

1. Navigate to the **Credentials** tab
2. Copy the **Client secret** value - This is your `SSO_KEYCLOAK_CLIENT_SECRET`
3. **IMPORTANT**: Store this secret securely (use a password manager or vault)
4. The Client ID is visible in the **Settings** tab

## Step 3: Configure Client Scopes and Mappers

### 3.1 Configure Client Scopes

Keycloak includes default scopes for OpenID Connect. Verify these are enabled:

1. In your client's settings, go to **Client scopes** tab
2. Verify these **Assigned default client scopes**:

   - ✅ `email` - Email address scope
   - ✅ `profile` - Basic profile information
   - ✅ `roles` - User roles
   - ✅ `web-origins` - CORS origins

If any are missing, click **Add client scope** and select them from the **Default** type.

### 3.2 Add Custom Mappers (Optional)

To include additional claims in tokens:

1. Go to **Client scopes** → Select a scope (e.g., `profile`)
2. Go to **Mappers** tab
3. Click **Add mapper** → **By configuration**
4. Choose mapper type based on what you need:

**Group Membership Mapper**:

- **Name**: `groups`
- **Mapper Type**: `Group Membership`
- **Token Claim Name**: `groups`
- **Full group path**: Off (for simple group names)
- **Add to ID token**: On
- **Add to access token**: On
- **Add to userinfo**: On

**User Attribute Mapper** (for custom attributes):

- **Name**: `department`
- **Mapper Type**: `User Attribute`
- **User Attribute**: `department`
- **Token Claim Name**: `department`
- **Claim JSON Type**: `String`
- **Add to ID token**: On
- **Add to access token**: On
- **Add to userinfo**: On

## Step 4: Configure Realm and Client Roles

### 4.1 Create Realm Roles

Realm roles apply across all clients in the realm:

1. In the left sidebar, click **Realm roles**
2. Click **Create role**
3. Create roles for your organization:

**Example roles**:

- **Role name**: `gateway-admin`
- **Description**: Administrator role for ContextForge
- Click **Save**

Repeat for additional roles:

- `gateway-user` - Standard user
- `gateway-developer` - Developer access
- `gateway-viewer` - Read-only access

### 4.2 Create Client Roles (Optional)

Client roles are specific to ContextForge client:

1. Navigate to **Clients** → Select your `mcp-gateway` client
2. Go to **Roles** tab
3. Click **Create role**
4. Create client-specific roles:

**Example roles**:

- `admin` - Client admin
- `member` - Client member
- `viewer` - Client viewer

### 4.3 Assign Roles to Users

1. Go to **Users** in the left sidebar
2. Find and select a user
3. Go to **Role mapping** tab
4. Click **Assign role**
5. Select roles to assign:

   - Filter by **Realm roles** or client name
   - Check desired roles
   - Click **Assign**

### 4.4 Configure Role Mappers

To include roles in JWT tokens:

1. Go to **Client scopes** → **roles**
2. Go to **Mappers** tab
3. Verify these mappers exist:

**realm roles**:

- Maps realm roles to `realm_access.roles` claim
- Should be enabled by default

**client roles**:

- Maps client roles to `resource_access.{client_id}.roles` claim
- Should be enabled by default

If missing, create them manually using **Add mapper** → **By configuration** → **User Realm Role** or **User Client Role**.

## Step 5: Configure User Attributes and Groups

### 5.1 Create Groups (Optional)

Groups provide hierarchical organization:

1. In the left sidebar, click **Groups**
2. Click **Create group**
3. Enter group details:

   - **Name**: `Developers`
   - Click **Create**

Create additional groups as needed:

- `Administrators`
- `Operations`
- `Support`

### 5.2 Assign Users to Groups

1. Go to **Users** → Select a user
2. Go to **Groups** tab
3. Click **Join Group**
4. Select desired groups
5. Click **Join**

### 5.3 Add Group Mappers

To include group membership in tokens:

1. Go to **Client scopes** → **profile** (or create custom scope)
2. Go to **Mappers** tab
3. Verify or create **Group Membership** mapper (see Step 3.2)

## Step 6: Configure ContextForge Environment

### 6.1 Keycloak Auto-Discovery Feature

Keycloak provides OpenID Connect auto-discovery, which **reduces configuration from 10 environment variables to just 6**:

- **No need to specify**: Authorization URL, Token URL, Userinfo URL, JWKS URI
- **Only specify**: Base URL, Realm, Client ID, Client Secret

The gateway automatically discovers endpoints from:
```
https://your-keycloak.com/realms/{realm}/.well-known/openid-configuration
```

### 6.2 Update Environment Variables

Add these variables to your `.env` file:

```bash
# Enable SSO System
SSO_ENABLED=true

# Keycloak OIDC Configuration
SSO_KEYCLOAK_ENABLED=true
SSO_KEYCLOAK_BASE_URL=https://keycloak.yourcompany.com
SSO_KEYCLOAK_REALM=master
SSO_KEYCLOAK_CLIENT_ID=mcp-gateway
SSO_KEYCLOAK_CLIENT_SECRET=your-client-secret-from-keycloak

# Optional: Role mapping configuration
SSO_KEYCLOAK_MAP_REALM_ROLES=true
SSO_KEYCLOAK_MAP_CLIENT_ROLES=false

# Optional: Custom JWT claim mapping
SSO_KEYCLOAK_USERNAME_CLAIM=preferred_username
SSO_KEYCLOAK_EMAIL_CLAIM=email
SSO_KEYCLOAK_GROUPS_CLAIM=groups

# Optional: Auto-create users on first login
SSO_AUTO_CREATE_USERS=true

# Optional: Restrict to corporate email domains
SSO_TRUSTED_DOMAINS=["yourcompany.com"]

# Optional: Preserve local admin authentication
SSO_PRESERVE_ADMIN_AUTH=true
```

### 6.3 Example Production Configuration

```bash
# Production Keycloak SSO Setup
SSO_ENABLED=true
SSO_KEYCLOAK_ENABLED=true
SSO_KEYCLOAK_BASE_URL=https://keycloak.acmecorp.com
SSO_KEYCLOAK_REALM=production
SSO_KEYCLOAK_CLIENT_ID=mcp-gateway-prod
SSO_KEYCLOAK_CLIENT_SECRET=[REDACTED]

# Role mapping - include realm roles, exclude client roles
SSO_KEYCLOAK_MAP_REALM_ROLES=true
SSO_KEYCLOAK_MAP_CLIENT_ROLES=false

# Custom claims for enterprise directory
SSO_KEYCLOAK_USERNAME_CLAIM=preferred_username
SSO_KEYCLOAK_EMAIL_CLAIM=email
SSO_KEYCLOAK_GROUPS_CLAIM=groups

# Enterprise security settings
SSO_AUTO_CREATE_USERS=true
SSO_TRUSTED_DOMAINS=["acmecorp.com"]
SSO_PRESERVE_ADMIN_AUTH=true
```

### 6.4 Development Configuration

```bash
# Development Keycloak SSO Setup
SSO_ENABLED=true
SSO_KEYCLOAK_ENABLED=true
SSO_KEYCLOAK_BASE_URL=http://localhost:8080
SSO_KEYCLOAK_REALM=master
SSO_KEYCLOAK_CLIENT_ID=mcp-gateway-dev
SSO_KEYCLOAK_CLIENT_SECRET=dev-client-secret-value

# More permissive for testing
SSO_KEYCLOAK_MAP_REALM_ROLES=true
SSO_KEYCLOAK_MAP_CLIENT_ROLES=true
SSO_AUTO_CREATE_USERS=true
SSO_PRESERVE_ADMIN_AUTH=true
```

### 6.5 Multi-Realm Configuration

For organizations with multiple realms:

```bash
# Development Realm
SSO_KEYCLOAK_REALM=development
SSO_KEYCLOAK_CLIENT_ID=mcp-gateway-dev
# Redirect: https://gateway-dev.yourcompany.com/auth/sso/callback/keycloak

# Staging Realm
SSO_KEYCLOAK_REALM=staging
SSO_KEYCLOAK_CLIENT_ID=mcp-gateway-staging
# Redirect: https://gateway-staging.yourcompany.com/auth/sso/callback/keycloak

# Production Realm
SSO_KEYCLOAK_REALM=production
SSO_KEYCLOAK_CLIENT_ID=mcp-gateway-prod
# Redirect: https://gateway.yourcompany.com/auth/sso/callback/keycloak
```

### 6.6 Configuration Variables Reference

| Variable | Required | Default | Description |
|----------|----------|---------|-------------|
| `SSO_KEYCLOAK_ENABLED` | Yes | `false` | Enable Keycloak SSO provider |
| `SSO_KEYCLOAK_BASE_URL` | Yes | - | Base URL of Keycloak instance |
| `SSO_KEYCLOAK_PUBLIC_BASE_URL` | No | _unset_ | Browser-facing Keycloak URL used for authorization redirects when gateway uses an internal URL |
| `SSO_KEYCLOAK_REALM` | Yes | `master` | Keycloak realm name |
| `SSO_KEYCLOAK_CLIENT_ID` | Yes | - | OAuth client ID from Keycloak |
| `SSO_KEYCLOAK_CLIENT_SECRET` | Yes | - | OAuth client secret from Keycloak |
| `SSO_KEYCLOAK_MAP_REALM_ROLES` | No | `true` | Include realm roles in user profile |
| `SSO_KEYCLOAK_MAP_CLIENT_ROLES` | No | `false` | Include client-specific roles |
| `SSO_KEYCLOAK_USERNAME_CLAIM` | No | `preferred_username` | JWT claim for username |
| `SSO_KEYCLOAK_EMAIL_CLAIM` | No | `email` | JWT claim for email |
| `SSO_KEYCLOAK_GROUPS_CLAIM` | No | `groups` | JWT claim for group membership |
| `SSO_KEYCLOAK_ROLE_MAPPINGS` | No | `{}` | JSON map of Keycloak roles/groups to Gateway RBAC roles |
| `SSO_KEYCLOAK_DEFAULT_ROLE` | No | _unset_ | Fallback role when no mapping matches |
| `SSO_KEYCLOAK_RESOLVE_TEAM_SCOPE_TO_PERSONAL_TEAM` | No | `false` | Resolve team-scoped mapped roles to the user's personal team |

## Step 7: Restart and Verify Gateway

### 7.1 Restart the Gateway

```bash
# Development
make dev

# Or directly with uvicorn
uvicorn mcpgateway.main:app --reload --host 0.0.0.0 --port 8000

# Production
make serve
```

### 7.2 Verify Keycloak SSO is Enabled

Test that Keycloak appears in SSO providers:

```bash
# Check if Keycloak is listed
curl -X GET http://localhost:8000/auth/sso/providers

# Should return Keycloak in the list:
[
  {
    "id": "keycloak",
    "name": "keycloak",
    "display_name": "Keycloak"
  }
]
```

### 7.3 Check Startup Logs

Verify no errors in the logs:

```bash
# Look for SSO initialization messages
tail -f logs/gateway.log | grep -i keycloak

# Should see:
# INFO: SSO provider 'keycloak' initialized successfully
# INFO: Keycloak auto-discovery loaded endpoints from https://.../.well-known/openid-configuration
```

### 7.4 Test Auto-Discovery Endpoint

Verify Keycloak's OIDC discovery endpoint is accessible:

```bash
# Test OIDC discovery
curl https://keycloak.yourcompany.com/realms/master/.well-known/openid-configuration

# Should return JSON with endpoints:
{
  "issuer": "https://keycloak.yourcompany.com/realms/master",
  "authorization_endpoint": "https://keycloak.yourcompany.com/realms/master/protocol/openid-connect/auth",
  "token_endpoint": "https://keycloak.yourcompany.com/realms/master/protocol/openid-connect/token",
  "userinfo_endpoint": "https://keycloak.yourcompany.com/realms/master/protocol/openid-connect/userinfo",
  ...
}
```

## Step 8: Test Keycloak SSO Login

### 8.1 Access Login Page

1. Navigate to your gateway's login page:

   - Development: `http://localhost:8000/admin/login`
   - Production: `https://gateway.yourcompany.com/admin/login`

2. You should see a "Keycloak" button with a key icon

### 8.2 Test Authentication Flow

1. Click **Continue with Keycloak**
2. You'll be redirected to Keycloak's sign-in page
3. Enter your Keycloak username and password
4. Complete multi-factor authentication if configured in Keycloak
5. Grant consent for the application if prompted (first-time users)
6. You'll be redirected back to the gateway admin panel
7. You should be logged in successfully

### 8.3 Verify User Creation

Check that a user was created in the gateway:

```bash
# Using the admin API (requires admin token)
curl -H "Authorization: Bearer YOUR_ADMIN_TOKEN" \
  http://localhost:8000/auth/users

# Look for your Keycloak email in the user list
```

### 8.4 Verify User Profile and Roles

Check that user attributes and roles were imported correctly:

```bash
# Get user details
curl -H "Authorization: Bearer YOUR_ADMIN_TOKEN" \
  http://localhost:8000/auth/users/{user_id}

# Verify fields are populated:
# - email: your@company.com
# - full_name: First Last
# - provider: keycloak
# - provider_id: unique-keycloak-id
# - roles: [list of realm/client roles if mapped]
# - groups: [list of groups if mapped]
```

### 8.5 Test Role Mapping

If `SSO_KEYCLOAK_MAP_REALM_ROLES=true`, verify roles are included:

```bash
# Decode JWT token to inspect claims
# Use https://jwt.io or a JWT decoding library

# Expected claims:
{
  "realm_access": {
    "roles": ["gateway-admin", "gateway-user"]
  },
  "resource_access": {
    "mcp-gateway": {
      "roles": ["admin", "member"]  # If MAP_CLIENT_ROLES=true
    }
  },
  "groups": ["/Developers", "/Administrators"]
}
```

## Step 9: Configure Advanced Features

### 9.1 Multi-Factor Authentication (MFA)

Configure MFA in Keycloak for enhanced security:

1. Go to **Authentication** in the left sidebar
2. Select **Flows** tab
3. Configure **Browser** flow:

   - Add **OTP Form** execution
   - Set to **Required**

4. Go to **Required Actions** tab
5. Enable **Configure OTP** for first-time setup

Users will be prompted to configure OTP (Google Authenticator, etc.) on first login.

### 9.2 Conditional Authentication

Create custom authentication flows:

1. Go to **Authentication** → **Flows**
2. Click **Create flow**
3. Add conditional logic:

   - **Condition - User Role**: Check if user has specific role
   - **Condition - User Attribute**: Check custom attributes
   - **OTP Form**: Require MFA for admins only

### 9.3 Identity Brokering

Connect Keycloak to external identity providers:

1. Go to **Identity Providers** in the left sidebar
2. Click **Add provider**
3. Select provider type:

   - **GitHub** - Social login
   - **Google** - Google Workspace
   - **Microsoft** - Azure AD/Entra ID
   - **SAML v2.0** - Enterprise SAML providers
   - **OpenID Connect** - Generic OIDC providers

Configure the provider and users can login through Keycloak using external accounts.

### 9.4 User Federation

Sync users from LDAP/Active Directory:

1. Go to **User federation** in the left sidebar
2. Click **Add LDAP providers** (or Kerberos)
3. Configure connection:

   - **Connection URL**: `ldap://ldap.company.com:389`
   - **Bind DN**: Service account DN
   - **Bind Credential**: Service account password

4. Configure user mapping:

   - **User Object Classes**: `person, organizationalPerson, user`
   - **Username LDAP attribute**: `sAMAccountName`
   - **RDN LDAP attribute**: `cn`
   - **UUID LDAP attribute**: `objectGUID`

5. Click **Test connection** and **Test authentication**
6. Click **Save**
7. Click **Synchronize all users** to import LDAP users

### 9.5 Custom Themes and Branding

Customize Keycloak's login page appearance:

1. Go to **Realm settings** → **Themes** tab
2. Configure themes:

   - **Login theme**: Custom branded login page
   - **Account theme**: Custom account management UI
   - **Email theme**: Branded email templates

3. Or create custom theme:

   - Place theme files in `themes/{theme-name}/` directory
   - Update realm theme settings
   - Restart Keycloak

### 9.6 Events and Monitoring

Configure audit logging:

1. Go to **Realm settings** → **Events** tab
2. **Login events settings**:

   - Enable **Save Events**: Yes
   - Set **Expiration**: 7 days (or longer for compliance)
   - Select events to log (Login, Logout, Register, etc.)

3. **Admin events settings**:

   - Enable **Save Events**: Yes
   - Enable **Include Representation**: Yes (for detailed audit)

View events:

- **Events** → **Login events**: User authentication events
- **Events** → **Admin events**: Configuration changes

## Step 10: Production Deployment Checklist

### 10.1 Security Requirements

- [ ] HTTPS enforced for all redirect URIs
- [ ] Client secrets stored securely (HashiCorp Vault, Kubernetes Secrets)
- [ ] MFA enabled for administrators
- [ ] MFA recommended or required for all users
- [ ] Strong password policies configured
- [ ] Session timeout configured appropriately
- [ ] Brute force detection enabled

### 10.2 Keycloak Configuration

- [ ] Client created with correct settings
- [ ] Client ID and client secret documented securely
- [ ] Redirect URIs match production URLs exactly
- [ ] Client scopes configured (email, profile, roles, groups)
- [ ] Required mappers added for custom claims
- [ ] Realm roles defined and assigned
- [ ] Client roles defined (if needed)
- [ ] Users assigned to appropriate roles
- [ ] Groups configured (if using group-based access)

### 10.3 Gateway Configuration

- [ ] Environment variables configured correctly
- [ ] Trusted domains configured for email restrictions
- [ ] `SSO_AUTO_CREATE_USERS` set appropriately
- [ ] `SSO_PRESERVE_ADMIN_AUTH` enabled (recommended)
- [ ] Role mapping settings configured (`MAP_REALM_ROLES`, `MAP_CLIENT_ROLES`)
- [ ] Custom claim mapping configured (username, email, groups)
- [ ] Logs configured for audit trail
- [ ] Auto-discovery endpoint accessible from gateway

### 10.4 Keycloak Hardening

- [ ] Keycloak database secured (TLS, strong passwords)
- [ ] Keycloak admin console access restricted (IP allowlist)
- [ ] Keycloak running behind reverse proxy (HTTPS termination)
- [ ] Keycloak realm settings reviewed for security
- [ ] Password policies enforced (complexity, history, expiration)
- [ ] Brute force detection enabled (failed login lockout)
- [ ] Events logging enabled for audit compliance
- [ ] LDAP/AD integration secured (if applicable)
- [ ] Regular Keycloak updates applied

### 10.5 Monitoring and Compliance

- [ ] Keycloak login events monitoring enabled
- [ ] Keycloak admin events monitoring enabled
- [ ] Gateway SSO logs reviewed regularly
- [ ] Alerting configured for authentication failures
- [ ] Regular access reviews scheduled
- [ ] Compliance reporting configured (if required)

## Troubleshooting

### Error: "SSO authentication is disabled"

**Problem**: SSO endpoints return 404
**Solution**: Set `SSO_ENABLED=true` and `SSO_KEYCLOAK_ENABLED=true`, then restart gateway

```bash
# Verify SSO is enabled
curl -I http://localhost:8000/auth/sso/providers
# Should return 200 OK
```

### Error: "Invalid client credentials"

**Problem**: Wrong client ID or client secret
**Solution**: Verify credentials from Keycloak admin console match exactly

```bash
# Double-check these values from Keycloak client settings
SSO_KEYCLOAK_CLIENT_ID=mcp-gateway  # From client General Settings
SSO_KEYCLOAK_CLIENT_SECRET=your-actual-secret  # From client Credentials tab
SSO_KEYCLOAK_REALM=master  # Realm name (case-sensitive)
```

Verify in Keycloak:

1. Go to **Clients** → Select your client
2. **Settings** tab: Verify Client ID
3. **Credentials** tab: Regenerate secret if needed

### Error: "redirect_uri_mismatch"

**Problem**: Keycloak redirect URI doesn't match
**Solution**: Verify exact URL match in Keycloak client configuration

```bash
# Keycloak redirect URI must exactly match:
https://your-domain.com/auth/sso/callback/keycloak

# Common mistakes:
https://your-domain.com/auth/sso/callback/keycloak/  # Extra slash
http://your-domain.com/auth/sso/callback/keycloak   # HTTP instead of HTTPS
https://your-domain.com/auth/sso/callback/generic   # Wrong provider ID
```

To fix:

1. Go to Keycloak Admin Console → **Clients** → Your client
2. Go to **Settings** tab
3. Update **Valid redirect URIs** field
4. Add exact callback URL (one per line)
5. Click **Save**

### Error: "User not found" or "Email not verified"

**Problem**: User email not verified in Keycloak
**Solution**: Verify user's email in Keycloak

1. Go to **Users** → Find user
2. Go to **Details** tab
3. Check **Email verified**: Set to **On**
4. Click **Save**

Or configure Keycloak to skip email verification:

1. Go to **Realm settings** → **Login** tab
2. Disable **Verify email**

### Error: "Failed to discover OIDC endpoints"

**Problem**: Auto-discovery endpoint not accessible
**Solution**: Verify Keycloak base URL and realm are correct

```bash
# Test discovery endpoint manually
curl https://keycloak.yourcompany.com/realms/master/.well-known/openid-configuration

# Should return JSON with OIDC endpoints
# If this fails, check:
# - Base URL is correct and accessible from gateway
# - Realm name is spelled correctly (case-sensitive)
# - Keycloak is running and healthy
# - Network/firewall rules allow access
```

### Error: "Invalid issuer in JWT token"

**Problem**: JWT issuer doesn't match expected value
**Solution**: Verify realm and base URL configuration

```bash
# Expected issuer format:
https://keycloak.yourcompany.com/realms/{realm}

# Common issues:
# - Base URL includes "/auth" path for older Keycloak versions (pre-17)
# - Realm name mismatch (case-sensitive)
# - Base URL with trailing slash

# For Keycloak < 17.0, use:
SSO_KEYCLOAK_BASE_URL=https://keycloak.yourcompany.com/auth

# For Keycloak >= 17.0, use:
SSO_KEYCLOAK_BASE_URL=https://keycloak.yourcompany.com
```

### Roles Not Appearing in JWT

**Problem**: User roles not included in JWT token
**Solution**: Configure role mappers and enable role mapping

1. Verify role mappers exist:

   - Go to **Client scopes** → **roles** → **Mappers**
   - Ensure **realm roles** and **client roles** mappers exist

2. Enable role mapping in gateway:
```bash
SSO_KEYCLOAK_MAP_REALM_ROLES=true
SSO_KEYCLOAK_MAP_CLIENT_ROLES=true
```

3. Assign roles to user:

   - Go to **Users** → Select user → **Role mapping**
   - Assign appropriate roles

### Groups Not Appearing in JWT

**Problem**: User groups not included in JWT token
**Solution**: Add group membership mapper

1. Go to **Client scopes** → **profile** (or custom scope)
2. Go to **Mappers** tab
3. Click **Add mapper** → **By configuration**
4. Select **Group Membership**:

   - **Name**: `groups`
   - **Token Claim Name**: `groups`
   - **Full group path**: Off
   - **Add to ID token**: On
   - **Add to userinfo**: On

5. Click **Save**

Update gateway configuration:
```bash
SSO_KEYCLOAK_GROUPS_CLAIM=groups
```

### Keycloak Admin Console Not Accessible

**Problem**: Cannot access Keycloak admin console
**Solution**: Check Keycloak configuration and network

1. Verify Keycloak is running:
```bash
# For containerized Keycloak
docker ps | grep keycloak

# Check Keycloak logs
docker logs keycloak-container
```

2. Check network and firewall rules
3. Verify admin user credentials
4. Reset admin password if needed:
```bash
# Inside Keycloak container
cd /opt/keycloak/bin
./kcadm.sh config credentials --server http://localhost:8080 --realm master --user admin
./kcadm.sh update realms/master -s enabled=true
```

## Testing Checklist

- [ ] Client created in Keycloak admin console
- [ ] Client ID and secret copied securely
- [ ] Redirect URIs configured correctly
- [ ] Client scopes assigned (email, profile, roles)
- [ ] Mappers configured for custom claims
- [ ] Realm roles created and assigned
- [ ] Users assigned to appropriate roles
- [ ] Groups configured (if applicable)
- [ ] Environment variables configured in gateway
- [ ] Gateway restarted with new config
- [ ] `/auth/sso/providers` returns Keycloak provider
- [ ] Login page shows Keycloak button
- [ ] Authentication flow completes successfully
- [ ] User created in gateway user list
- [ ] User profile populated with correct data
- [ ] Roles included in JWT (if `MAP_REALM_ROLES=true`)
- [ ] Groups included in JWT (if groups mapper configured)
- [ ] MFA working (if configured)
- [ ] LDAP sync working (if configured)

## Security Best Practices

### Secret Management

**DO**:

- ✅ Store client secrets in secure vault (HashiCorp Vault, Kubernetes Secrets)
- ✅ Rotate secrets regularly (every 90-180 days)
- ✅ Use separate clients for dev/staging/prod
- ✅ Use separate realms for environment isolation

**DON'T**:

- ❌ Store secrets in source control
- ❌ Share secrets via email or chat
- ❌ Use the same secret across environments
- ❌ Reuse secrets after exposure

### Access Control

1. **Principle of Least Privilege**: Only grant necessary roles
2. **Role-Based Access**: Use realm roles for broad access, client roles for specific permissions
3. **Group-Based Management**: Manage users via groups for easier administration
4. **Regular Reviews**: Audit user access quarterly
5. **Time-Limited Sessions**: Configure appropriate session timeouts

### Keycloak Hardening

1. **Admin Console Access**: Restrict to specific IPs or VPN
2. **Database Security**: Use TLS for database connections, strong passwords
3. **HTTPS Only**: Never run Keycloak on HTTP in production
4. **Brute Force Protection**: Enable lockout after failed login attempts
5. **Password Policies**: Enforce strong passwords (length, complexity, history)
6. **Regular Updates**: Keep Keycloak updated with latest security patches

### Monitoring

1. Enable **Login events** in Keycloak for authentication audit trail
2. Enable **Admin events** for configuration change tracking
3. Configure **Alerts** for suspicious authentication patterns
4. Review **Event logs** regularly for security incidents
5. Export logs to SIEM for centralized monitoring

## Benefits of Keycloak SSO

### Simplified Configuration

Keycloak's auto-discovery reduces configuration by **40%** compared to generic OIDC:

**Generic OIDC requires**:

- Authorization URL
- Token URL
- Userinfo URL
- Issuer URL
- JWKS URI (sometimes)

**Keycloak requires only**:

- Base URL
- Realm name
- Client ID
- Client secret

The gateway automatically discovers all endpoints from the well-known configuration.

### Enterprise Features

- **User Federation**: LDAP/Active Directory synchronization
- **Identity Brokering**: Connect to external IdPs (Google, GitHub, SAML)
- **Multi-Factor Authentication**: Built-in OTP and WebAuthn support
- **Fine-Grained Authorization**: Realm and client roles, group-based access
- **Customizable UI**: Branded login pages and themes
- **Events and Audit**: Comprehensive logging for compliance

### Open Source Advantages

- **Self-Hosted**: Full control over identity data
- **No Vendor Lock-In**: Standards-based OIDC/OAuth 2.0
- **Active Community**: Large ecosystem and plugin support
- **Cost-Effective**: No per-user licensing fees
- **Extensible**: Custom authenticators, mappers, and providers

## Next Steps

After Keycloak SSO is working:

1. **Configure MFA** for enhanced security
2. **Set up user federation** with LDAP/AD (if applicable)
3. **Configure identity brokering** for social login options
4. **Implement fine-grained authorization** with custom roles
5. **Customize login themes** for brand consistency
6. **Set up event logging** for audit compliance
7. **Configure session management** and timeout policies
8. **Implement group-based team mapping** in ContextForge
9. **Document your configuration** for team reference

## Related Documentation

- [Complete SSO Guide](sso.md) - Full SSO documentation
- [GitHub SSO Tutorial](sso-github-tutorial.md) - GitHub setup guide
- [Google SSO Tutorial](sso-google-tutorial.md) - Google setup guide
- [IBM Security Verify Tutorial](sso-ibm-tutorial.md) - IBM setup guide
- [Microsoft Entra ID Tutorial](sso-microsoft-entra-id-tutorial.md) - Microsoft Entra ID setup guide
- [Okta SSO Tutorial](sso-okta-tutorial.md) - Okta setup guide
- [Generic OIDC Tutorial](sso-generic-oidc-tutorial.md) - Generic OIDC providers
- [Team Management](teams.md) - Managing teams and roles
- [RBAC Configuration](rbac.md) - Role-based access control

## Support and Resources

### Keycloak Documentation

- [Keycloak Official Documentation](https://www.keycloak.org/documentation)
- [Server Administration Guide](https://www.keycloak.org/docs/latest/server_admin/)
- [Securing Applications Guide](https://www.keycloak.org/docs/latest/securing_apps/)
- [Authorization Services Guide](https://www.keycloak.org/docs/latest/authorization_services/)

### Troubleshooting Resources

1. **Keycloak Server Logs**: Check Keycloak logs for detailed authentication errors
2. **Gateway logs**: Enable `LOG_LEVEL=DEBUG` for detailed SSO flow logging
3. **OIDC Discovery**: Test `.well-known/openid-configuration` endpoint
4. **Keycloak Community**: Active community forums and mailing lists

### Getting Help

If you encounter issues:

1. Check Keycloak server logs for error messages
2. Verify OIDC discovery endpoint is accessible
3. Enable debug logging in gateway: `LOG_LEVEL=DEBUG`
4. Review gateway logs for Keycloak-specific errors
5. Test JWT token claims at [jwt.io](https://jwt.io)
6. Consult Keycloak documentation and community forums
7. Check [ContextForge issue tracker](https://github.com/IBM/mcp-context-forge/issues)

Files in this skill

  • README.md1002 B
  • skill.md30.8 KB

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.