Skip to main content
Version: 0.58.0-rc.42

Authentication for Local Development

This guide covers how authentication works in the local development environment, including Keycloak setup and login procedures.

Keycloak Setup

Keycloak runs at http://localhost:8081 and is automatically configured with realm imports when you run make start-deps.

Keycloak Admin Console

Realms

RealmPurposeUsed by
internalAdministrative usersAdmin Panel
customerBank customersExternal customer clients, customer-server API

Realm definitions are stored in dev/keycloak/ and imported automatically on startup.

Admin Panel Login

  1. Navigate to http://admin.lana-bank.localhost:1355
  2. You'll be redirected to Keycloak
  3. Log in with: admin@galoy.io
  4. The admin panel uses the internal Keycloak realm with OIDC Code Flow

Customer API Login

The bank no longer ships an in-repo customer-facing web frontend. The customer-server (port 5254) is exposed at http://app.lana-bank.localhost:1355/graphql for:

  • External customer clients that drive their own OIDC login against the Keycloak customer realm. The reference client is lana-mobile-demo — if you change the customer realm, the customer-server schema, or the app.localhost route, check that demo still works.
  • Bats tests, which use the dev direct-grant (password) flow to obtain a Keycloak access token — see get_customer_access_token in bats/helpers.bash.

Authentication Flow

How Backend JWT Validation Works

The backend servers validate Keycloak access tokens directly:

  1. Read the Bearer token from the request.
  2. Validate the JWT signature against the realm JWKS endpoint.
  3. Validate the issuer against the configured Keycloak realm URL.
  4. Extract the entity-specific claim as the Lana subject for authorization and audit context: userId on tokens from the admin (internal) realm, partyId on tokens from the customer realm.

Casbin authorization remains enforced inside the application layer after token validation.

Token Lifetimes (Development)

TokenLifetime
Access token5 minutes
Refresh token30 minutes
Session8 hours