✨ We just launched fimo.ai - an AI Website Builder to create websites in minutes - Try it now

Strapi plugin logo for Strapi Keycloak Passport

Strapi Keycloak Passport

Seamlessly integrate Keycloak authentication with Strapi Admin Panel.

thumbnail for Strapi Keycloak Passport

Strapi Keycloak Passport Plugin

Enterprise-grade Keycloak authentication for Strapi v5 Admin Panel with full RBAC support.

npm version License: MIT Strapi v5

Features

  • Single Sign-On (SSO) - Replace Strapi's default admin login with Keycloak OAuth2
  • Keycloak 17+ Support - Works with both modern (17+) and legacy Keycloak versions
  • Role Mapping - Dynamically map Keycloak roles to Strapi admin roles via UI
  • Token Caching - Intelligent caching with automatic refresh before expiry
  • Audit Logging - Comprehensive audit trail for all authentication events
  • Strapi RBAC Integration - Leverages Strapi's native Roles & Permissions
  • Secure by Default - Error sanitization, HttpOnly cookies, input validation

Requirements

  • Node.js >= 20.0.0
  • Strapi v5.x
  • Keycloak 17+ (or legacy with configuration flag)

Installation

yarn add strapi-keycloak-passport

or

npm install strapi-keycloak-passport

Configuration

Plugin Configuration

Add to your config/plugins.js (or config/plugins.ts):

module.exports = ({ env }) => ({
  'strapi-keycloak-passport': {
    enabled: env.bool('KEYCLOAK_ENABLED', true),
    config: {
      // Required: Keycloak server URL (without trailing slash)
      KEYCLOAK_AUTH_URL: env('KEYCLOAK_AUTH_URL', 'https://keycloak.example.com'),

      // Required: Keycloak realm name
      KEYCLOAK_REALM: env('KEYCLOAK_REALM', 'master'),

      // Required: OAuth client credentials
      KEYCLOAK_CLIENT_ID: env('KEYCLOAK_CLIENT_ID', 'strapi-admin'),
      KEYCLOAK_CLIENT_SECRET: env('KEYCLOAK_CLIENT_SECRET'),

      // Optional: Set to true for Keycloak versions < 17 (uses /auth prefix)
      KEYCLOAK_LEGACY_MODE: env.bool('KEYCLOAK_LEGACY_MODE', false),

      // Optional: Role configuration
      roleConfigs: {
        // Default Strapi role ID when no mapping exists
        defaultRoleId: env.int('KEYCLOAK_DEFAULT_ROLE_ID', 1),

        // Keycloak roles to exclude from the mapping UI
        excludedRoles: [
          'uma_authorization',
          'offline_access',
          'default-roles-master',
        ],
      },
    },
  },
});

Environment Variables

# Required
KEYCLOAK_AUTH_URL=https://keycloak.example.com
KEYCLOAK_REALM=master
KEYCLOAK_CLIENT_ID=strapi-admin
KEYCLOAK_CLIENT_SECRET=your-client-secret

# Optional
KEYCLOAK_ENABLED=true
KEYCLOAK_LEGACY_MODE=false
KEYCLOAK_DEFAULT_ROLE_ID=1

Keycloak Version Compatibility

Keycloak VersionKEYCLOAK_LEGACY_MODEURL Format
17+ (Quarkus)false (default)https://keycloak.example.com/realms/{realm}/...
< 17 (WildFly)truehttps://keycloak.example.com/auth/realms/{realm}/...

Keycloak Setup

1. Create an OAuth Client

  1. Navigate to Keycloak Admin ConsoleClients
  2. Click Create Client:
    • Client ID: strapi-admin
    • Client Protocol: openid-connect
    • Client Authentication: On (Confidential)
  3. Configure settings:
    • Root URL: https://your-strapi-instance.com
    • Valid Redirect URIs: https://your-strapi-instance.com/admin/*
    • Web Origins: https://your-strapi-instance.com
  4. Go to Credentials tab and copy the Client Secret

2. Assign Required Roles to Client

For the plugin to fetch user roles, the client needs realm-management permissions:

  1. Go to Clientsstrapi-adminService Account Roles
  2. Click Assign role
  3. Filter by realm-management client
  4. Assign these roles:
    • view-users
    • view-realm
    • manage-users (optional, for future features)

3. Create Keycloak Roles

  1. Go to Realm RolesCreate Role
  2. Create roles that will map to Strapi admin roles:
    • STRAPI_SUPER_ADMIN
    • STRAPI_EDITOR
    • STRAPI_AUTHOR

4. Assign Roles to Users

  1. Go to Users → Select a user → Role Mapping
  2. Assign the appropriate Keycloak role

Role Mapping

Managing Mappings via Admin UI

  1. Log in to Strapi Admin Panel
  2. Navigate to SettingsKeycloak Passport
  3. Map Keycloak roles to Strapi admin roles
  4. Click Save

Example Mapping

Keycloak RoleStrapi Role
STRAPI_SUPER_ADMINSuper Admin (1)
STRAPI_EDITOREditor (2)
STRAPI_AUTHORAuthor (3)

How It Works

  1. User logs in with Keycloak credentials
  2. Plugin fetches user's Keycloak roles
  3. Roles are mapped to Strapi roles using saved mappings
  4. If no mapping exists, user gets the defaultRoleId role
  5. User is created/updated in Strapi with assigned roles

Authentication Flow

┌─────────────┐                    ┌─────────────┐                    ┌─────────────┐
│    User     │                    │   Strapi    │                    │  Keycloak   │
└──────┬──────┘                    └──────┬──────┘                    └──────┬──────┘
       │                                  │                                  │
1. POST /admin/login            │                                  │
       │  (email + password)              │                                  │
       │─────────────────────────────────>│                                  │
       │                                  │                                  │
       │                                  │  2. OAuth2 Password Grant        │
       │                                  │─────────────────────────────────>
       │                                  │                                  │
       │                                  │  3. Access Token                 │
       │                                  │<─────────────────────────────────│
       │                                  │                                  │
       │                                  │  4. GET /userinfo                │
       │                                  │─────────────────────────────────>
       │                                  │                                  │
       │                                  │  5. User Info + Roles            │
       │                                  │<─────────────────────────────────│
       │                                  │                                  │
       │                                  │  6. Find/Create Admin User       │
       │                                  │  7. Map Roles                    │
       │                                  │  8. Generate Strapi JWT
       │                                  │                                  │
9. JWT Token + User             │                                  │
<─────────────────────────────────│                                  │
       │                                  │                                  │

API Endpoints

All endpoints are prefixed with /strapi-keycloak-passport/

MethodEndpointDescriptionAuth
POST/admin/loginAuthenticate via KeycloakNo
GET/keycloak-rolesFetch available Keycloak & Strapi rolesYes
GET/get-keycloak-role-mappingsGet saved role mappingsYes
POST/save-keycloak-role-mappingsSave role mappingsYes
GET/test-connectionTest Keycloak connectivityYes
GET/token-cache-statsGet token cache statisticsYes
POST/invalidate-tokenInvalidate cached admin tokenYes

Features in Detail

Token Caching

Admin tokens are cached in-memory with automatic refresh:

  • Tokens are cached using a composite key: serverUrl:realm:clientId
  • Automatic refresh triggered 60 seconds before expiry
  • Cache is invalidated when configuration changes
  • Monitor cache via /token-cache-stats endpoint

Audit Logging

All authentication events are logged to the database:

EventLogged Data
Login SuccessUser email, Keycloak ID, assigned roles, IP, user agent
Login FailureAttempted email, failure reason, IP, user agent
User CreatedEmail, Strapi ID, Keycloak ID, assigned roles
User UpdatedEmail, changed fields (roles, name, etc.)
Role Mapping ChangedKeycloak role, Strapi role, performed by

Query audit logs via Strapi's Content Manager or API.

Error Handling

The plugin implements a sanitized error pattern:

  • Internal errors are logged with full details for debugging
  • Client responses contain safe, generic messages
  • Sensitive information (tokens, secrets) never exposed in responses

Security Considerations

  • Client Secret: Store securely in environment variables, never commit
  • Token Storage: Admin tokens cached in-memory only, never persisted
  • Cookies: HttpOnly, Secure (in production), SameSite protection
  • Input Validation: All inputs validated before processing
  • Audit Trail: All authentication events logged for compliance

Troubleshooting

"Failed to authenticate with Keycloak"

  1. Verify KEYCLOAK_AUTH_URL is correct (no trailing slash)
  2. Check if KEYCLOAK_LEGACY_MODE matches your Keycloak version
  3. Confirm client secret is correct
  4. Ensure client has proper service account roles

"Failed to fetch roles from Keycloak"

  1. Verify the client has view-users and view-realm roles assigned
  2. Check Keycloak server logs for permission errors

"User gets wrong role"

  1. Check role mappings in Admin Panel
  2. Verify user has the expected role in Keycloak
  3. Check if role is in excludedRoles configuration

Test Connection

Use the built-in connection test:

curl -X GET "https://your-strapi.com/strapi-keycloak-passport/test-connection" \
  -H "Authorization: Bearer YOUR_ADMIN_TOKEN"

Changelog

v0.3.0

  • Added Keycloak 17+ support with KEYCLOAK_LEGACY_MODE option
  • Implemented token caching with automatic refresh
  • Added comprehensive audit logging
  • Refactored to centralized constants (no magic values)
  • Implemented error sanitization pattern
  • Added new endpoints: /test-connection, /token-cache-stats, /invalidate-token
  • Full JSDoc documentation
  • Simplified configuration (removed KEYCLOAK_TOKEN_URL, KEYCLOAK_USERINFO_URL)

v0.2.x

  • Initial release with basic Keycloak authentication
  • Role mapping UI
  • Strapi v5 compatibility

Contributing

Contributions are welcome! Please read our contributing guidelines before submitting PRs.

License

MIT License - see LICENSE for details.

Support

Install now

npm install strapi-keycloak-passport

STATS

3 GitHub stars28 weekly downloads

Last updated

4 days ago

Strapi Version

5.32.0 and above

Author

github profile image for LPIX-11
LPIX-11

Useful links

Create your own plugin

Check out the available plugin resources that will help you to develop your plugin or provider and get it listed on the marketplace.