Skip to main content
Version: 0.62.0-rc.1267

Authentication and Authorization Architecture

Lana separates authentication from application authorization:

  • Keycloak issues OIDC access tokens and owns login sessions.
  • Rust API servers validate token signatures, expiry, audience, and realm issuer.
  • Lana identity claims link the token to an application subject.
  • Casbin evaluates the subject's application permissions.
  • The use-case audit layer records authorization decisions and request metadata according to the action's audit policy.

Realms and Clients​

Realm names are instance-specific and can be overridden. The local stack uses:

RealmPurposeFrontend client
main-internalAdministrative usersadmin-panel
main-customerBank customersExternal customer clients, including the optional mobile demo
main-partnerPartner userspartner-portal

tf/modules/keycloak-realms/ defines the realms, clients, protocol mappers, and authentication flows. Backend service accounts manage Keycloak users using federated client authentication; they are not a generic GraphQL api-client.

Local passwordless DEV browser/direct-grant flows are a development convenience. Deployments outside local development must disable them. See Authentication (Local Dev).

Backend Token Validation​

The API config nests the Keycloak connection under each server. For example:

admin_server:
aud: admin-panel
keycloak:
internal_url: http://keycloak:8080/
public_url: https://keycloak.example.com/
realm: main-internal

customer_server:
aud: customer-portal
keycloak:
internal_url: http://keycloak:8080/
public_url: https://keycloak.example.com/
realm: main-customer

The JWKS URL is derived from internal_url and realm; the expected issuer is derived from public_url and realm. There are no top-level jwks_url or keycloak_issuer_url fields in these server configs. Set the public URL to the origin Keycloak uses in the token's iss, even if the server reaches Keycloak through an internal address.

JWT authentication requires these UUID-valued application identity claims; the admin and customer APIs additionally require a Keycloak sub:

APIClaims
AdminuserId
CustomerpartyId
PartnerpartnerUserId, partnerId

The application subject is not simply Keycloak's sub or a Keycloak realm role. A token must reference provisioned Lana entities, and those entities must be authorized for the requested operation.

The partner API also supports revocable partner API keys for unattended integrations. Those requests authenticate a partner-scoped API-key subject rather than a Keycloak user; see API Authentication.

Role-Based Access Control​

Administrative access follows this relationship:

User → Role → Permission sets → Object/action permissions

An admin user has one current role, which can contain multiple permission sets. The seeded bank roles are superuser, admin, bank-manager, and accountant; they are not a hard-coded inheritance tree of teller and credit-officer roles. Custom roles can combine grantable permission sets. The bootstrap-configured superuser has additional protections against reassignment and permission removal.

Policies are persisted in PostgreSQL and evaluated by lib/use-case's Casbin integration. The model uses transitive role grouping and keyMatch object matching. Authorization is enforced by the application/use-case layer, not by a GraphQL RoleGuard annotation.

See Authorization (RBAC) for the model and permission sets. The authoritative seeded permission lists are in lana/app/src/authorization/seed.rs.

Audit Access​

The admin API exposes authorization audit entries through audit:

query AuthorizationAudits {
audit(first: 10, authorized: false) {
edges {
node {
auditEntryId
recordedAt
object
action
authorized
requestIp
userAgent
}
}
}
}

Audit access itself requires the appropriate permission. See Audit System for storage and audit policies.

Sessions and Token Handling​

The shared realm module configures 5-minute access tokens, a 24-hour SSO idle timeout, and refresh-token rotation. Other session limits remain dependent on realm/client configuration; the module does not guarantee a separate 30-minute refresh-token lifetime or an 8-hour session.

The admin panel uses keycloak-js with PKCE and refreshes tokens through its auth helper. Browser tokens should stay in memory; confidential-client secrets must not be embedded in a SPA. Logout clears the client session and redirects through Keycloak.

For client integration and token refresh examples, see API Authentication.