Skip to content

Keycloak Realm Setup

Gatez uses Keycloak as the identity provider for both portals. The gateway realm is auto-imported on first start from config/keycloak/gateway-realm.json.

Auto-Provisioned Resources

On docker compose up, Keycloak imports:

ResourceNamePurpose
RealmgatewayMain realm for all Gatez users
Clientoperator-portalPublic OIDC client for the operator portal (PKCE, no secret)
Clientdeveloper-portalPublic OIDC client for the developer portal (PKCE, no secret)

Client Configuration

Both portal clients use:

  • Protocol: OpenID Connect
  • Access Type: Public (no client secret — uses PKCE S256)
  • Standard Flow: Enabled (authorization code flow)
  • Direct Access Grants: Enabled (for testing with curl)
  • Valid Redirect URIs: https://operator.gatez.dev/* / https://developer.gatez.dev/* (and http://localhost:3003/* / http://localhost:3004/* for dev)
  • Web Origins: + (allows all origins matching redirect URIs)

Creating Demo Users

Via Admin API

bash
# Get admin token
KC_PASS="your-keycloak-admin-password"
TOKEN=$(curl -s -X POST "http://localhost:8081/realms/master/protocol/openid-connect/token" \
  -d "client_id=admin-cli" -d "username=admin" -d "password=$KC_PASS" \
  -d "grant_type=password" | python3 -c "import sys,json; print(json.load(sys.stdin)['access_token'])")

# Create operator user (platform admin)
curl -X POST "http://localhost:8081/admin/realms/gateway/users" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "username": "sarah.platform",
    "email": "sarah@company.com",
    "firstName": "Sarah",
    "lastName": "Chen",
    "enabled": true,
    "emailVerified": true,
    "credentials": [{"type": "password", "value": "demo123", "temporary": false}],
    "attributes": {"tenant_id": [""]}
  }'

# Create developer user (tenant user)
curl -X POST "http://localhost:8081/admin/realms/gateway/users" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "username": "raj.developer",
    "email": "raj@company.com",
    "firstName": "Raj",
    "lastName": "Patel",
    "enabled": true,
    "emailVerified": true,
    "credentials": [{"type": "password", "value": "demo123", "temporary": false}],
    "attributes": {"tenant_id": ["retail"]}
  }'

Via Admin Console

  1. Navigate to https://keycloak.yourdomain.com (or http://localhost:8081)
  2. Login with admin credentials
  3. Select the gateway realm
  4. Go to Users -> Add user
  5. Set username, email, first/last name
  6. Under Credentials, set a password (toggle "Temporary" off)
  7. Under Attributes, add tenant_id with the tenant identifier

Role Mapping

Gatez uses JWT claims for authorization:

ClaimSourceUsed By
preferred_usernameKeycloak user profileDisplay name in portals
emailKeycloak user profileUser identification
realm_access.rolesRealm rolesAuthorization (platform-admin, tenant-admin, tenant-user)
tenant_idUser attributeMulti-tenant scoping

Key Roles

RolePortalCapabilities
platform-adminOperatorFull access to all tenants, routes, analytics, settings
tenant-adminBothManage users, keys, and settings for their tenant
tenant-userDeveloperView APIs, request keys, view own usage

SAML / SSO Brokering

For enterprise customers using their own IdP (Okta, Azure AD, etc.):

  1. Configure via API: PUT /api/tenants/:id/saml-config with IdP metadata URL
  2. Keycloak brokering: Gatez stores the SAML config and provides Keycloak brokering instructions
  3. The operator portal has a SAML tab in the tenant drawer for configuration

See the SSO documentation for MCP_OAUTH_* variables.

Production Checklist

  • [ ] Change KEYCLOAK_ADMIN_PASSWORD from default
  • [ ] Configure Valid Redirect URIs to match your domain (not localhost)
  • [ ] Enable HTTPS (Keycloak behind Caddy with auto-TLS)
  • [ ] Create real users (not demo accounts)
  • [ ] Set up realm email for password reset flows
  • [ ] Configure session timeouts appropriate for your security policy

Enterprise API + AI + Agent Gateway