KEYCLOAK - BevvyTech/BrewskiDocs GitHub Wiki
This document captures the end-to-end plan for introducing Keycloak as the centralized identity provider for Brewski. It covers infrastructure, configuration, application integration, third-party client management, and the rollout strategy.
- Single IdP for web, mobile, kiosk, and partner integrations.
- Built-in support for password login, Google federation, MFA, and OAuth2/OpenID Connect flows.
- Consolidated storage for OAuth clients, secrets, tokens, and audit events.
- Extensible via Admin REST API so Brewski can expose custom UX for partners while delegating the security-critical pieces to Keycloak.
-
Keycloak Service: Runs as a dedicated App Platform component, backed by its own PostgreSQL database and TLS endpoint (e.g.,
https://auth.brewskiapp.com). - Brewski API: Trusts Keycloak-issued JWTs (via JWKS). Uses a Keycloak service account to drive admin actions (client creation, secret rotation).
- Brewski Admin & Mobile Apps: Treat Keycloak as the OIDC provider; obtain tokens via Authorization Code + PKCE.
- Third-Party Apps: Receive client credentials managed through Keycloak. Brewski surfaces these via new API endpoints that proxy to Keycloak’s Admin API.
- DigitalOcean App Platform access to modify
app.yaml. - A managed PostgreSQL instance (dedicated or database within an existing cluster) for Keycloak.
- Secrets manager entries for Keycloak admin credentials, database URL, mail settings, and any external IdPs (e.g., Google).
- DNS entry for the Keycloak endpoint (recommended
auth.brewskiapp.comwith TLS certificate). - Internal agreement to update documentation (
AGENTS.md,README.md) and user onboarding flows.
-
Database: Create a
keycloakPostgres database (or schema) with its own user and password. Grant full privileges to that user. -
Secrets: Store the following in App Platform secrets (names are suggestions):
KEYCLOAK_DB_URLKEYCLOAK_ADMIN_PASSWORD-
KEYCLOAK_HOSTNAME(auth.brewskiapp.com) -
KEYCLOAK_PROXY(edge) - Optional: SMTP credentials for email notifications, Google identity provider credentials if federating.
- TLS: Point DNS to App Platform and enable automatic certificates, or configure a managed certificate.
Add a new component for Keycloak (simplified example):
- name: keycloak
environment_slug: docker
instance_count: 1
instance_size_slug: basic-xxs
source_dir: .
dockerfile_path: Dockerfile.keycloak
http_port: 8080
routes:
- path: /
preserve_path_prefix: false
domain: auth.brewskiapp.com
envs:
- key: KC_DB
value: postgres
- key: KC_DB_URL
value: ${KEYCLOAK_DB_URL}
scope: RUN_AND_BUILD_TIME
- key: KEYCLOAK_ADMIN
value: kc-admin
- key: KEYCLOAK_ADMIN_PASSWORD
value: ${KEYCLOAK_ADMIN_PASSWORD}
scope: RUN_AND_BUILD_TIME
- key: KC_HOSTNAME
value: ${KEYCLOAK_HOSTNAME}
- key: KC_PROXY
value: edge
- key: KC_HEALTH_ENABLED
value: "true"
- key: JAVA_OPTS_APPEND
value: "-Djava.net.preferIPv4Stack=true"Notes
- Provide a
Dockerfile.keycloakthat simplyFROM quay.io/keycloak/keycloak:24.0(or latest LTS) and runskc.sh start --optimized. - Scale instance size/count based on expected load. For HA, add more instances and configure sticky sessions or an external cache.
- Additional env vars (SMTP, Google federation) can be added as needed.
FROM quay.io/keycloak/keycloak:24.0
ENV KC_CACHE=local \
KC_CACHE_STACK=default
ENTRYPOINT ["/opt/keycloak/bin/kc.sh", "start", "--optimized"]-
Access the Admin Console: Use
kc-admin/${KEYCLOAK_ADMIN_PASSWORD}athttps://auth.brewskiapp.com/admin. -
Create Realm:
brewski(repeat per environment:brewski-dev,brewski-staging, etc.). - Set Policies: Password strength, MFA options, session timeouts, brute-force detection, email server.
-
Identity Providers (optional): Configure Google federation under
Identity Providersif you want to retain Google sign-in. -
Realm Roles: Define
owner,admin,member,integration.read,integration.write, etc. -
Clients:
- Admin UI (
brewski-admin): public client, PKCE required, redirect URIshttps://admin.brewskiapp.com/*. - API Service Account (
brewski-api-admin): confidential client, service accounts enabled, assignmanage-clientsand custom roles for client management. - Mobile app (
brewski-mobile): public client with custom redirect URI scheme (brewski://auth/callback).
- Admin UI (
-
Client Scopes: Create default scopes for team IDs, roles, etc. Use protocol mappers to inject claims (
team_ids,roles,email). - Keys: Confirm active RSA signature keys. Document rotation schedule.
Add:
KEYCLOAK_ISSUER_URL=https://auth.brewskiapp.com/realms/brewski
KEYCLOAK_JWKS_URL=https://auth.brewskiapp.com/realms/brewski/protocol/openid-connect/certs
KEYCLOAK_ADMIN_CLIENT_ID=brewski-api-admin
KEYCLOAK_ADMIN_CLIENT_SECRET=<pulled from secrets manager>
KEYCLOAK_AUDIENCE=brewski-api
-
KEYCLOAK_ADMIN_CLIENT_SECRETshould be injected via DevOps tooling; do not commit. - Local dev can target the remote hosted Keycloak. If you want a local Keycloak, spin it up via Docker and point these URLs accordingly.
- Replace the Google JWT verification with Keycloak verification:
- Fetch JWKS from
KEYCLOAK_JWKS_URL, cache keys. - Validate issuer (
KEYCLOAK_ISSUER_URL), audience (KEYCLOAK_AUDIENCE), expiry, and signature. - Extract user ID (
sub), email, roles, team IDs from token claims.
- Fetch JWKS from
- Update refresh-token flow to call Keycloak’s token endpoint (
/protocol/openid-connect/token) and introspection/revocation endpoints where needed. - Maintain existing role enforcement logic by mapping Keycloak claims to internal authorisation checks.
Expose endpoints for first-party apps and team owners to manage their integrations. Suggested additions (Fastify routes):
-
GET /auth/keycloak/config: Returns discovery info (issuer, client IDs for Admin/Mobile) so clients can configure themselves. -
POST /auth/keycloak/token: Optional proxy for resource-owner password or service-account flows if you need server mediation. -
GET /integrations/clients: List Keycloak clients owned by the authenticated team (calls Keycloak Admin API via service account, filters via custom attributes liketeam_id). -
POST /integrations/clients: Create new client for a team owner. Payload includesname,redirectUris, scopes. Implementation:- Validate owner/admin role within team.
- Call Keycloak Admin API to create client with
protocol=openid-connect. - Tag the Keycloak client with attributes (
team_id,created_by). - Persist metadata in Brewski DB if you need extra info (contact email, usage plan).
- Return client ID and generated secret (confidential clients) once.
-
POST /integrations/clients/:id/rotate-secret: Rotate and return new secret (only for confidential clients). -
DELETE /integrations/clients/:id: Disable or delete client. -
GET /integrations/clients/:id/credentials: Fetch masked credentials, scope assignments, and audit history (pull from Keycloak).
Restrict these endpoints so only team owners/admins can manage clients tied to their team. Use Keycloak attributes (team_id) and internal records to enforce separation.
- Login Flow: Replace current Google button with “Sign in with Brewski” linking to Keycloak’s authorization endpoint. Continue to offer Google as a choice if federated.
-
Token Handling: Use the OIDC client libraries suited for the platform (e.g.,
keycloak-js,@react-keycloak, AppAuth for mobile). Ensure PKCE, refresh tokens, and logout flows are handled correctly. -
Third-Party Management Screens: Build UI components that hit the
/integrations/clientsendpoints to display and manage partner applications. - Style Keycloak Theme: Export the default theme, customize colors/logo, and upload to Keycloak so users experience consistent branding.
- Request Intake: Team owner submits a request via Admin UI (app name, redirect URIs, desired scopes, contact details).
- Validation: Brewski API validates URIs, ensures scopes are allowed, and enforces per-team limits.
-
Client Creation: API calls Keycloak Admin to create the client, attaches
team_idattribute. - Secret Delivery: For confidential clients, return the secret once via the API response. Encourage owners to copy/store securely.
- Maintenance: Provide endpoints for rotating secrets, disabling clients, and viewing audit logs.
-
Audit Storage: Optionally persist metadata in a Brewski table (e.g.,
integration_clients) with references to KeycloakclientId, contact email, notes, and created/rotated timestamps.
- Store Keycloak admin client credentials and service account secrets in the central secrets manager.
- Use a Keycloak service account for the Brewski API to interact with the Admin API (grant
manage-clients,manage-usersas needed). - Implement rotation scripts (cron or manual SOP) that:
- Generate new secrets in Keycloak.
- Update secrets manager entries.
- Redeploy services that consume the secret.
- Enable Keycloak key rotation for signing keys and update the API JWKS cache logic accordingly.
-
Reuse Remote Keycloak: Point
.enventries at the staging realm. Limit developer privileges via client scopes. -
Run Local Keycloak: Use Docker:
Update
docker run --rm -p 8080:8080 \ -e KEYCLOAK_ADMIN=kc-admin \ -e KEYCLOAK_ADMIN_PASSWORD=localpass \ quay.io/keycloak/keycloak:24.0 start-dev
.envto usehttp://127.0.0.1:8080/realms/brewski. - Keep secrets out of source control; rely on
.env.localor a tooling like Doppler/S1 for loading dev credentials.
- Pilot Environment: Deploy Keycloak to staging. Integrate API and Admin UI, run regression tests.
- Dual Auth Period: Allow existing Google tokens while issuing Keycloak tokens. Add feature flag to switch between issuers.
-
User Migration:
- Import email/password users into Keycloak via Admin API.
- Federate Google accounts to Keycloak so users can continue using Google login through the hosted page.
- Communicate to users that they will see a new login screen.
- Mobile Rollout: Update the mobile app with the new OIDC flow, release to beta testers, monitor metrics (failed logins, token refresh issues).
- Cutover: Switch production API to require Keycloak-issued tokens. Disable direct Google token verification.
- Post-Cutover Monitoring: Track Keycloak health, login rates, admin actions, and adjust scaling as needed.
- Automated integration tests that hit Keycloak dev realm to obtain tokens and exercise API endpoints.
- Security tests for token expiry, revoked sessions, incorrect roles, and brute-force protection.
- Manual QA for login/registration/password reset, MFA, and third-party client management flows.
- Load testing on Keycloak endpoints if expecting high concurrency.
- Enable metrics (
/metrics), ship logs to centralized logging, set alerts for5xxrates and failed logins. - Schedule periodic backups of the Keycloak database (daily snapshot + point-in-time recovery).
- Document break-glass procedures and rotate admin credentials regularly.
- Keep Keycloak version patched; stage upgrades in non-prod before production rollout.
- Keycloak Docs: https://www.keycloak.org/documentation
- Admin REST API: https://www.keycloak.org/docs-api/24.0/rest-api/
- Theme Customization Guide: https://www.keycloak.org/docs/latest/server_development/#_themes
- Review and approve the plan internally.
- Draft the
app.yamlchanges and create the associated secrets. - Begin implementing the authentication middleware updates and the third-party client management endpoints.
- Schedule staging deployment and regression testing window.