---
title: System map
description: The architecture and the two boundaries that must always hold.
sidebar:
  order: 1
  label: Overview
---

The boundary between the storefront and the Shop API is recorded in ADR-0001 (`docs/adr/` in the repository); terms
such as _storefront-only capability_ and _shared capability_ are defined in the repository's `CONTEXT.md`.

The diagram records the existing deployment configuration, including `shop.sandrino.run` for the storefront.
`https://tarnandtimber.com` is the intended storefront address for a later cutover; changing the brand does not
change live domains, authentication audiences or infrastructure resource names.

## Architecture

```mermaid
flowchart LR
  subgraph Clients
    Browser[Shopper browser]
    MCPClient[MCP client<br/>Claude, ChatGPT, Cursor]
    Operator[Operator browser]
    PoppyAgent[Poppy personal agent]
  end

  subgraph Cloudflare["Cloudflare Workers"]
    Web[apps/webshop<br/>shop.sandrino.run]
    MCP[apps/mcp<br/>mcp.tarnandtimber.com]
    API[apps/api<br/>api.tarnandtimber.com/v1]
    BO[apps/backoffice<br/>backoffice.tarnandtimber.com]
  end

  ProxyAuth0[apps/proxy-auth0<br/>login-shop / auth-shop]
  Auth0[(Auth0 tenant<br/>custom domain login-shop)]
  Okta[(Okta)]
  D1[(D1 ShopDatabase)]
  DOs[[AccountWriter<br/>ConversationHub]]
  Stripe[(Stripe)]

  Browser --> Web
  MCPClient -->|Bearer MCP token| MCP
  Operator --> BO
  PoppyAgent -->|sign-in, grants, token exchange| ProxyAuth0
  PoppyAgent -->|DPoP token| API
  PoppyAgent -->|Bearer token| MCP

  Web -->|service binding<br/>user, storefront or agent-forwarder token| API
  MCP -->|service binding<br/>OBO or agent-forwarder token| API
  BO -->|service binding<br/>M2M + operator| API
  ProxyAuth0 -->|Custom Token Exchange,<br/>custom-domain front| Auth0
  API -->|Session introspection| ProxyAuth0
  MCP -->|Session introspection| ProxyAuth0

  Web -->|login, refresh| Auth0
  Web -->|My Account API, web only| Auth0
  MCP -->|OBO token exchange| Auth0
  Web -->|client credentials| Auth0
  BO -->|client credentials| Auth0
  BO -->|operator SSO| Okta
  MCPClient -->|authorize via the Auth0 proxy<br/>on the custom domain| Auth0

  API --> D1
  API --> DOs
  API --> Stripe
  Web -->|storefront-only capabilities| D1
  Web -->|account writer, conversation hub| DOs
  Web -->|card setup, browser checkout| Stripe
  API -->|Management API| Auth0
```

Read the diagram from the clients on the left. Browsers and operators reach their own apps. MCP clients reach the MCP
server with a bearer token. Requests for shared capabilities end at the API; requests for capabilities only the
storefront performs end at the storefront, which is bound to the same commerce database. The API also runs the Stripe
webhook and the hourly jobs.

## Rules the diagram encodes

- Domain execution (carts, orders, payments, workflows) and the commerce database belong to two Workers: the API and the
  storefront. The storefront runs the capabilities only it performs through the same domain operations, from server-only
  modules, against the same database and `AccountWriter`; shared capabilities stay in the API and the storefront calls
  their public endpoints. The MCP server has no database binding. The backoffice keeps its own database for operator
  sessions and audit and has no access to the shop's.
- The storefront keeps OAuth redirects, cookies, Stripe Elements, WebMCP registration and all My Account calls. Those
  are protocol and identity concerns, not shop business logic.
- The Auth0 proxy issues credentials and answers introspection; it never forwards shop business requests to the API or
  MCP server.
- The MCP server holds no state and no business rules. It authorizes tools, exchanges tokens, calls the API and
  formats results.

## Two boundaries that must always hold

**1. The Auth0 proxy is an extension of Auth0**

It fronts the Auth0 custom domain, runs the Poppy sign-in flows, grants, sessions and Custom Token Exchange, and
serves discovery, introspection and revocation. It issues and brokers **credentials**. It never forwards **resource
traffic**.

**2. My Account is web-only**

Auth0's My Account API is called only by the storefront, with the customer's own My Account token. The Shop API has
no My Account endpoints and never receives a My Account token.

### The Auth0 proxy never proxies the API or MCP

No Auth0 proxy route forwards to `api.tarnandtimber.com`, `mcp.tarnandtimber.com` or the storefront's resource paths, and
none is ever added. Poppy agents call the API and the MCP server directly with a token, exactly as every other client
does; Poppy discovery advertises those URLs. The Auth0 proxy's boundary test (`apps/proxy-auth0/src/app.boundary.test.ts`)
sends every method to the old Poppy, MCP and conversation paths and checks that no request leaves for those hosts.
The API and MCP server call the Auth0 proxy to introspect Sessions, and the Auth0 proxy calls the API only for its internal
notifications (signed-out Sessions, connected agents, agent authorization), authenticated by `X-Proxy-Auth0-Secret`.

### My Account stays in the storefront

That covers authentication methods, passkeys, MFA enrollment and removal, and recovery codes. My Account tokens stay
in the storefront's server-side session. See [My Account](/architecture/auth0/my-account).

## Where to go next

- [Components](/architecture/components) describes each box in the diagram.
- [Callers and tokens](/architecture/callers-and-tokens) explains how the API tells callers apart.
- [Request flows](/architecture/request-flows/signed-in-checkout) walks through real requests step by step.

## Diagnostic ownership

ShopDatabase also retains five diagnostic tables; it is not a new database or collector. BackofficeDatabase continues to
own only operator sessions and the separate access ledger. “No shop database access” means no direct binding: auditors
can investigate authorized diagnostics through API procedures. Storefront, MCP and backoffice emit through distinct named
private API producer capabilities; the Auth0 proxy emits only synthetic HTTP streams, without app recorder or database access.
Genuine direct/forwarded Auth0 events remain visibly separate from simulation. See [diagnostic investigations](/runbooks/audit-investigations)
for actual service/runtime attribution, source evidence, bounded raw demo policy and 30-day retention/restore behavior.
