Skip to content

Architecture

BFF Pattern

The webapp uses a Backend-for-Frontend (BFF) architecture. The SvelteKit frontend never talks directly to backend microservices — all requests go through the FastAPI BFF layer.

Benefits: - A single auth boundary: the BFF validates the JWT and attaches credentials - The browser is not exposed to internal service URLs or access tokens - The BFF can aggregate, transform, and cache data from multiple services

Deployment Model

Requests from the browser pass through Caddy (TLS termination) → oauth2_proxy (OIDC authentication against Keycloak) → the BFF. The BFF then forwards authenticated requests to internal services (digital-twin, nudging-tool, celine-ai-assistant).

Layer Component Role
Ingress Caddy TLS termination, reverse proxy
Auth oauth2_proxy OIDC login with Keycloak, JWT injection
Application FastAPI BFF Request handling, service aggregation
Backend services digital-twin, nudging-tool, celine-ai-assistant Domain data

The BFF is deployed as a standalone container. The participant frontend is served from celine-frontend apps/webapp.

JWT Flow

  1. User authenticates via Keycloak through oauth2_proxy.
  2. oauth2_proxy injects the access token into the X-Auth-Request-Access-Token header.
  3. The BFF reads this header on each request — signature is not re-verified (trusted internal header).
  4. The BFF extracts the user subject (sub), groups, and email from the token.
  5. Downstream service calls include the access token as Authorization: Bearer <token>.

Service Dependencies

Service Usage
Digital Twin Energy overview data, participant values
nudging-tool Notification list and preferences
celine-ai-assistant Embedded chat assistant (proxied)
Keycloak Identity provider (via oauth2_proxy)

Frontend

This repository is a pure API backend. The participant frontend (SvelteKit) is maintained separately in celine-frontend apps/webapp. The frontend communicates exclusively with this BFF at /api/*.