KEYCLOAK - BevvyTech/BrewskiDocs GitHub Wiki

Keycloak Integration Guide

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.


1. Why Keycloak

  • 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.

2. High-Level Architecture

  1. Keycloak Service: Runs as a dedicated App Platform component, backed by its own PostgreSQL database and TLS endpoint (e.g., https://auth.brewskiapp.com).
  2. Brewski API: Trusts Keycloak-issued JWTs (via JWKS). Uses a Keycloak service account to drive admin actions (client creation, secret rotation).
  3. Brewski Admin & Mobile Apps: Treat Keycloak as the OIDC provider; obtain tokens via Authorization Code + PKCE.
  4. Third-Party Apps: Receive client credentials managed through Keycloak. Brewski surfaces these via new API endpoints that proxy to Keycloak’s Admin API.

3. Prerequisites

  • 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.com with TLS certificate).
  • Internal agreement to update documentation (AGENTS.md, README.md) and user onboarding flows.

4. Provisioning Checklist

  1. Database: Create a keycloak Postgres database (or schema) with its own user and password. Grant full privileges to that user.
  2. Secrets: Store the following in App Platform secrets (names are suggestions):
    • KEYCLOAK_DB_URL
    • KEYCLOAK_ADMIN_PASSWORD
    • KEYCLOAK_HOSTNAME (auth.brewskiapp.com)
    • KEYCLOAK_PROXY (edge)
    • Optional: SMTP credentials for email notifications, Google identity provider credentials if federating.
  3. TLS: Point DNS to App Platform and enable automatic certificates, or configure a managed certificate.

5. App Platform Deployment

5.1 app.yaml Additions

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.keycloak that simply FROM quay.io/keycloak/keycloak:24.0 (or latest LTS) and runs kc.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.

5.2 Dockerfile snippet

FROM quay.io/keycloak/keycloak:24.0

ENV KC_CACHE=local \
    KC_CACHE_STACK=default

ENTRYPOINT ["/opt/keycloak/bin/kc.sh", "start", "--optimized"]

6. Configuration Tasks in Keycloak

  1. Access the Admin Console: Use kc-admin / ${KEYCLOAK_ADMIN_PASSWORD} at https://auth.brewskiapp.com/admin.
  2. Create Realm: brewski (repeat per environment: brewski-dev, brewski-staging, etc.).
  3. Set Policies: Password strength, MFA options, session timeouts, brute-force detection, email server.
  4. Identity Providers (optional): Configure Google federation under Identity Providers if you want to retain Google sign-in.
  5. Realm Roles: Define owner, admin, member, integration.read, integration.write, etc.
  6. Clients:
    • Admin UI (brewski-admin): public client, PKCE required, redirect URIs https://admin.brewskiapp.com/*.
    • API Service Account (brewski-api-admin): confidential client, service accounts enabled, assign manage-clients and custom roles for client management.
    • Mobile app (brewski-mobile): public client with custom redirect URI scheme (brewski://auth/callback).
  7. Client Scopes: Create default scopes for team IDs, roles, etc. Use protocol mappers to inject claims (team_ids, roles, email).
  8. Keys: Confirm active RSA signature keys. Document rotation schedule.

7. Brewski API Integration

7.1 Environment Variables (API/.env)

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_SECRET should 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.

7.2 Auth Middleware Changes

  • 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.
  • 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.

7.3 New API Endpoints

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 like team_id).
  • POST /integrations/clients: Create new client for a team owner. Payload includes name, redirectUris, scopes. Implementation:
    1. Validate owner/admin role within team.
    2. Call Keycloak Admin API to create client with protocol=openid-connect.
    3. Tag the Keycloak client with attributes (team_id, created_by).
    4. Persist metadata in Brewski DB if you need extra info (contact email, usage plan).
    5. 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.


8. Admin UI and Mobile Updates

  1. 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.
  2. 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.
  3. Third-Party Management Screens: Build UI components that hit the /integrations/clients endpoints to display and manage partner applications.
  4. Style Keycloak Theme: Export the default theme, customize colors/logo, and upload to Keycloak so users experience consistent branding.

9. Third-Party Onboarding Workflow

  1. Request Intake: Team owner submits a request via Admin UI (app name, redirect URIs, desired scopes, contact details).
  2. Validation: Brewski API validates URIs, ensures scopes are allowed, and enforces per-team limits.
  3. Client Creation: API calls Keycloak Admin to create the client, attaches team_id attribute.
  4. Secret Delivery: For confidential clients, return the secret once via the API response. Encourage owners to copy/store securely.
  5. Maintenance: Provide endpoints for rotating secrets, disabling clients, and viewing audit logs.
  6. Audit Storage: Optionally persist metadata in a Brewski table (e.g., integration_clients) with references to Keycloak clientId, contact email, notes, and created/rotated timestamps.

10. Secret Management & Rotation

  • 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-users as needed).
  • Implement rotation scripts (cron or manual SOP) that:
    1. Generate new secrets in Keycloak.
    2. Update secrets manager entries.
    3. Redeploy services that consume the secret.
  • Enable Keycloak key rotation for signing keys and update the API JWKS cache logic accordingly.

11. Local Development Options

  • Reuse Remote Keycloak: Point .env entries at the staging realm. Limit developer privileges via client scopes.
  • Run Local Keycloak: Use Docker:
    docker run --rm -p 8080:8080 \
      -e KEYCLOAK_ADMIN=kc-admin \
      -e KEYCLOAK_ADMIN_PASSWORD=localpass \
      quay.io/keycloak/keycloak:24.0 start-dev
    Update .env to use http://127.0.0.1:8080/realms/brewski.
  • Keep secrets out of source control; rely on .env.local or a tooling like Doppler/S1 for loading dev credentials.

12. Migration & Rollout Plan

  1. Pilot Environment: Deploy Keycloak to staging. Integrate API and Admin UI, run regression tests.
  2. Dual Auth Period: Allow existing Google tokens while issuing Keycloak tokens. Add feature flag to switch between issuers.
  3. 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.
  4. Mobile Rollout: Update the mobile app with the new OIDC flow, release to beta testers, monitor metrics (failed logins, token refresh issues).
  5. Cutover: Switch production API to require Keycloak-issued tokens. Disable direct Google token verification.
  6. Post-Cutover Monitoring: Track Keycloak health, login rates, admin actions, and adjust scaling as needed.

13. Testing Strategy

  • 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.

14. Operational Checklist

  • Enable metrics (/metrics), ship logs to centralized logging, set alerts for 5xx rates 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.

15. Reference Links


Next Steps

  • Review and approve the plan internally.
  • Draft the app.yaml changes 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.
⚠️ **GitHub.com Fallback** ⚠️