# The Edge Layer Execution Model: Layered Responders And The No-Invalid-Request Principle

**version** v0.27.58
**date** 18 May 2026
**from** Human (project lead)
**to** Architect, Developer (lead), Security, @Dev
**type** Arch brief

---

## What This Is

The second brief in the security-tools series, building on the principles brief. Where that one established the why and the principles, this one defines **the execution model**: the layers the edge gateway runs across, what each layer can and cannot do, what responsibilities belong where, and the core principles that govern how traffic is handled.

The framing question the voice memo posed is worth keeping in view: **if you were building a firewall, a gateway, an application-aware edge engine in 2026, with agentic development and the capabilities we now have, what would you do differently?** The answer the brief develops is a multi-layer responder model where each layer runs at the substrate best suited to its job, where most traffic is rejected as fast and cheap as possible, and where the system knows exactly what valid traffic looks like because we control both client and server.

This brief covers the two CloudFront runtimes and their trade-offs, the layered-responder model, the cache-hit-versus-cache-miss distinction, the "not everything has to be online" insight, and the two core principles: **no invalid request should reach the server**, and **the edge should be hostile to our own applications too** (for bug-finding). It builds toward the next brief, which will detail what the first-phase Lambda functions actually do.

## The Plumbing Already Exists

Worth stating up front, because it shapes the effort estimate: **much of the deployment plumbing is already built**. SG/Compute already has support for CloudFront distributions, including pushing to Lambda functions. We already have a function that creates a simple CloudFront Function (the one built for host-header rewriting). The edge layer is, in significant part, **an extension of plumbing that already exists** rather than a greenfield build.

What needs adding is the plumbing specific to these new edge functions: deploying CloudFront Functions and Lambda@Edge functions with our security/routing/logging logic, measuring their performance, and managing their lifecycle. The foundation is there.

## The Two CloudFront Runtimes

CloudFront offers two execution environments, and the edge layer should use both, dancing between them based on what each is good at.

### CloudFront Functions: The Quick Decision Point

CloudFront Functions are the fast runtime. JavaScript, sub-millisecond startup, runs at every CloudFront edge location. The trade-offs:

| Property | CloudFront Functions |
|----------|----------------------|
| **Speed** | Sub-millisecond startup; the fastest option |
| **Language** | JavaScript (a constrained subset); fine, since the LLM writes it well |
| **Network access** | None |
| **Filesystem access** | None (but the function can be updated with embedded data) |
| **Compute limits** | Very tight; designed for quick decisions only |
| **Cost** | Extremely cheap per invocation |
| **Deployment** | Fast to update |

The voice memo named this the **"quick decision point"** and the insight is sharp: despite the limitations (no network, no filesystem, tight compute), **a great deal can be done here, because the only real constraint is no external dependencies**. And critically, **the function can be updated quickly with embedded data**: so a list of banned IPs, banned regions, or other lookup data can be baked into the function and refreshed by redeploying.

This is the right place for the fastest, cheapest decisions: IP blocking, region blocking, obvious-bad-traffic rejection, initial logging, cleanup of malformed requests. The voice memo's framing: **"why don't I do it at the edge? Why don't I do it in this layer one?"** If a check can be expressed as a fast lookup against embedded data, this is where it belongs.

The deployment-speed question matters here and the voice memo flagged it as something to measure: **how fast does a CloudFront Function update propagate?** If banning an IP means redeploying the function, the propagation time determines how quickly we can react. This needs measuring, because it shapes the whole reaction model.

### Lambda@Edge: The Capable Layer

Lambda@Edge is the slower but more capable runtime. The trade-offs:

| Property | Lambda@Edge |
|----------|-------------|
| **Speed** | Higher overhead than CloudFront Functions; cold starts possible |
| **Language** | Full Node.js (and others); fewer constraints |
| **Network access** | Yes; can make network calls, trigger other requests |
| **Filesystem access** | Yes; can load files from disk |
| **Compute** | Much more headroom than CloudFront Functions |
| **Cost** | More expensive per invocation than Functions |
| **Invocation points** | Can run on every request OR on every cache miss (and on response) |

This is the layer for decisions that need more than a fast lookup: anything requiring network calls, file loading, heavier analysis, or triggering downstream actions. The voice memo wants to **understand its performance, cost, and deployment model deeply**. This is the layer where the "when people talk about performance, I want hot data" demand applies most.

### The Cache-Hit Versus Cache-Miss Distinction

A subtlety the voice memo flagged: Lambda@Edge can be invoked at different points in the request lifecycle, and the cache-hit-versus-cache-miss distinction matters:

- **On every request** (viewer request/response): runs regardless of cache state
- **On every cache miss** (origin request/response): runs only when the request reaches the origin

This is a controllable lever. For our case it is particularly relevant because **some of our projects run without caching** (due to particular side-effects and state requirements). The edge layer lets us see and control this: which requests are cached, which are not, and where our logic runs relative to the cache.

## The Layered Responder Model

Putting the runtimes together produces a layered model the voice memo described as **"first responder, second responder, third responder"** or **"level one, level two, level three reaction."** Each layer has different speed, capability, and responsibility.

| Layer | Runtime | Speed | Capability | Responsibility |
|-------|---------|-------|------------|----------------|
| **Layer 1** | CloudFront Functions | Sub-ms | Fast lookups against embedded data; no network/files | Take every hit; log; block known-bad (IPs, regions); reject malformed; cheap cleanup |
| **Layer 2** | Lambda@Edge | Higher overhead | Network, files, heavier logic; runs on request or cache miss | Decisions needing more context; request validation; response processing |
| **Layer 3** | Lambda / containers / our compute | Variable | Full capability; async-capable | Heavy analysis, LLM decisions, async reactions, rule generation |

The key properties of this model:

- **Layer 1 takes every hit.** It is the universal first responder. Because it is sub-millisecond and nearly free, it can afford to see everything. This makes it the natural logging point and the first line of cleanup.
- **Layer 2 sees what gets past Layer 1**, and specifically what reaches the backend (on cache miss) or every request (if configured). It does the work that needs real compute.
- **Layer 3 is off the hot path.** It handles things that do not need to happen inline: analysis, LLM-driven decisions, rule generation, async reactions.

The responsibility question the voice memo posed (**"which responsibilities each layer has"**) is the core design decision. The principle: **push each decision to the fastest, cheapest layer that can make it.** A decision that can be a Layer 1 lookup should not be a Layer 2 network call. The art is in the placement.

## The "Not Everything Has To Be Online" Insight

One of the most important concepts in the voice memo, and one it noted is often misunderstood: **edge security reactions do not all have to happen in real time. We have time. We just have to respond within a period of time, not instantly.**

This is a genuinely important reframing. Most WAF thinking assumes every decision is inline: the request arrives, the system decides, the request is allowed or blocked, all within the request's lifetime. But many useful reactions do not need to be inline:

- Detecting that an IP is brute-forcing can happen over a window of requests, then result in a ban that takes effect for subsequent requests
- Analysing a suspicious traffic pattern can happen asynchronously, then update the Layer 1 banned-list
- Generating new rules from observed traffic can happen on a schedule, not per-request
- LLM-driven analysis of ambiguous traffic can take seconds, running async, then feed back into the fast layers

The voice memo's framing: **"the problem with most of this is that we don't have to respond in real time, we just have to respond within a period of time."** Even against an attacker, the right response is often "detect within seconds, react within seconds", not "decide in the request's 50ms lifetime."

This insight is what makes Layer 3 valuable. **Async reactions feed back into the fast layers.** The system observes (Layer 1 logs everything), analyses (Layer 3, async), and reacts (updates Layer 1's embedded data, Layer 2's rules). The feedback loop does not need to be inline; it needs to be timely.

This also justifies the LLM-driven approach from the principles brief. An LLM cannot run in a sub-millisecond Layer 1 function. But it can run async in Layer 3, analyse ambiguous traffic, and push updated rules down to Layer 1. **Slow analysis, fast enforcement.**

## Core Principle: No Invalid Request Should Reach The Server

The strongest principle in the voice memo, and the one that most distinguishes this edge layer from a generic WAF: **because we control both the client and the server, we know exactly what valid traffic looks like. So we should lock traffic down to exactly what is valid, and drop everything else.**

This is a fundamentally different security posture from a typical WAF. A generic WAF tries to identify and block known-bad traffic (signatures, patterns, anomalies) while allowing everything else. Our edge layer can invert this: **identify and allow known-good traffic, and drop everything else.** Allowlist, not denylist.

The voice memo stated it sharply: **"there should be no request made to the server that is not a valid request."** Anything that is brute-forcing, making noise, probing, or otherwise not a request the legitimate client would make should be dropped, sent on a wild goose chase, or otherwise handled, but never allowed to consume backend resources.

This is possible because we control the client. We know:

- Which endpoints the client actually calls
- What shape those requests have (headers, methods, parameters, body structure)
- What sequence of requests is legitimate
- What authentication every request should carry

Any request that does not match the known-good profile is, by definition, either an attack, a bug, or noise. None of those deserve backend resources.

### The Symmetry Principle: Endpoints And The Edge Move Together

A powerful consequence the voice memo drew out: **if the edge enforces "only valid requests," then deploying a new endpoint requires updating the edge to know about it.** The endpoint and the edge move together.

The voice memo's example: **should we publish the OpenAPI / Swagger definitions to the edge?** And the answer is **yes, eventually**, because why should the edge allow any call to an API endpoint that the API definition does not declare? If the OpenAPI spec is the source of truth for what the API accepts, the edge can enforce exactly that, rejecting anything outside the spec before it reaches the backend.

This creates a deployment discipline with real security value:

- Push a new endpoint without updating the edge → the edge rejects calls to it (fails safe)
- Push a new endpoint AND update the edge's allowlist → calls to it are permitted
- The edge's knowledge of valid traffic is always in sync with what is actually deployed

This is the symmetry: **the application and its edge protection are deployed together, as a unit.** The OpenAPI spec (or equivalent) becomes a deployment artefact that flows to the edge. This is more work per deployment, but the security payoff is large: the attack surface is exactly the declared surface, never more.

## Core Principle: Hostile To Our Own Applications Too

A second principle the voice memo emphasised, and an unusual one: **the edge should be hostile not just to attackers but to our own applications, for the purpose of finding bugs.**

The reasoning: if the edge enforces exactly what valid traffic looks like, then any request our own application makes that does not match the valid profile is a bug. A client-side JavaScript bug that makes a malformed request, calls a wrong endpoint, or generates a request storm will be caught by the edge the same way an attack would be.

The voice memo: **"I want this to be super hostile to our own applications, super hostile to our own environments, so we can know the difference between one version"** and the next. Every time a new version, capability, or endpoint is pushed, the edge must be updated too, and if it is not, the new behaviour fails, surfacing the discrepancy immediately.

This turns the edge into a **correctness check as well as a security check.** The runaway-redirect bug from the principles brief is exactly the kind of thing this catches: a bug that generates abnormal traffic gets caught at the edge before it generates abnormal cost. Being hostile to our own traffic is how we find our own bugs fast.

## The TUI/CLI/API-First Approach

Consistent with the TUI thread from yesterday, the voice memo was explicit: **this is a TUI, CLI, and TUI-API-first solution.** We develop, visualise, and control the edge layer through the CLI and TUI and the underlying classes first; a web interface comes later.

The performance question is where this matters most. The voice memo was emphatic: **"when people talk about performance, I want hot data."** The TUI is the natural place to show real-time edge performance: layer-by-layer latency, request volumes, block rates, cache hit/miss ratios, cost per layer. The live-event-stream and the topology screens from yesterday's first-five-screens brief apply almost directly to edge traffic visualisation.

This composes cleanly: the edge layer is a tool; it gets a TUI and a TUI API per the pattern established yesterday; operators watch and control traffic through that surface. **The thing the project lead most wants (real-time traffic visibility) is exactly what the TUI thread is built to provide.**

## Multi-CDN Future

The voice memo flagged that the design should anticipate running on CDNs beyond CloudFront, because **most CDNs now offer edge compute** (Cloudflare Workers, Akamai EdgeWorkers, Fastly Compute, etc.). The layered model should map onto other providers' edge runtimes:

| Our Layer | CloudFront | Cloudflare | Fastly |
|-----------|------------|------------|--------|
| Layer 1 (fast) | CloudFront Functions | Workers (fast path) | Compute@Edge |
| Layer 2 (capable) | Lambda@Edge | Workers (with bindings) | Compute@Edge |
| Layer 3 (async) | Lambda / our compute | Workers + Queues / our compute | Our compute |

The principle from the principles brief (substrate independence) applies here. We design the layered model abstractly, implement it first on CloudFront, and keep the core logic portable to other CDN edge runtimes. This is the beginning of genuine edge-computing capability across providers.

## What This Asks For

Concrete next steps:

1. **Measure CloudFront Function deployment propagation time.** This shapes the reaction model; we need real numbers.
2. **Measure Lambda@Edge cold-start and warm latency** at the relevant invocation points.
3. **Build the Layer 1 CloudFront Function** with embedded-data lookup (banned IPs/regions) and logging.
4. **Build the Layer 2 Lambda@Edge function** with request validation against known-good profiles.
5. **Establish the Layer 3 async path** for analysis and rule-generation feeding back to Layer 1/2.
6. **Define the known-good traffic profile mechanism** (how the edge knows what valid looks like; OpenAPI integration).
7. **Implement the symmetry discipline** (deploying an endpoint updates the edge).
8. **Build the edge TUI** showing real-time per-layer performance and traffic.
9. **Extend the existing SG/Compute CloudFront plumbing** to deploy these functions.
10. **Document the layer-placement decision framework** (which decisions go to which layer).

Estimated effort: 2-3 weeks for the layered model with Layer 1 and Layer 2 working and the TUI showing real data. Layer 3 async and the OpenAPI symmetry are follow-on.

## What This Does Not Try To Be

Deliberate scope limits:

- **Not SSL termination (yet).** The voice memo was explicit: SSL termination comes later. v1 assumes it is handled upstream.
- **Not a full feature-parity AWS WAF replacement.** It does what we need, not everything AWS WAF does.
- **Not LLM-on-the-hot-path.** LLM decisions are Layer 3, async.
- **Not multi-CDN in v1.** CloudFront first; the design anticipates multi-CDN but does not implement it yet.
- **Not the specific Layer 2 logic.** That is the next brief; this one is the execution model.

## Honest Risks

Three risks:

**Risk 1: The allowlist (no-invalid-request) model is operationally demanding.** Every endpoint change requires an edge update; get the discipline wrong and legitimate traffic gets blocked. Mitigation: the symmetry discipline must be automated (OpenAPI flows to the edge as part of deployment); start in observe-mode (log what would be blocked) before enforce-mode.

**Risk 2: Layer placement is easy to get wrong.** Putting too much in Layer 1 hits its limits; putting too much in Layer 2 adds latency and cost. Mitigation: the layer-placement framework; measure everything; move logic between layers based on data, not guesses.

**Risk 3: Deployment propagation may be slower than the reaction model needs.** If banning an IP takes minutes to propagate, fast attacks win. Mitigation: measure first (step 1); if Layer 1 redeploy is too slow, use a fast-updating data source (a Layer 2 lookup against frequently-updated storage) for time-sensitive bans.

## Open Questions

| Question | Notes |
|----------|-------|
| How fast does a CloudFront Function update propagate? | Must measure; shapes the whole reaction model |
| Lambda@Edge cold-start impact at our volumes? | Must measure; determines viability for inline use |
| OpenAPI-to-edge: automatic or manual? | Should be automatic (part of deploy); manual for v1 prototype |
| Banned-list storage: embedded in function or external lookup? | Embedded for slow-changing; external for fast-updating; probably both |
| Observe-mode before enforce-mode: how long? | Until we trust the known-good profile; per-endpoint |
| How do we handle legitimate traffic the profile does not yet know about? | Observe-mode catches it; alert before enforcing |
| Layer 3 substrate: Lambda, container, or our compute? | Probably our compute for the heavy/LLM work |
| Wild-goose-chase responses for bad traffic: worth building? | Maybe; tarpitting has value but adds complexity; v2 |

## Relationship To Previous Briefs

| Date | Document | Relationship |
|---|---|---|
| 18 May | `v0.27.58__arch-brief__edge-security-and-logging-layer-principles.md` | The principles this execution model implements |
| 17 May | `v0.27.55__arch-brief__tui-api-structured-surface-for-text-uis.md` | The edge layer is TUI/CLI/API-first per this pattern |
| 17 May | `v0.27.55__dev-brief__sg-edge-tui-first-five-screens.md` | The live-event-stream and topology screens apply to edge traffic |
| 17 May | `v0.27.55__article__de-commoditising-the-commodity.md` | The edge layer is the shield over AWS WAF attrition |
| 16 May | `v0.27.45__dev-brief__on-demand-vault-provisioning-workflows.md` | The CloudFront plumbing and host-header function this extends |
| 16 May | `v0.27.45__arch-brief__vault-discovery-and-public-keys.md` | PKI / known-good auth uses the public-key work |
| 16 May | `v0.27.45__strategy-brief__sg-compute-as-serverless-environment.md` | The substrate spectrum the layers map onto |
| 16 May | `v0.27.45__strategy-brief__multi-cloud-deployment-and-agent-communication.md` | The multi-CDN future this anticipates |
| 15 May | `v0.27.43__arch-brief__unified-observability-session.md` | Where edge logs flow |

---

## Acceptance Criteria

| # | Criterion | Verification |
|---|-----------|-------------|
| 1 | CloudFront Function deployment propagation time measured | Real number documented |
| 2 | Lambda@Edge latency (cold and warm) measured | Real numbers documented |
| 3 | Layer 1 function blocks known-bad and logs every hit | Working at the edge |
| 4 | Layer 2 function validates requests against known-good profile | Working on request/cache-miss |
| 5 | Layer 3 async path analyses and feeds rules back to Layer 1/2 | Feedback loop works |
| 6 | The no-invalid-request principle is enforced for at least one endpoint | Allowlist works; invalid dropped |
| 7 | The symmetry discipline (endpoint deploy updates edge) works | Tested end-to-end |
| 8 | The edge is hostile to a deliberately-malformed own-app request | Bug-finding behaviour proven |
| 9 | The edge TUI shows real-time per-layer performance | Hot data visible |
| 10 | The layer-placement framework is documented | Decisions are principled, not ad hoc |
| 11 | Existing SG/Compute CloudFront plumbing extended for these functions | Deployment works |

---

This document is released under the Creative Commons Attribution 4.0 International licence (CC BY 4.0).
