plug n play

Reference architecture

Every box. Every reason.

Tap any component to see what it does, why it's there, and what it costs. The diagram is the architecture — nothing is hidden in footnotes.

Distribution

~$2/mo

CloudFront

Public HTTPS front door for app + API.

One distribution serves both the Next.js app (default behaviour) and the API (/revenue/*, /chat/*, /ai/*, etc.). Injects an origin-verify header so Amplify rejects direct hits.

ClientEdgeIdentityComputeData

Request flow

Watch a single question become an answer.

Nine checkpoints, from the keystroke in the browser to the streamed response. Every step either verifies identity, scopes data, or does both.

Or tap any step
01 / 9

Step 1 · Client

Keystroke

User types a question in the chat textarea. The Next.js client validates it locally and attaches the Cognito id token from in-memory state.

Security

Four independent layers, each blocking a different class of attack.

01

AWS WAF — perimeter

OWASP Top 10 managed rule set, known-bad-inputs (Log4j, SSRF), IP reputation list, and a rate-based rule that blocks any IP sending more than 100 requests in a 5-minute window.

02

Cognito JWT — API boundary

API Gateway rejects every request without a valid Cognito JWT before Lambda is invoked. No authenticated caller means no AI compute runs, which eliminates the cost exposure open endpoints typically carry.

03

Row-level security — data layer

Postgres enforces the tenant_id claim from the JWT on every SELECT, INSERT, UPDATE, and DELETE. A bug in the application layer cannot leak cross-tenant data.

04

Origin verify — bypass prevention

Amplify basic-auth rejects direct origin hits. CloudFront injects a shared secret on every request. Anyone who discovers the raw Amplify URL receives a 401 — the WAF cannot be bypassed.

Multi-tenancy

Enforced in Postgres, not in the application.

Every API request carries a Cognito JWT. Lambda extracts the custom:tenant_id claim and sets it as a Postgres session variable before any query runs.

Row-level security policies on every table enforce that variable. Tenant A can never read tenant B's rows — not because the application filtered them out, but because the database rejected the read outright.

AI layer

Natural language in. Tenant-scoped data out.

The Ask endpoint pre-fetches three context slices from the tenant's database — revenue by day, top menu items, recent orders — and injects them as grounded context before calling Amazon Nova Lite on Bedrock via a cross-region inference profile.

The JWT authorizer rejects unauthenticated requests at API Gateway before any Lambda is invoked. The AI compute never runs for an unverified caller — so there is no cost exposure from open endpoints.

By the numbers

CDK stacks
9

one cdk deploy

Security layers
4

independent

Lambda functions
5

Python 3.12

WAF rule groups
4

OWASP + rate limit