Auth Service — Local Dev Setup
Status: populated Owner: Engineering Last updated: 2026-04-18
1. compose
docker compose up postgres redis vault keycloak. Vault runs in dev mode with root-token=devroot. Keycloak runs with realm ghasi-local pre-imported (see infra/docker/keycloak/realm-ghasi-local.json) containing a test client auth-service and two users: admin@example.com, user@example.com.
2. Env
PORT=3020
DATABASE_URL=postgresql://auth:auth@localhost:5432/ghasi_sms?schema=auth
REDIS_URL=redis://localhost:6379/2
VAULT_ADDR=http://localhost:8200
VAULT_TOKEN=devroot
# Base IdP — Keycloak (default)
KEYCLOAK_BASE_URL=http://localhost:8080
KEYCLOAK_REALM=ghasi-local
KEYCLOAK_CLIENT_ID=auth-service
KEYCLOAK_CLIENT_SECRET=dev-secret
KEYCLOAK_ADMIN_USER=admin
KEYCLOAK_ADMIN_PASSWORD=admin
# Legacy provider — Firebase (optional; only if FIREBASE_LEGACY_ENABLED=true)
FIREBASE_LEGACY_ENABLED=false
# FIREBASE_PROJECT_ID=ghasi-dev
# FIREBASE_CREDENTIALS=/secrets/fb-dev.json
NATS_URL=nats://localhost:4222
ACCESS_TOKEN_TTL=15m
REFRESH_TOKEN_TTL=30d
JWKS_ROTATION_CRON=0 0 1 * *
LOG_LEVEL=debug
3. Commands
pnpm install
pnpm --filter @ghasi/service-auth prisma migrate dev
pnpm --filter @ghasi/service-auth prisma db seed # seeds 1 account + admin user + test API key
pnpm --filter @ghasi/service-auth dev
4. Smoke test
# Native fallback login (test account only)
curl -X POST http://localhost:3020/v1/auth/login -H "Content-Type: application/json" \
-d '{"email":"admin@example.com","password":"ChangeMe!1"}'
# Keycloak SSO (default path) — browser flow; CLI equivalent:
curl -v "http://localhost:3020/v1/auth/sso/start?tenant=local"
# JWKS (consumed by Kong)
curl http://localhost:3020/.well-known/jwks.json
# Keycloak admin sanity
curl http://localhost:8080/realms/ghasi-local/.well-known/openid-configuration
5. Seed data
- 1 tenant (
local), 1 account, 1 admin user mirrored between Postgres (auth.users) and Keycloak realmghasi-local. - 1 API key for Kong smoke (printed once).
- 2 JWK keys (active + next).
- Default
tenant_identity_providersrow:providerId=keycloak,kind=oidc,is_default=true.
6. Simulating a tenant external IdP (OIDC)
docker compose up mock-oidc starts a second Keycloak instance at http://localhost:9080 that represents a customer's IdP ("acme-corp"). Register it against the main Keycloak as a brokered IdP:
pnpm --filter @ghasi/service-auth tenant:register-oidc \
--tenant=local --providerId=tenant-oidc:acme \
--discoveryUrl=http://localhost:9080/realms/acme/.well-known/openid-configuration
Then visit http://localhost:3020/v1/auth/sso/start?tenant=local&provider=tenant-oidc:acme to exercise the full brokered flow end-to-end.