supabase
Handles the full Supabase workflow from schema changes to deployment, with built-in security guardrails that catch common traps like RLS...
Expert guidance for Keycloak identity and access management including realm configuration, client setup, user federation, authentication flows, role-based access control, and integration with applications. Use this when setting up authentication, configuring SSO, managing users and roles, or inte...
Full skill instructions
Expert assistance with Keycloak identity and access management platform.
Keycloak is an open-source Identity and Access Management (IAM) solution providing:
# Run Keycloak
docker run -d \
--name keycloak \
-p 8080:8080 \
-e KEYCLOAK_ADMIN=admin \
-e KEYCLOAK_ADMIN_PASSWORD=admin \
quay.io/keycloak/keycloak:latest start-dev
# With PostgreSQL
docker run -d \
--name keycloak \
-p 8080:8080 \
-e KC_DB=postgres \
-e KC_DB_URL=jdbc:postgresql://localhost/keycloak \
-e KC_DB_USERNAME=keycloak \
-e KC_DB_PASSWORD=password \
-e KEYCLOAK_ADMIN=admin \
-e KEYCLOAK_ADMIN_PASSWORD=admin \
quay.io/keycloak/keycloak:latest start
version: '3'
services:
postgres:
image: postgres:15
environment:
POSTGRES_DB: keycloak
POSTGRES_USER: keycloak
POSTGRES_PASSWORD: password
volumes:
- postgres_data:/var/lib/postgresql/data
keycloak:
image: quay.io/keycloak/keycloak:latest
command: start
environment:
KC_DB: postgres
KC_DB_URL: jdbc:postgresql://postgres/keycloak
KC_DB_USERNAME: keycloak
KC_DB_PASSWORD: password
KEYCLOAK_ADMIN: admin
KEYCLOAK_ADMIN_PASSWORD: admin
KC_HOSTNAME: localhost
KC_HOSTNAME_PORT: 8080
KC_HOSTNAME_STRICT_HTTPS: false
KC_HTTP_ENABLED: true
ports:
- "8080:8080"
depends_on:
- postgres
volumes:
postgres_data:
# Build with PostgreSQL support
docker run \
-e KC_DB=postgres \
-e KC_FEATURES=token-exchange,admin-fine-grained-authz \
-e KC_HTTP_ENABLED=true \
-e KC_HOSTNAME_STRICT_HTTPS=false \
quay.io/keycloak/keycloak:latest build
# Run in production mode
docker run \
-p 8443:8443 \
-e KC_DB=postgres \
-e KC_DB_URL=jdbc:postgresql://postgres/keycloak \
-e KC_DB_USERNAME=keycloak \
-e KC_DB_PASSWORD=password \
-e KEYCLOAK_ADMIN=admin \
-e KEYCLOAK_ADMIN_PASSWORD=admin \
-e KC_HOSTNAME=auth.example.com \
-e KC_HTTPS_CERTIFICATE_FILE=/opt/keycloak/conf/server.crt \
-e KC_HTTPS_CERTIFICATE_KEY_FILE=/opt/keycloak/conf/server.key \
quay.io/keycloak/keycloak:latest start
Realm Settings:
- General
- Display name: My Application
- HTML Display name: <b>My App</b>
- Frontend URL: https://auth.example.com (optional)
- Login
- User registration: Enable to allow self-registration
- Edit username: Allow users to edit username
- Forgot password: Enable password reset
- Remember me: Allow remember me checkbox
- Login with email: Allow email as username
- Keys
- Active keys for signing tokens
- Configure providers (RSA, ECDSA, HMAC)
- Email
- From: [email protected]
- Host: smtp.example.com
- Port: 587
- Enable authentication
- Username/Password for SMTP
- Themes
- Login theme: keycloak (or custom)
- Account theme: keycloak
- Admin console theme: keycloak
- Email theme: keycloak
- Tokens
- Access Token Lifespan: 5 minutes
- Refresh Token Max Reuse: 0
- SSO Session Idle: 30 minutes
- SSO Session Max: 10 hours
OpenID Connect Client:
Client ID: my-app
Client Protocol: openid-connect
Root URL: http://localhost:3000
Settings:
- Client authentication: ON (for confidential clients)
- Authorization: OFF (unless using fine-grained authz)
- Valid redirect URIs:
- http://localhost:3000/*
- http://localhost:3000/api/auth/callback/keycloak
- Valid post logout redirect URIs:
- http://localhost:3000
- Web origins: http://localhost:3000
Capability config:
- Client authentication: ON
- Authorization: OFF
- Standard flow: ON (Authorization Code Flow)
- Direct access grants: ON (Resource Owner Password Credentials)
- Implicit flow: OFF (deprecated)
- Service accounts roles: ON (for client credentials)
After creating client with authentication ON:
Create custom scope:
1. Clients > Client scopes > Create
2. Name: custom-scope
3. Protocol: openid-connect
4. Display on consent: OFF
5. Include in token scope: ON
Add mappers:
1. Mappers tab > Create
2. Mapper type: User Property
3. Property: email
4. Token Claim Name: email
5. Claim JSON Type: String
Assign to client:
1. Clients > [your-client] > Client scopes
2. Add available scope to Assigned default scopes
Admin Console > Users > Create user
Username: john.doe
Email: [email protected]
Email verified: ON
First name: John
Last name: Doe
Enabled: ON
Credentials:
- Set password
- Temporary: OFF (user won't be forced to change)
Users > [user] > Attributes
Key: department
Value: engineering
Key: employee_id
Value: EMP-12345
1. Create roles:
Realm roles > Create role
- Name: admin
- Name: user
- Name: viewer
2. Assign to user:
Users > [user] > Role mapping
- Assign role: admin
1. Create group:
Groups > Create group
- Name: Developers
2. Add attributes to group:
Groups > Developers > Attributes
- team: backend
3. Assign roles to group:
Groups > Developers > Role mapping
- Assign: developer role
4. Add users to group:
Users > [user] > Groups
- Join: Developers
Realm roles > Create role
Name: super-admin
Description: Full system access
Composite roles:
- Add child roles (admin, user, viewer)
Clients > [client] > Roles > Create role
Name: app-admin
Description: Application administrator
Use case: Application-specific roles
Client scopes > roles > Mappers > realm roles
Add to token:
- Token Claim Name: realm_access.roles
- Claim JSON Type: String
- Add to ID token: ON
- Add to access token: ON
- Add to userinfo: ON
Authentication > Flows > Browser
Steps:
1. Cookie (SSO check)
2. Kerberos (optional)
3. Forms (username/password)
- Username password form
- OTP form (if enabled)
1. Duplicate existing flow:
Flows > Browser > Duplicate
2. Customize:
- Add execution
- Set requirement (REQUIRED, ALTERNATIVE, DISABLED)
3. Bind to client:
Clients > [client] > Advanced > Authentication flow overrides
- Browser flow: [custom-flow]
1. Enable OTP:
Authentication > Flows > Browser
- Add execution: OTP Form
- Requirement: CONDITIONAL
2. Configure OTP:
Authentication > OTP Policy
- Type: Time-based or Counter-based
- Algorithm: SHA1, SHA256, SHA512
- Digits: 6
- Period: 30 seconds
3. Users enable OTP:
Account console > Account security > Signing in
- Set up Authenticator Application
User Federation > Add provider > LDAP
Connection:
- Console display name: LDAP
- Edit mode: READ_ONLY or WRITEABLE
- Sync registrations: ON
- Vendor: Active Directory, Red Hat Directory Server, etc.
- Connection URL: ldap://ldap.example.com:389
- Users DN: ou=users,dc=example,dc=com
- Bind DN: cn=admin,dc=example,dc=com
- Bind credential: password
LDAP searching and updating:
- Custom user search filter: (objectClass=person)
- Search scope: Subtree
Synchronization:
- Batch size: 1000
- Full sync period: 604800 (weekly)
- Changed users sync period: 86400 (daily)
Test connection and authentication
public class CustomUserStorageProvider implements UserStorageProvider {
@Override
public UserModel getUserById(String id, RealmModel realm) {
// Fetch user from custom storage
}
@Override
public UserModel getUserByUsername(String username, RealmModel realm) {
// Lookup by username
}
@Override
public UserModel getUserByEmail(String email, RealmModel realm) {
// Lookup by email
}
}
Identity Providers > Add provider > Google
Settings:
- Client ID: [from Google Console]
- Client secret: [from Google Console]
- Default scopes: openid profile email
- Store tokens: ON
- Stored tokens readable: ON
Mappers:
- Create mapper: Import from provider
- Sync mode: Import or Force
Identity Providers > Add provider > SAML
Settings:
- Service provider entity ID: my-app
- Single sign-on service URL: [from SAML provider]
- Name ID policy format: Email
- Principal type: Subject NameID
- Want AuthnRequests signed: ON
Import from URL or file for metadata
Clients > [client] > Settings > Advanced
Access Token Lifespan: 5 minutes
Client Session Idle: 30 minutes
Client Session Max: 10 hours
Include in token:
- Standard claims (sub, aud, iss, exp, iat)
- Custom claims via mappers
Realm Settings > Tokens
Refresh Token Max Reuse: 0
Revoke Refresh Token: ON
SSO Session Idle: 30 minutes
SSO Session Max: 10 hours
Offline Session Idle: 30 days
Client scopes > [scope] > Mappers > Create
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
# Password grant
curl -X POST http://localhost:8080/realms/master/protocol/openid-connect/token \
-d "client_id=admin-cli" \
-d "username=admin" \
-d "password=admin" \
-d "grant_type=password"
# Get realm
curl -X GET http://localhost:8080/admin/realms/myapp \
-H "Authorization: Bearer $TOKEN"
# Create user
curl -X POST http://localhost:8080/admin/realms/myapp/users \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"username": "john",
"email": "[email protected]",
"enabled": true,
"firstName": "John",
"lastName": "Doe"
}'
# Get users
curl -X GET http://localhost:8080/admin/realms/myapp/users \
-H "Authorization: Bearer $TOKEN"
# Assign role
curl -X POST http://localhost:8080/admin/realms/myapp/users/{userId}/role-mappings/realm \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '[{"id": "{roleId}", "name": "admin"}]'
// pages/api/auth/[...nextauth].ts
import NextAuth from "next-auth"
import KeycloakProvider from "next-auth/providers/keycloak"
export default NextAuth({
providers: [
KeycloakProvider({
clientId: process.env.KEYCLOAK_CLIENT_ID!,
clientSecret: process.env.KEYCLOAK_CLIENT_SECRET!,
issuer: process.env.KEYCLOAK_ISSUER, // http://localhost:8080/realms/myapp
}),
],
callbacks: {
async jwt({ token, account }) {
if (account) {
token.accessToken = account.access_token
token.refreshToken = account.refresh_token
}
return token
},
async session({ session, token }) {
session.accessToken = token.accessToken
return session
},
},
})
// .env.local
KEYCLOAK_CLIENT_ID=my-app
KEYCLOAK_CLIENT_SECRET=secret
KEYCLOAK_ISSUER=http://localhost:8080/realms/myapp
const session = require('express-session')
const Keycloak = require('keycloak-connect')
const memoryStore = new session.MemoryStore()
const keycloak = new Keycloak({ store: memoryStore }, {
'realm': 'myapp',
'auth-server-url': 'http://localhost:8080',
'ssl-required': 'external',
'resource': 'my-app',
'credentials': {
'secret': 'client-secret'
}
})
app.use(session({
secret: 'session-secret',
resave: false,
saveUninitialized: true,
store: memoryStore
}))
app.use(keycloak.middleware())
// Protected route
app.get('/protected', keycloak.protect(), (req, res) => {
res.json({ message: 'Protected resource' })
})
// Role-based protection
app.get('/admin', keycloak.protect('admin'), (req, res) => {
res.json({ message: 'Admin resource' })
})
import Keycloak from 'keycloak-js'
const keycloak = new Keycloak({
url: 'http://localhost:8080',
realm: 'myapp',
clientId: 'my-app',
})
// Initialize
keycloak.init({
onLoad: 'login-required',
checkLoginIframe: false,
}).then((authenticated) => {
if (authenticated) {
console.log('User is authenticated')
console.log('Token:', keycloak.token)
console.log('Roles:', keycloak.realmAccess?.roles)
}
})
// Auto-refresh token
keycloak.onTokenExpired = () => {
keycloak.updateToken(30)
}
// API call with token
fetch('/api/data', {
headers: {
'Authorization': `Bearer ${keycloak.token}`
}
})
// Logout
keycloak.logout({ redirectUri: 'http://localhost:3000' })
// Check role
if (keycloak.hasRealmRole('admin')) {
// Show admin features
}
# Decode JWT token
echo $TOKEN | cut -d. -f2 | base64 -d | jq
# Verify token signature
curl http://localhost:8080/realms/myapp/protocol/openid-connect/certs
# Check Keycloak health
curl http://localhost:8080/health
# Check realm endpoints
curl http://localhost:8080/realms/myapp/.well-known/openid-configuration
Clients > [client] > Settings
- Web origins: http://localhost:3000
- Valid redirect URIs: http://localhost:3000/*
# Export realm
docker exec keycloak /opt/keycloak/bin/kc.sh export \
--dir /tmp/export \
--realm myapp
# Import realm
docker exec keycloak /opt/keycloak/bin/kc.sh import \
--file /tmp/export/myapp-realm.json
# PostgreSQL backup
docker exec postgres pg_dump -U keycloak keycloak > keycloak-backup.sql
# Restore
docker exec -i postgres psql -U keycloak keycloak < keycloak-backup.sql
themes/
└── custom-theme/
├── login/
│ ├── theme.properties
│ ├── login.ftl
│ └── resources/
│ ├── css/
│ └── img/
└── account/
└── ...
Realm Settings > Themes > Login theme: custom-theme
Handles the full Supabase workflow from schema changes to deployment, with built-in security guardrails that catch common traps like RLS...
Comprehensive guides and best practices for Neon Serverless Postgres, covering setup, connection methods, authentication, and platform APIs.
Guide for setting up and using Firebase Authentication. Use this skill when the user's app requires user sign-in, user management, or secure data access using auth rules.
A skill to evaluate how secure Firestore security rules are. Use this when Firestore security rules are updated to ensure that the generated rules are extremely secure and robust.
Official skill for integrating Firebase AI Logic (Gemini API) into web applications. Covers setup, multimodal inference, structured output, and security.
Complete Better Auth server and client setup with database adapters, session management, plugins, and security configuration.
Deploy and manage projects on Vercel using token-based authentication. Use when working with Vercel CLI using access tokens rather than interactive login — e.g. "deploy to vercel", "set up vercel", "add environment variables to vercel".
Complete Cloudflare platform integration with decision trees for compute, storage, AI, networking, security, and infrastructure-as-code.
Run Azure compliance and security audits with azqr plus Key Vault expiration checks. Covers best-practice assessment, resource review, policy/compliance validation, and security posture checks. WHEN: compliance scan, security audit, BEFORE running azqr (compliance cli tool), Azure best practices, Key Vault expiration check, expired certificates, expiring secrets, orphaned resources, compliance assessment.
Send, read, and manage Gmail messages, drafts, labels, and account settings.
Comprehensive website auditing across 230+ rules in 21 categories including SEO, performance, security, and accessibility.
Shared authentication, CLI syntax, and output formatting patterns for gws Google Workspace commands.
Discover your celebrity doppelgänger with StarByFace!
GeoSpy: Pricing, Features, FAQs, and Alternatives for AI Teams
Detect AI-generated voices to protect against audio fraud.
Ensure Your Content's Originality with AI Plagiarism Checker
Upscale images by 400% without quality loss
Protect your social media from copyright disputes
Accurately Detect AI-Generated Content with TheChecker.AI
Chrome extension that detects and flags AI-generated content