Platform internals

What is actually running

Eight services. One docker compose up. Every component below is a real server, not a diagram box. The model making tool calls is the Anthropic API. The token in the JWT inspector is from a live OAuth exchange with Authentik.

Customer / AgentLara Trust PlatformBanking CorepromptcontextMCP tool calltoken validationKYA lookupforward requestAER receiptrisk evalstep-up triggerauthorised callread/writeenrollmentSarah ChenWealth-tier customerCowork / Chat UIChannel 1 interfaceAI ModelClaude · ChatGPT · GeminiAuthentik IDP:9000 · OAuth 2.0 / OIDCMCP Server:8100 · SSE transportBorder Gateway:8200 · AgentROA enforcementAudit LogAER receipts · SQLiteAgent RegistryKYA profiles · ROA storeRisk EngineAmount · payee · frequencyConsent Engine:8300 · Push consent · WSBank API:8000 · FastAPIMock DataSarah Chen · accountsEnforcement is external to the model5 clients · not per-user

Click any platform node to jump to its component detail below.

  1. 1Sarah prompts Claude in Cowork: "Pay my Netflix bill"
  2. 2Claude calls make_payment tool via MCP (:8100)
  3. 3MCP Server fetches JWT from Authentik (:9000) — token includes act.sub: agent-claude-personal-sarah, act.channel_type: customer_ai
  4. 4MCP Server forwards call to Border Gateway (:8200)
  5. 5Border Gateway: fetches ROA → checks payee (Netflix ✓), amount (£14.99 < £500 ceiling ✓), TTL (active ✓)
  6. 6Risk Engine: merchant payee, known, low amount → auto-approve
  7. 7Border Gateway generates AER receipt (HMAC-SHA256 signed) → writes to Audit Log
  8. 8Border Gateway forwards to Bank API (:8000)
  9. 9Bank API updates Sarah's balance → returns success
  10. 10Response flows back: Bank API → Gateway → MCP → Claude → Sarah

Component catalog

Eight services. Click any card to expand the full detail.

The entry point for any AI model. Wraps the Bank API as a set of tools any MCP-compatible agent can call. Model-agnostic — Claude, ChatGPT, and Gemini all connect the same way.

The enforcement proxy. Every request from the MCP Server passes through here before reaching the Bank API. External to the model's execution context — a prompt-injected agent cannot bypass it.

The identity provider. Issues JWTs for all five agent channel types. Five fixed OAuth clients — one per channel type. Enrollment never creates a new client; it writes to the Agent Registry instead.

One row per enrollment. The source of truth for who has enrolled which agent, with what scopes, and at what trust tier. Also stores the ROA that the Border Gateway fetches on every request.

Classifies every inbound request on five dimensions before the Border Gateway makes its allow/deny decision. Not ML-based — deterministic rules matching the demo scenarios.

The mock banking backend. Five endpoints covering the core banking actions the demo needs. Sarah Chen's data lives in memory — the auth stack around it is real.

Stores every AER receipt generated by the Border Gateway. Not a log — a signed pre-execution commitment. The receipt exists whether the action was allowed or denied. HMAC-SHA256 signed with GATEWAY_SIGNING_KEY.

Everything running on localhost

ServiceURLPurpose
Bank APIhttp://localhost:8000/docsSwagger UI — all endpoints
Bank API healthhttp://localhost:8000/health{"status":"healthy","phase":2}
Border Gateway healthhttp://localhost:8200/gateway/health{"status":"healthy"}
Consent Enginehttp://localhost:8300/health{"status":"healthy"}
MCP Serverhttp://localhost:8100/sseSSE transport endpoint
Authentik adminhttp://localhost:9000/if/admin/IDP admin console
Authentik OIDC discoveryhttp://localhost:9000/application/o/lara-bank/.well-known/openid-configurationOpenID configuration
Authentik JWKShttp://localhost:9000/application/o/lara-bank/jwks/Public keys for token validation
Frontendhttp://localhost:3001This app

The agent making tool calls

In Channel 1 (Your AI assistant), the agent is not simulated. It is a live Claude session via the Anthropic API. When you open Cowork and ask Claude to check Sarah's balance, that is claude-sonnet-4-6 making a real tool call to the MCP Server running on your machine.

Model: claude-sonnet-4-6API: Anthropic Messages API with tool use

The model does not see Sarah's accounts directly. It sees the tool result returned by the MCP Server — which has already passed through the Border Gateway enforcement stack. The model cannot request data outside what the MCP tools expose, and the MCP tools enforce auth on every call.

What the Anthropic API does NOT do
  • It does not receive Sarah's actual account data in the prompt context
  • It does not hold tokens or credentials
  • It does not bypass the Border Gateway — it speaks to the MCP Server, and the MCP Server enforces auth
  • It does not retain customer data — each session is stateless

Channels 2–5 use the same MCP Server and Border Gateway. The model layer is swappable — MoneyDash (Channel 3) could use OpenAI's function calling; the enforcement stack does not care.

Run it in five minutes

git clone https://github.com/lakshsinghal/lara-trust
cd lara-trust
docker compose up -d
python3 scripts/setup_authentik.py   # first run only
python3 scripts/test_phase2_gateway.py  # verify everything is working

Then open http://localhost:3001.

To connect your own Claude session (Channel 1):

  1. Add the MCP server to your Claude desktop config:
    {
      "mcpServers": {
        "lara-trust": { "url": "http://localhost:8100/sse" }
      }
    }
  2. Restart Claude desktop
  3. Ask: “What’s Sarah Chen’s current account balance?”
  4. Watch the Theatre enforcement panel respond

You'll need an Anthropic API key for the embedded agent (set ANTHROPIC_API_KEY in .env).

MIT licence. Fork it, extend it, break it, fix it.