Frozen document. Dates and status refer to its original source. Private resources and unreviewed images are unavailable.
BFF alternative to MuleSoft
Status: selected first-phase BFF design, 2026-09-23, with placement amended by ADR 0010 on 2026-09-26. The owner requested exploration in Evaluate a BFF and backend adapters as the MuleSoft replacement. ADR 0008 and ADR 0009 retain the accepted BFF/session decisions. ADRs 0006 and 0007 are historical and superseded. Earlier deployment recommendations below are research; the two-stage runtime is authoritative.
Recommendation and boundary
For the synthetic Atlas prototype, replace the MuleSoft implementation with a small TypeScript backend-for-frontend plus backend integration adapters. Keep React/Vite, Contentful, Camunda and Keycloak. A BFF is an architectural role, not a hosted integration product or a substitute for every MuleSoft capability.
Atlas has one browser application and simulated REST legacy systems. UI-specific aggregation and HTTP mapping are reasonable code to own. We would give up Mule connectors, DataWeave and Anypoint management/policies, and maintain that code ourselves. If learning MuleSoft is an objective, this option does not satisfy it.
| Existing responsibility | Proposed owner |
| Experience API aggregation, UI projections and validation | BFF with explicit authorized response schemas |
| System APIs and legacy protocol/payload mapping | Backend adapter modules behind private system contracts |
| Browser authentication/session mediation | BFF confidential OIDC client with Keycloak |
| Business permissions, revisions, durable commands and outbox | Existing authoritative backend modules |
| BPMN and human-task orchestration | Camunda and its workers |
| Content/form authoring and bilingual releases | Contentful and the existing release compiler |
| Evidence scanning and protected bytes | Document owner, ClamAV and private storage |
Do not move business tables, task ownership or payment state into BFF sessions. Workers call private system contracts, not browser-session endpoints. A BFF can share the repository and VPS with the backend, while retaining separate modules and a separate container/process. This avoids requiring one microservice per insurance product.
Proposed technology stack
| Concern | Proposal |
| Runtime and language | Node.js 24 LTS and TypeScript; pin supported patch versions during setup |
| HTTP framework | Fastify with plugin/module boundaries for auth, forms, cases, tasks, payments and documents |
| Contracts | tRPC over HTTPS for React-to-SDUI BFF experience calls with reviewed TypeBox procedure parsers; REST/OpenAPI for compatibility and suitable integration paths |
| OIDC | openid-client with confidential-client authorization code flow and S256 PKCE |
| Browser sessions | @fastify/cookie and @fastify/session; opaque session ID, server-side PostgreSQL store |
| Persistence access | Existing PostgreSQL instance with separate BFF session schema/role and a reviewed session-store adapter |
| TLS entry | Caddy or Nginx on the VPS; choose one during setup |
| Deployment | Docker Compose on the Hostinger VPS, UI static assets on Vercel |
| Tests | Fastify injection tests, PostgreSQL/session integration tests and Playwright browser journeys |
Node's release table lists 24 as LTS. Fastify provides TypeScript support, JSON Schema validation and plugin boundaries; its Swagger plugin generates OpenAPI documents. Node releases, Fastify, validation, OpenAPI plugin.
September 30 amendment: the owner confirmed TypeBox boundary contracts and gRPC for suitable private adapters. The later ADR 0013 selects browser tRPC over HTTPS. Keep same-process business-owner interfaces and REST compatibility/protocol endpoints during migration. The migration design distinguishes these accepted choices from implementation still pending.
NestJS with the Fastify adapter is an alternative if the team prefers decorators, dependency injection and stronger framework conventions. For this prototype I prefer plain Fastify with explicit module ownership and fewer framework abstractions. This is a maintainability choice, not a benchmark claim. Nest Fastify adapter.
PostgreSQL sessions are a design choice using the existing database, not a bundled Fastify database integration. Verify the adapter against the selected plugin, TTL, atomic updates and refresh concurrency. Avoid the default in-memory session store and avoid adding Redis solely for sessions at this scale. Fastify sessions, openid-client.
Authentication change
[Private setup detail omitted.]
Retain the accepted five-minute access tokens, 15-minute idle and eight-hour absolute session bounds, and five-minute sensitive-action MFA freshness. The BFF must not extend those limits with its own session. Verify state/nonce/PKCE, rotate session IDs on authentication, serialize refresh-token rotation, implement logout/revocation, and enforce CSRF tokens and Origin checks on state-changing requests. SameSite is additional protection, not the entire CSRF defense. HttpOnly limits token extraction but malicious same-origin JavaScript can still issue requests.
The backend still verifies service identity plus authenticated actor context, with suitable token audiences and owner-side current permissions. Do not replace user authorization with a powerful machine token or trust caller-supplied identity headers. Preserve fresh assurance and current-session checks for sensitive actions.
Hosted placement considered but deferred
Prefer a stable SPA origin with Vercel external rewrites for /api and /auth to the VPS BFF, placed before the SPA fallback. The browser then uses same-origin API/session routes, while Keycloak login uses its own HTTPS identity hostname. Use fixed callback URLs and restrict proxy forwarding to known destinations. Configure trusted proxy handling narrowly. Vercel rewrites.
Explicitly disable caching for rewritten auth, private APIs and evidence, and send private/no-store headers. Verify Set-Cookie forwarding, redirects, logout, 10 MiB streaming and upload timeout behavior end to end. This proposal does not claim the selected Vercel plan's transfer path is proven. Do not insert a Vercel Function into the document path without checking its separate limits.
An alternative is sibling custom domains for app and API with exact credentialed CORS and host-only cookies. An unrelated vercel.app origin and VPS domain creates cross-site cookie restrictions; do not rely on third-party cookies. Serving both SPA and BFF through the VPS's HTTPS gateway gives a simpler same-origin fallback if Vercel proxy tests fail.
Cost, capacity and adoption gates
The coded BFF removes the need for the MuleSoft/CloudHub subscription in this alternative. It still costs engineering and operations time. Co-hosting it adds no separate hosting subscription if existing capacity is sufficient. Budget roughly 256–512 MiB for initial BFF measurement, not as a proven maximum; stream documents and measure actual resident memory under concurrency.
Compared with CloudHub, the BFF adds local VPS work. It does not free local Mule memory because Mule was remote. KVM 2 remains an unproven tight fit for Camunda, Keycloak, PostgreSQL, scanner, backend and BFF. KVM 4 remains the more comfortable starting candidate. No free-year entitlement for the remaining SaaS products is implied.
The owner selected the local BFF and Keycloak session design in ADRs 0008 and 0009. The Experience API and security contracts retain the behavioral guarantees with vendor-specific wording updated. Hosted Vercel/VPS placement remains an option for a later phase. No specs, implementation tickets or application code were created by this selection.
Prove token absence from browser storage, session fixation/refresh races, CSRF denial, session expiry/logout/step-up, owner and employer isolation, document streaming/scanning, durable 202 acceptance and response-loss recovery, dependency outages and full-stack capacity before declaring the replacement suitable.
Supporting evidence: BFF authentication and browser deployment.