{"id":16892,"library":"remix-keycloak","title":"Remix Auth Keycloak Strategy","description":"remix-keycloak is an authentication strategy for Remix applications, specifically designed to integrate with Keycloak identity and access management. It extends the `remix-auth` library's `OAuth2Strategy` to provide a robust solution for authenticating users via a Keycloak instance. Maintained by Cybernite Intelligence, this package serves as a direct successor and active continuation of the now-archived `remix-auth-keycloak`. The current stable version is 2.0.4. While there isn't a fixed release cadence, updates are made as needed to ensure compatibility with Remix v1 and v2, and to address Keycloak-related changes. A key differentiator is its commitment to supporting multiple runtimes, including Node.js, Cloudflare Workers, and Netlify functions, making it versatile for various deployment environments. It simplifies the setup of Keycloak-based authentication flows, including client ID/secret handling, callback URLs, and token management within a Remix context.","status":"active","version":"2.0.4","language":"javascript","source_language":"en","source_url":"https://github.com/marsmars0x01/remix-keycloak","tags":["javascript","remix","remix-auth","auth","authentication","strategy","keycloak","typescript"],"install":[{"cmd":"npm install remix-keycloak","lang":"bash","label":"npm"},{"cmd":"yarn add remix-keycloak","lang":"bash","label":"yarn"},{"cmd":"pnpm add remix-keycloak","lang":"bash","label":"pnpm"}],"dependencies":[{"reason":"Required by Remix for server-side utilities and request handling.","package":"@remix-run/server-runtime","optional":false}],"imports":[{"note":"The strategy class for Keycloak. Ensure you import from 'remix-keycloak', not the old 'remix-auth-keycloak' package.","wrong":"import { Keycloak } from 'remix-auth-keycloak'","symbol":"KeycloakStrategy","correct":"import { KeycloakStrategy } from 'remix-keycloak'"},{"note":"remix-keycloak integrates with remix-auth; Authenticator is imported from 'remix-auth', not remix-keycloak itself. This is standard for remix-auth strategies.","symbol":"Authenticator","correct":"import { Authenticator } from 'remix-auth'"},{"note":"Remix loaders handle GET requests. When setting up callback routes, the loader will typically be used for the initial authentication success/failure redirect.","symbol":"loader","correct":"export let loader: LoaderFunction = ({ request }) => { /* ... */ }"},{"note":"Remix actions handle POST requests. The action is used to initiate the Keycloak authentication flow, usually via a form submission.","symbol":"action","correct":"export let action: ActionFunction = ({ request }) => { /* ... */ }"}],"quickstart":{"code":"import { Authenticator } from \"remix-auth\";\nimport { KeycloakStrategy } from \"remix-keycloak\";\nimport { createCookieSessionStorage } from \"@remix-run/node\";\n\ninterface User {\n  id: string;\n  email: string;\n  name: string;\n}\n\n// Create a session storage for the authenticator\nconst sessionStorage = createCookieSessionStorage({\n  cookie: {\n    name: \"_session\",\n    sameSite: \"lax\",\n    path: \"/\",\n    httpOnly: true,\n    secrets: [process.env.SESSION_SECRET ?? 'super-secret-key'],\n    secure: process.env.NODE_ENV === \"production\",\n  },\n});\n\nexport const authenticator = new Authenticator<User>(sessionStorage);\n\nconst keycloakStrategy = new KeycloakStrategy(\n  {\n    useSSL: process.env.KEYCLOAK_USE_SSL === 'true',\n    domain: process.env.KEYCLOAK_DOMAIN ?? 'your-keycloak-domain.com',\n    realm: process.env.KEYCLOAK_REALM ?? 'your-realm',\n    clientID: process.env.KEYCLOAK_CLIENT_ID ?? 'your-client-id',\n    clientSecret: process.env.KEYCLOAK_CLIENT_SECRET ?? 'your-client-secret',\n    callbackURL: process.env.KEYCLOAK_CALLBACK_URL ?? 'http://localhost:3000/auth/keycloak/callback',\n  },\n  async ({ accessToken, refreshToken, extraParams, profile }) => {\n    // In a real application, you would typically find or create a user in your DB\n    // based on the profile data from Keycloak.\n    console.log(\"Keycloak Profile:\", profile);\n    console.log(\"Access Token:\", accessToken);\n    // For this example, we'll return a mock user\n    return {\n      id: profile.id || profile.emails?.[0]?.value || 'anonymous',\n      email: profile.emails?.[0]?.value || 'user@example.com',\n      name: profile.displayName || 'Keycloak User'\n    };\n  }\n);\n\nauthenticator.use(keycloakStrategy, \"keycloak\");\n\n// Example route: app/routes/login.tsx\n// export default function Login() {\n//   return (\n//     <form action=\"/auth/keycloak\" method=\"post\">\n//       <button>Login with Keycloak</button>\n//     </form>\n//   );\n// }\n\n// Example route: app/routes/auth/keycloak.tsx\n// import type { ActionFunction } from \"@remix-run/node\";\n// import { authenticator } from \"~/utils/auth.server\"; // Adjust path as needed\n\n// export let action: ActionFunction = ({ request }) => {\n//   return authenticator.authenticate(\"keycloak\", request);\n// };\n\n// Example route: app/routes/auth/keycloak/callback.tsx\n// import type { LoaderFunction } from \"@remix-run/node\";\n// import { redirect } from \"@remix-run/node\";\n// import { authenticator } from \"~/utils/auth.server\"; // Adjust path as needed\n\n// export let loader: LoaderFunction = ({ request }) => {\n//   return authenticator.authenticate(\"keycloak\", request, {\n//     successRedirect: \"/dashboard\",\n//     failureRedirect: \"/login\",\n//   });\n// };","lang":"typescript","description":"This quickstart demonstrates how to set up `KeycloakStrategy` with `remix-auth`, configure environment variables, and define the authentication and callback routes required for a complete Keycloak login flow in a Remix application. It also shows a basic `User` interface and session storage setup."},"warnings":[{"fix":"Uninstall `remix-auth-keycloak` and install `remix-keycloak`. Update all import paths to reference `remix-keycloak`.","message":"This package is a direct replacement for `remix-auth-keycloak`, which was archived on December 2nd, 2023. Users migrating from the old package must update their `package.json` and all import statements from `remix-auth-keycloak` to `remix-keycloak`.","severity":"breaking","affected_versions":"<2.0.0"},{"fix":"Ensure all Keycloak configuration parameters match your Keycloak client setup precisely, especially `clientID`, `clientSecret`, and `callbackURL`. The `callbackURL` must be registered in Keycloak for your client.","message":"The `KeycloakStrategy` requires several configuration options (domain, realm, clientID, clientSecret, callbackURL) that are critical for connecting to your Keycloak instance. Incorrect values will lead to authentication failures.","severity":"gotcha","affected_versions":">=2.0.0"},{"fix":"Set `useSSL: true` in your `KeycloakStrategy` configuration when deploying to production environments. Ensure your Keycloak instance and your Remix application are accessible via HTTPS.","message":"For production deployments, `useSSL` should almost always be `true`. Misconfiguring SSL can lead to security vulnerabilities or connection issues, especially when Keycloak is served over HTTPS.","severity":"gotcha","affected_versions":">=2.0.0"},{"fix":"Verify that the `callbackURL` in your strategy instance is identical to an authorized redirect URI in your Keycloak client settings. Include the full URL, including protocol and port if applicable.","message":"The authentication `callbackURL` configured in `KeycloakStrategy` must exactly match one of the valid redirect URIs configured for your client in the Keycloak admin console. A mismatch will result in a redirect error from Keycloak.","severity":"gotcha","affected_versions":">=2.0.0"}],"env_vars":null,"last_verified":"2026-04-22T00:00:00.000Z","next_check":"2026-07-21T00:00:00.000Z","problems":[{"fix":"Ensure that `authenticator.use(keycloakStrategy, \"keycloak\")` is called with the correct strategy name and that the `authenticator.authenticate(\"keycloak\", request, ...)` calls in your routes also use `\"keycloak\"`.","cause":"This usually indicates that the `authenticator.authenticate` call in your Remix action or loader is not correctly configured or the strategy name ('keycloak' by default) doesn't match.","error":"Error: Response not found for strategy \"keycloak\""},{"fix":"Verify that `export const authenticator = new Authenticator<User>(sessionStorage);` is in a server-side utility file (e.g., `app/utils/auth.server.ts`) and is correctly imported into your route files.","cause":"The `authenticator` instance was not properly initialized or exported/imported in the file where it's being used.","error":"TypeError: Cannot read properties of undefined (reading 'authenticate')"},{"fix":"Double-check the `clientID`, `clientSecret`, and `callbackURL` in your `KeycloakStrategy` configuration against your Keycloak client settings. Pay close attention to trailing slashes and case sensitivity for the URL.","cause":"This error originates from the Keycloak server and means there's a mismatch in the `clientID`, `clientSecret`, or `callbackURL` provided by your Remix application and what Keycloak expects.","error":"Keycloak: Invalid client or redirect URI"}],"ecosystem":"npm","meta_description":null}