> keycloak
You are an expert in Keycloak, the open-source identity and access management solution by Red Hat. You help teams implement single sign-on (SSO), OAuth 2.0, OpenID Connect, SAML 2.0, user federation (LDAP/Active Directory), social login, multi-factor authentication, and fine-grained authorization — providing enterprise-grade identity management that can be self-hosted and customized.
curl "https://skillshub.wtf/TerminalSkills/skills/keycloak?format=md"Keycloak — Open-Source Identity and Access Management
You are an expert in Keycloak, the open-source identity and access management solution by Red Hat. You help teams implement single sign-on (SSO), OAuth 2.0, OpenID Connect, SAML 2.0, user federation (LDAP/Active Directory), social login, multi-factor authentication, and fine-grained authorization — providing enterprise-grade identity management that can be self-hosted and customized.
Core Capabilities
Setup
# docker-compose.yml — Keycloak with PostgreSQL
version: "3.8"
services:
keycloak:
image: quay.io/keycloak/keycloak:24.0
command: start-dev
environment:
KC_DB: postgres
KC_DB_URL: jdbc:postgresql://postgres:5432/keycloak
KC_DB_USERNAME: keycloak
KC_DB_PASSWORD: ${KC_DB_PASSWORD}
KEYCLOAK_ADMIN: admin
KEYCLOAK_ADMIN_PASSWORD: ${KC_ADMIN_PASSWORD}
KC_HOSTNAME: auth.example.com
KC_PROXY_HEADERS: xforwarded
ports:
- "8080:8080"
depends_on:
- postgres
postgres:
image: postgres:16
environment:
POSTGRES_DB: keycloak
POSTGRES_USER: keycloak
POSTGRES_PASSWORD: ${KC_DB_PASSWORD}
volumes:
- pg_data:/var/lib/postgresql/data
volumes:
pg_data:
Client Integration (Next.js)
// src/lib/auth.ts — Keycloak OIDC integration
import NextAuth from "next-auth";
import KeycloakProvider from "next-auth/providers/keycloak";
export const { handlers, signIn, signOut, auth } = NextAuth({
providers: [
KeycloakProvider({
clientId: process.env.KEYCLOAK_CLIENT_ID!,
clientSecret: process.env.KEYCLOAK_CLIENT_SECRET!,
issuer: `${process.env.KEYCLOAK_URL}/realms/${process.env.KEYCLOAK_REALM}`,
}),
],
callbacks: {
async jwt({ token, account }) {
if (account) {
token.accessToken = account.access_token;
token.refreshToken = account.refresh_token;
token.idToken = account.id_token;
}
return token;
},
async session({ session, token }) {
session.accessToken = token.accessToken as string;
return session;
},
},
});
Admin API
// Keycloak Admin REST API — manage users programmatically
const KEYCLOAK_URL = process.env.KEYCLOAK_URL;
const REALM = process.env.KEYCLOAK_REALM;
async function getAdminToken(): Promise<string> {
const res = await fetch(
`${KEYCLOAK_URL}/realms/master/protocol/openid-connect/token`,
{
method: "POST",
headers: { "Content-Type": "application/x-www-form-urlencoded" },
body: new URLSearchParams({
grant_type: "client_credentials",
client_id: "admin-cli",
client_secret: process.env.KEYCLOAK_ADMIN_SECRET!,
}),
},
);
const { access_token } = await res.json();
return access_token;
}
async function createUser(userData: {
username: string;
email: string;
firstName: string;
lastName: string;
}) {
const token = await getAdminToken();
await fetch(`${KEYCLOAK_URL}/admin/realms/${REALM}/users`, {
method: "POST",
headers: {
Authorization: `Bearer ${token}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
...userData,
enabled: true,
emailVerified: true,
credentials: [{ type: "password", value: "temp123", temporary: true }],
}),
});
}
async function assignRole(userId: string, roleName: string) {
const token = await getAdminToken();
// Get role
const rolesRes = await fetch(
`${KEYCLOAK_URL}/admin/realms/${REALM}/roles/${roleName}`,
{ headers: { Authorization: `Bearer ${token}` } },
);
const role = await rolesRes.json();
// Assign to user
await fetch(
`${KEYCLOAK_URL}/admin/realms/${REALM}/users/${userId}/role-mappings/realm`,
{
method: "POST",
headers: { Authorization: `Bearer ${token}`, "Content-Type": "application/json" },
body: JSON.stringify([role]),
},
);
}
Realm Configuration
## Key Concepts
### Realm
- Isolated namespace for users, clients, roles
- Each realm has its own login page, user database, settings
- Example: "production" realm, "staging" realm
### Clients
- Applications that authenticate via Keycloak
- Types: public (SPA), confidential (backend), bearer-only (API)
- Configure redirect URIs, CORS, token lifetimes
### Roles
- Realm roles: global across all clients (admin, user, moderator)
- Client roles: scoped to a specific application (api:read, api:write)
- Composite roles: combine multiple roles into one
### Identity Providers
- Social: Google, GitHub, Facebook, Apple, Microsoft
- Enterprise: SAML (Okta, Azure AD), LDAP, Active Directory
- Custom: any OIDC/SAML 2.0 provider
### Authentication Flows
- Username/password + OTP (TOTP/HOTP)
- WebAuthn (passkeys, security keys)
- Custom flows (conditional OTP, required actions)
Installation
# Docker (development)
docker run -p 8080:8080 -e KEYCLOAK_ADMIN=admin -e KEYCLOAK_ADMIN_PASSWORD=admin \
quay.io/keycloak/keycloak:24.0 start-dev
# Production
docker run -e KC_DB=postgres -e KC_HOSTNAME=auth.example.com \
quay.io/keycloak/keycloak:24.0 start --optimized
# Kubernetes (Helm)
helm install keycloak bitnami/keycloak
Best Practices
- Realm per environment — Separate realms for dev/staging/production; export/import configs between them
- Confidential clients for backends — Use client secret authentication; never expose secrets in frontend apps
- RBAC with roles — Map business roles (admin, editor, viewer) to Keycloak realm/client roles
- Social login — Enable Google/GitHub for developer tools, Google/Apple for consumer apps
- Token lifetimes — Access tokens: 5 minutes; refresh tokens: 30 days; balance security vs UX
- MFA for admins — Require TOTP or WebAuthn for all admin and privileged accounts
- User federation — Connect to existing LDAP/AD; Keycloak syncs users without migration
- Export realm config — Export realm as JSON; store in Git for reproducible deployments
> related_skills --same-repo
> zustand
You are an expert in Zustand, the small, fast, and scalable state management library for React. You help developers manage global state without boilerplate using Zustand's hook-based stores, selectors for performance, middleware (persist, devtools, immer), computed values, and async actions — replacing Redux complexity with a simple, un-opinionated API in under 1KB.
> zoho
Integrate and automate Zoho products. Use when a user asks to work with Zoho CRM, Zoho Books, Zoho Desk, Zoho Projects, Zoho Mail, or Zoho Creator, build custom integrations via Zoho APIs, automate workflows with Deluge scripting, sync data between Zoho apps and external systems, manage leads and deals, automate invoicing, build custom Zoho Creator apps, set up webhooks, or manage Zoho organization settings. Covers Zoho CRM, Books, Desk, Projects, Creator, and cross-product integrations.
> zod
You are an expert in Zod, the TypeScript-first schema declaration and validation library. You help developers define schemas that validate data at runtime AND infer TypeScript types at compile time — eliminating the need to write types and validators separately. Used for API input validation, form validation, environment variables, config files, and any data boundary.
> zipkin
Deploy and configure Zipkin for distributed tracing and request flow visualization. Use when a user needs to set up trace collection, instrument Java/Spring or other services with Zipkin, analyze service dependencies, or configure storage backends for trace data.