Skip to content

dotcomrow/k8s-keycloak

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

399 Commits
 
 
 
 
 
 

Repository files navigation

k8s-keycloak

Suncoast Systems Keycloak Auth server

Public SPA Client (External Realm)

manifests/02-keycloak-configmaps.yaml defines a shared public OIDC client for browser apps:

  • client id: shell-spa-public
  • realm: external
  • issuer URL: https://auth.suncoast.systems/realms/external
  • discovery URL: https://auth.suncoast.systems/realms/external/.well-known/openid-configuration

This client is configured for Authorization Code + PKCE (S256) and includes redirect/web-origin patterns for:

  • http://localhost/*
  • http://127.0.0.1/*
  • https://*.suncoast.systems/*
  • https://*.app.suncoast.systems/*

Auth Gateway Service (Shared Callback + GUI APIs)

The dedicated auth gateway source now lives in: https://github.com/suncoast-systems/keycloak-auth-gateway

This repo keeps the deployment manifest at manifests/07-auth-gateway.yaml. The Keycloak external realm client auth-gateway-public is defined in manifests/02-keycloak-configmaps.yaml.

Purpose:

  • Centralize Keycloak redirect handling to a single callback URL (for example https://login.suncoast.systems/callback).
  • Store allowed apps in a database so a GUI can manage them dynamically.
  • Expose APIs for CRUD management of allowed apps.

Database tables created automatically at startup:

  • auth_gateway_allowed_apps
  • auth_gateway_login_state
  • auth_gateway_exchange_codes

Runtime flow:

  1. App sends users to GET /start?app=<slug>&return_to=<url-or-path>.
  2. Gateway redirects to Keycloak and receives callback at GET /callback.
  3. Gateway redirects back to app with one-time gateway_code query param.
  4. App exchanges that code with POST /v1/auth/exchange.

Management APIs (for GUI):

  • GET /v1/apps
  • POST /v1/apps
  • GET /v1/apps/{slug}
  • PUT /v1/apps/{slug}
  • DELETE /v1/apps/{slug}

GitOps seed job for baseline app registrations:

  • manifests/09-auth-gateway-seed-apps.yaml
  • Upserts shell and example-mfe-preview on each Argo sync so they survive rebuilds.

If ADMIN_API_TOKEN is set, management APIs require:

  • Authorization: Bearer <ADMIN_API_TOKEN>

Build and Publish Auth Gateway Image

Build/publish is managed in the keycloak-auth-gateway repo via GitHub Actions. Deployment in this repo expects:

  • ghcr.io/dotcomrow/keycloak-auth-gateway:latest

Deploy Auth Gateway

kubectl apply -f manifests/07-auth-gateway.yaml
kubectl apply -f manifests/09-auth-gateway-seed-apps.yaml

Optional secrets:

kubectl -n keycloak create secret generic auth-gateway-admin-api \
  --from-literal=token='<strong-admin-token>'

kubectl -n keycloak create secret generic auth-gateway-oidc-client \
  --from-literal=client-secret='<client-secret-if-using-confidential-client>'

APISIX example route:

  • manifests/08-auth-gateway-apisix-route.example.yaml

Profile Field Standard (IdP -> Keycloak -> Apps)

manifests/04-keycloak-configurator.yaml configures IdPs and imports as much profile data as is available from external identity providers into Keycloak user attributes. Apps then receive these fields via an OIDC client scope named user-profile (added as a default client scope for the main app clients in both realms).

Imported User Attributes (canonical)

  • picture (avatar URL)
  • profile (profile URL)
  • website
  • locale
  • name
  • given_name
  • family_name
  • preferred_username
  • email_verified

Imported User Attributes (provider-specific)

  • Google: hd, google_sub
  • GitHub: company, location, bio, twitter_username, github_id, github_node_id

How Apps Consume It

  • Tokens/userinfo include the above attributes as claims when the client has the user-profile scope attached.
  • The configurator also ensures the standard email scope is present for app clients that expect email.

Cloudflare Tunnel

This repo includes a Cloudflare Tunnel deployment at manifests/06-cloudflare-tunnel.yaml. It runs cloudflared in the keycloak namespace and reads TUNNEL_TOKEN from a Kubernetes Secret named cloudflare-tunnel-token. That Secret is created by External Secrets using Vault.

Vault policy + role for External Secrets (externalsecrets-keycloak) are created by:

  • manifests/03-vault-bootstrap-jobs.yaml

One-time setup

  1. Create a named tunnel in Cloudflare Zero Trust (or with the CLI) and copy the tunnel token.
cloudflared tunnel login
cloudflared tunnel create keycloak
cloudflared tunnel route dns keycloak auth.suncoast.systems
cloudflared tunnel token keycloak
  1. Write the token into Vault (KVv2) at secret/data/keycloak-cloudflare-tunnel-token with key value.
vault kv put secret/keycloak-cloudflare-tunnel-token value='<PASTE_TUNNEL_TOKEN>'
  1. Sync ArgoCD so these manifests are applied:
  • manifests/03-vault-bootstrap-jobs.yaml
  • manifests/06-cloudflare-tunnel.yaml
  1. In Cloudflare Zero Trust, set the tunnel public hostname and origin service:
  • Hostname: auth.suncoast.systems
  • Service URL: http://keycloak.keycloak.svc.cluster.local:8080

Verify

kubectl -n keycloak get deploy,pod -l app=cloudflared
kubectl -n keycloak logs deploy/cloudflared --tail=100 -f
kubectl -n keycloak get externalsecret cloudflare-tunnel-token

About

Suncoast Systems Keycloak Auth server

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors