WEB / WEB-20.02
Microservices, gateways, and intermediaries
Trace a public read through service, replica, edge reuse, and policy decision ownership.
1. Core · Mechanism
Read every scenario without motion
Service return
- Start at gateway
The public read has already reached the gateway; its prepared notes-b message has not arrived at the receiver.
- Browser
- Browser waiting
- Gateway / balancer
- notes-b message prepared
- Notes replica
- Notes has no request
- Index service
- Index has no request
- Edge cache / policy
- Edge inactive here
- Notes arrival
The prepared public read arrives at notes-b; the index service still has no knowledge of a request.
- Browser
- Browser waiting
- Gateway / balancer
- notes-b message prepared
- Notes replica
- Public read received
- Index service
- Index has no request
- Edge cache / policy
- Edge inactive here
- Index prepared
Notes locally prepares the tea category query; this is processing rather than a new wire arrival.
- Browser
- Browser waiting
- Gateway / balancer
- notes-b message prepared
- Notes replica
- Index query prepared
- Index service
- Index has no request
- Edge cache / policy
- Edge inactive here
- Index arrival
Index learns the tea query only on arrival; the notes sender and waiting browser retain their previous knowledge.
- Browser
- Browser waiting
- Gateway / balancer
- notes-b message prepared
- Notes replica
- Index query prepared
- Index service
- tea query received
- Edge cache / policy
- Edge inactive here
- Category prepared
Index prepares the Tea category response from its own public data; notes has not received that result yet.
- Browser
- Browser waiting
- Gateway / balancer
- notes-b message prepared
- Notes replica
- Index query prepared
- Index service
- Tea response prepared
- Edge cache / policy
- Edge inactive here
- Notes return
The category response arrives at notes; the gateway stays in its prior waiting state and does not know the composed result.
- Browser
- Browser waiting
- Gateway / balancer
- notes-b message prepared
- Notes replica
- Tea category received
- Index service
- Tea response prepared
- Edge cache / policy
- Edge inactive here
- Compose prepared
Notes composes title and category under its contract; delivering that JSON to the gateway remains a separate event.
- Browser
- Browser waiting
- Gateway / balancer
- notes-b message prepared
- Notes replica
- Composed JSON prepared
- Index service
- Tea response prepared
- Edge cache / policy
- Edge inactive here
- Gateway arrival
The composed response arrives at the gateway; this bounded scene ends here without claiming browser delivery.
- Browser
- Browser waiting
- Gateway / balancer
- Composed result received
- Notes replica
- Composed JSON prepared
- Index service
- Tea response prepared
- Edge cache / policy
- Edge inactive here
Cache hit
- Read prepared
The browser prepares an ordinary public read; the edge cache and policy actor has not seen it yet.
- Browser
- Public read prepared
- Gateway / balancer
- Gateway has no request
- Notes replica
- Notes has no request
- Index service
- Index has no request
- Edge cache / policy
- Edge has no request
- Edge arrival
The request reaches the edge on arrival; gateway, notes, and index states still show no forwarded request.
- Browser
- Public read prepared
- Gateway / balancer
- Gateway has no request
- Notes replica
- Notes has no request
- Index service
- Index has no request
- Edge cache / policy
- Public request received
- Cache hit
Logical age2 is below ttl5, so the public cover is fresh; the edge response is prepared with zero origin calls.
- Browser
- Public read prepared
- Gateway / balancer
- Gateway has no request
- Notes replica
- Notes has no request
- Index service
- Index has no request
- Edge cache / policy
- Fresh cover prepared
- Browser arrival
The edge’s prepared response arrives at the browser; the other actors still have not received a request.
- Browser
- Tea cover received
- Gateway / balancer
- Gateway has no request
- Notes replica
- Notes has no request
- Index service
- Index has no request
- Edge cache / policy
- Fresh cover prepared
- Result distinction
The browser locally classifies the response; this state proves neither origin availability nor private authorization.
- Browser
- Public cover visible
- Gateway / balancer
- Gateway has no request
- Notes replica
- Notes has no request
- Index service
- Index has no request
- Edge cache / policy
- Fresh cover prepared
No replica
- Request known
The gateway has already received the public read; selection of an eligible replica and forwarding have not happened.
- Browser
- Browser waiting
- Gateway / balancer
- Public read received
- Notes replica
- Notes has no request
- Index service
- Index has no request
- Edge cache / policy
- Edge inactive here
- No replica
The local eligible-set evaluation finds no ready instance; no service arrival is invented.
- Browser
- Browser waiting
- Gateway / balancer
- Eligible set empty
- Notes replica
- Notes has no request
- Index service
- Index has no request
- Edge cache / policy
- Edge inactive here
- 503 prepared
The selected unavailable policy prepares 503 at the gateway; notes and index have received no request.
- Browser
- Browser waiting
- Gateway / balancer
- 503 response prepared
- Notes replica
- Notes has no request
- Index service
- Index has no request
- Edge cache / policy
- Edge inactive here
- Browser arrival
The prepared unavailable response reaches the browser; the failure boundary remains gateway selection.
- Browser
- 503 response received
- Gateway / balancer
- 503 response prepared
- Notes replica
- Notes has no request
- Index service
- Index has no request
- Edge cache / policy
- Edge inactive here
- Caller classifies
The browser classifies the response as unavailable; this local classification does not claim origin recovery.
- Browser
- Unavailable visible
- Gateway / balancer
- 503 response prepared
- Notes replica
- Notes has no request
- Index service
- Index has no request
- Edge cache / policy
- Edge inactive here
Policy closed
- Read prepared
The browser prepares an ordinary public read; the edge cache and policy actor has not seen it yet.
- Browser
- Public read prepared
- Gateway / balancer
- Gateway has no request
- Notes replica
- Notes has no request
- Index service
- Index has no request
- Edge cache / policy
- Edge has no request
- Edge arrival
The request reaches the edge on arrival; gateway, notes, and index states still show no forwarded request.
- Browser
- Public read prepared
- Gateway / balancer
- Gateway has no request
- Notes replica
- Notes has no request
- Index service
- Index has no request
- Edge cache / policy
- Public request received
- Policy decision
The supplied maintenance closure locally blocks the ordinary request; 403 is prepared without forwarding to origin.
- Browser
- Public read prepared
- Gateway / balancer
- Gateway has no request
- Notes replica
- Notes has no request
- Index service
- Index has no request
- Edge cache / policy
- 403 block prepared
- Browser arrival
The edge’s prepared response arrives at the browser; the other actors still have not received a request.
- Browser
- 403 response received
- Gateway / balancer
- Gateway has no request
- Notes replica
- Notes has no request
- Index service
- Index has no request
- Edge cache / policy
- 403 block prepared
- Policy denial classified
The browser classifies the 403 response as a maintenance-policy denial. The request did not reach the origin; this decision does not establish that private authorization works correctly.
- Browser
- Policy error visible
- Gateway / balancer
- Gateway has no request
- Notes replica
- Notes has no request
- Index service
- Index has no request
- Edge cache / policy
- 403 block prepared
ACTORS · STATE · DATA FLOW
A service boundary is more than a URL
Microservices do not mean exposing every application function as another HTTP endpoint. A service carries a contract, release boundary, and data ownership around a business capability and bounded context. The notes service can own note representations while an index service owns a search summary. These are separate logical owners in the example. Their placement on machines, processes, or regions does not follow from that distinction. A route count cannot establish independent deployment.
In service-to-service communication the caller need not be a browser. Notes becomes the client of the next hop when it requests an index representation, while retaining its server responsibility for the response it composes. A synchronous call introduces a dependency on that result; messaging has different completion and retry boundaries. A commit in one service does not prove a simultaneous commit elsewhere. Transport identity, TLS trust, and permission for a particular note are separate decisions.
The normal ledger branch starts after the gateway has received the public read and prepared a message for notes-b. notes-a is not eligible. Notes requests the index, the index produces the Tea category, and responses return as far as the gateway. The browser still awaits a response at the final snapshot. A response arriving at the gateway has not yet arrived at the browser. The native check runs fixed local adapters; the illustrated service hops are conceptual messages rather than network captures.
The different questions asked by gateway, load balancer, CDN, and WAF
An API gateway can route a public contract to a service, and a product may also provide authentication, quotas, or transformations. A load balancer distributes work among instances of the selected service. Layer 4 selection and Layer 7 selection using HTTP methods or paths have different visibility. A reverse proxy can act as a server outward and as a client on an inward connection. We still ask which resource owner produced the representation rather than treating every intermediary as the same origin.
A CDN can return selected cacheable representations without contacting the origin. The fixed public asset hit has zero origin calls; this does not prove that the origin is currently available or that business data is current. Misses, freshness, and invalidation retain their own rules from WEB-09.02 and WEB-19.01. Edge cache and gateway are separate actors here, although a real product may combine roles or arrange them differently.
A WAF applies configured request policy. Allow, block, and count have different outcomes; a count observation does not itself stop a request. The closure branch applies a declared maintenance predicate to an ordinary public read and prepares 403. It is not an AWS rule or an attack-matching example. WAF allowance does not replace authorization for the note, and the service retains its purpose/resource decision. A final status alone may not reveal whether cache, origin availability, or edge policy determined the result.
2. Red · Trust & Impact
Read every scenario without motion
No ready instance
- Which service was requested?
A public-note request can map to a service contract. Recognizing the route does not establish a currently eligible instance for that service.
- Gateway decision
- public note route
- Service path
- Instance not selected yet
- Trust assumption
- Eligibility pending
- The eligible set is empty
The noOrigin branch supplies eligible=[]. The gateway sees no eligible instance in this snapshot and cannot invent an instance name outside it.
- Gateway decision
- eligible=[]
- Service path
- selected=null
- Trust assumption
- No eligible destination
- No forwarding occurred
Forwarded=false does not describe failed service-side processing. This request found no eligible instance to forward to.
- Gateway decision
- eligible=[]
- Service path
- forwarded=false
- Trust assumption
- Failure at routing boundary
- The 503 is prepared here
NoOrigin.status=503 is the gateway’s HTTP outcome for this branch. It is not evidence that downstream notes or index responded.
- Gateway decision
- status=503
- Service path
- selected=null / forwarded=false
- Trust assumption
- Gateway outcome only
- Health does not establish permission
Notes-b may be eligible under ready=true in another branch. Health does not grant a user permission over a particular note; availability and authorization are separate conditions.
- Gateway decision
- noOrigin: eligible=[]
- Service path
- no forwarding in this branch
- Trust assumption
- Ready != object permission
- Report the responsible failure boundary
The known boundary is gateway instance selection. Do not invent private-permission, notes-processing or browser-receipt outcomes without their observations.
- Gateway decision
- gateway selection failed
- Service path
- forwarded=false
- Trust assumption
- Other outcomes not observed
Maintenance
- Establish the ordinary public request
The policyClosed target is /public/notes/tea. Being public does not mean maintenance policy must admit it.
- Gateway decision
- target=/public/notes/tea
- Service path
- Forwarding not inspected yet
- Trust assumption
- Policy decision pending
- The configured predicate is closed
MaintenanceClosed=true is explicitly supplied. This is a selected policy input, not a conclusion that the request is an attack.
- Gateway decision
- maintenanceClosed=true
- Service path
- Service not processed
- Trust assumption
- No attack attribution from policy alone
- The policy selected block
Action=block and status=403 are produced at this layer. Do not rename this as the notes object owner’s authorization decision.
- Gateway decision
- action=block / status=403
- Service path
- Service not processed
- Trust assumption
- Maintenance policy outcome
- The request was not forwarded
Forwarded=false shows no work was handed to notes service for this request. Policy block and downstream error are different events.
- Gateway decision
- maintenance block
- Service path
- forwarded=false
- Trust assumption
- No downstream result in this branch
- Keep count separate from block
Configured count may record an observation while block may stop a request. This branch supplies block; do not infer another action from a product label or counter.
- Gateway decision
- action=block
- Service path
- forwarded=false
- Trust assumption
- Configured action determines this outcome
- Evaluate resource permission separately
If policy admits a request, the service still needs its object/action decision. This public maintenance example does not verify private authorization or a real vendor WAF.
- Gateway decision
- maintenance policy observed
- Service path
- public route only
- Trust assumption
- privateAuthorizationVerified=false
ASSUMPTION · BOUNDARY · CONTROL
Extending one hop’s success to the whole flow
Finding a route at the gateway does not establish that the chosen replica will reply or that its index dependency will return a usable result. Treating these as equivalent can make ordinary dependency failure appear as a completed result with empty or stale data. Review where each decision was produced and what response the caller actually received. Ending the normal scene at the gateway makes the boundary explicit: undelivered browser results cannot be marked complete.
Health information describes eligibility at an observation point. It does not confer permission for a business operation or indefinite availability. A read routed to a ready instance can still fail. When every instance is ineligible in the supplied snapshot, the gateway prepares 503 without calling a service. The control distinguishes an empty eligible set, an attempted forward, and a received result, instead of inventing an instance or an arrival.
Intermediary trust and domain permission
Edge allowance and recognition of a route are not domain authorization. A private service must bind caller identity, intended audience, operation, and object ownership in a trusted context. This fixture handles public reads only and does not claim to verify private permissions. A header or internal-looking service name alone is not identity evidence. If TLS termination points differ, each hop needs its own confidentiality and peer-trust boundary.
A CDN hit reuses a representation under its declared cache policy; misreading it as evidence of an origin call distorts observation. Counting WAF monitoring as blocking, or treating blocking as comprehensive domain authorization, also misstates coverage. The benign ledger can be read through source, policyResult, selectedReplica, and originCalls together. These are synthetic teaching fields for ownership, not an invented vendor logging format.
3. Blue · Secure development & defense
Read every scenario without motion
Ends at gateway
- Read replica selection from the record
The local routing adapter produces replica selection; the example’s service record produces originCalls and composed category. A JSON roundtrip rereads only those fields. The normal branch has notes-a ready=false and notes-b ready=true. Notes-b is selected; this snapshot does not establish health at another time.
- Edge / gateway observation
- selected=notes-b
- Service outcome
- Composed result not inspected yet
- Delivery evidence
- Browser receipt unknown
- The index result belongs to notes processing
IndexResponse.category=Tea is the category representation received by notes service. It does not establish arrival of the complete response at gateway or browser.
- Edge / gateway observation
- selected=notes-b
- Service outcome
- index category=Tea
- Delivery evidence
- Other receipts separate
- Notes composed the result
The normal response combines title=Tea note and category=Tea. Composition depends on notes receiving the required index result.
- Edge / gateway observation
- notes-b source
- Service outcome
- title=Tea note / category=Tea
- Delivery evidence
- Composed result available
- The record ends at gateway
StopsAt says gateway received result. This branch’s observed completion is gateway receipt of the service result; browser delivery is explicitly absent.
- Edge / gateway observation
- gateway received result
- Service outcome
- composed title / category
- Delivery evidence
- browser delivery not shown
- Do not copy gateway receipt into browser state
Without separate browser-receipt evidence, browser status and UI outcome remain unestablished. One owner’s knowledge cannot be written as another’s.
- Edge / gateway observation
- gateway result observed
- Service outcome
- service composition observed
- Delivery evidence
- Browser status / UI unknown
- Observe the missing hop for the same request
To establish delivery, inspect browser receipt and consumer outcome for the same request. Another request’s 200 does not complete this journey’s missing hop.
- Edge / gateway observation
- same request correlation required
- Service outcome
- gateway completion observed
- Delivery evidence
- Browser evidence still required
No origin call
- Establish cache scope first
The local routing adapter produces replica selection; the example’s service record produces originCalls and composed category. A JSON roundtrip rereads only those fields. The cacheHit branch stores Tea cover under public-cover-v1. It describes a public cover representation, not a personal note or every endpoint.
- Edge / gateway observation
- key=public-cover-v1
- Service outcome
- Origin not inspected yet
- Delivery evidence
- Scope: public cover
- The selected freshness condition passed
Stored=10, now=12 and ttl=5 give entry age 2, within the selected reuse window.
- Edge / gateway observation
- age=2 / ttl=5
- Service outcome
- Origin not inspected yet
- Delivery evidence
- Selected cache reuse eligible
- The body source is edge-cache
Source=edge-cache and body=Tea cover identify the edge as response source. Equal body text does not establish an origin call.
- Edge / gateway observation
- source=edge-cache / Tea cover
- Service outcome
- Origin calls examined separately
- Delivery evidence
- Body equality != source equality
- Origin call count is zero
OriginCalls=0 separately records no origin contact in this branch. It does not establish current origin health or the newest data revision.
- Edge / gateway observation
- public cover reused
- Service outcome
- originCalls=0
- Delivery evidence
- Origin health / newest revision unknown
- A cache hit does not measure another owner’s availability
Since origin was not involved in the cache hit, its live state requires separate measurement. Success here concerns reuse of the selected stored representation.
- Edge / gateway observation
- source=edge-cache
- Service outcome
- originCalls=0
- Delivery evidence
- Cache availability != origin availability
- Report scope together with response source
Report the public key’s edge response, selected freshness condition and zero origin calls. Do not add private permission or current origin business outcomes.
- Edge / gateway observation
- public-cover-v1 / edge-cache
- Service outcome
- originCalls=0
- Delivery evidence
- Only the observed reuse is established
IMPLEMENTATION · SECURITY CONTROL · VERIFICATION
Record roles and failure boundaries
The local routing adapter produces replica selection; the example’s service record produces originCalls and composed category. A JSON roundtrip rereads only those fields. Write the decision made by each box before its product name: can the edge reuse a representation, which service contract does the gateway select, which eligible replica does the balancing policy choose, and which data does notes own? Combining roles in an appliance does not merge their authority. Keep the method, target, and intended public-read purpose visible together. A trace identifier should not be treated as a secret or permission key.
The local adapter selects the first eligible instance deterministically, without claiming a vendor default algorithm. notes-a false and notes-b true selects b, while an empty set yields no-origin. A composed result is prepared only after notes receives the index response. Operational designs also manage contract versions, budgets, and correlation information; this fixture provides no cluster latency measurement.
Bind the notes operation to a defined backend contract in gateway routing configuration; selecting an eligible replica grants no resource permission. If the public read becomes a protected operation, the service must make its current actor, action and object decision at its endpoint; gateway or WAF acceptance does not replace it. An implementation test would distinguish routing acceptance from service permission denial. This lesson’s public-note fixture executes no authentication and verifies only absence of forwarding in the no-origin branch.
Bind distinct evidence to distinct results
Check the public asset key and logical freshness input in the cache-hit branch, the explicit block decision in the policy branch, and absence of forwarding in the unavailable-origin branch. These cases explain different decisions rather than repeating one failure. Native checks run an own dictionary cache, routing adapter, and public index builder. An independent JSON roundtrip checks selected replica, origin calls, and category relationships; it is not a CloudFront or WAF request.
A deployed system needs different evidence: CDN policies, health-observation age, WAF actions, routing contracts, and service-side access control. The XML selector here only separates a declared no-eligible decision from an inconsistent forward observation. Zero matches from a missing event are not evidence of a good control. In the scene reducer, the prepared message changes receiver state only on arrival, so movement remains tied to ownership.
NOW APPLY IT TO THE CASE
Which owner knows gateway results, edge cache hits and origin selection?
The Atlas gateway composes notes-service and index-service results for a public tea note. In another branch, the edge returns a stored Tea cover without contacting origin. Different requests in the same architecture can finish at different owners.
Which components contribute to the case response? Show where UI, service, platform and external-provider outcomes complete along their respective hops.
Open the related case file ↗READ THE EXAMPLE TOGETHER
Service hops / edge decision ledger
Select a field and examine what it supports and where the evidence ends.
Read the raw artifact and field explanations
{
"roles": {
"gateway": "service contract routing",
"balancer": "first eligible instance in supplied list",
"edge": "public cache/policy roles combined for diagram",
"notes": "note representation",
"index": "category representation"
},
"normal": {
"request": {
"method": "GET",
"target": "/public/notes/tea"
},
"eligible": [
{
"id": "notes-a",
"ready": false
},
{
"id": "notes-b",
"ready": true
}
],
"selected": "notes-b",
"indexRequest": {
"id": "tea"
},
"indexResponse": {
"category": "Tea"
},
"response": {
"id": "tea",
"title": "Tea note",
"category": "Tea"
},
"stopsAt": "gateway received result; browser delivery not shown"
},
"cacheHit": {
"key": "public-cover-v1",
"stored": 10,
"now": 12,
"ttl": 5,
"body": "Tea cover",
"source": "edge-cache",
"originCalls": 0
},
"noOrigin": {
"eligible": [],
"selected": null,
"forwarded": false,
"status": 503
},
"policyClosed": {
"ordinaryTarget": "/public/notes/tea",
"predicate": "supplied maintenanceClosed=true",
"action": "block",
"status": 403,
"forwarded": false
},
"limits": {
"networkExecuted": false,
"vendorGatewayExecuted": false,
"realWafExecuted": false,
"realCdnExecuted": false,
"privateAuthorizationVerified": false
},
"selector": {
"language": "XPath",
"xml": "<audit><route eligible=\"0\" forwarded=\"false\"/></audit>",
"xpath": "count(/audit/route[@eligible='0' and @forwarded='true'])",
"expected": 0,
"positiveFixtureXml": "<audit><route eligible=\"0\" forwarded=\"true\"/></audit>",
"positiveExpected": 1,
"scope": "Authored inert decision ledger only; these are teaching fields, not product log or API field names.",
"missingFieldBehavior": "A missing observation is insufficient evidence; zero matches alone proves no runtime control."
}
}- normal
- Service composition ends at gateway arrival; browser completion is separate.
- cacheHit/noOrigin
- Reuse and eligibility decisions produce different origin call counts.
- policyClosed/roles
- Supplied maintenance predicate, not a real WAF rule or permission decision.
- selector/limits
- Own adapter/XML ledger; no real CDN, gateway, or network execution.
This example separates public routing, caching and maintenance-policy decisions. Remote hops show information transfer rather than captured gateway, WAF or CDN traffic. A public response does not establish that private resource authorization works correctly.
Two reality checks
Gateway, load balancer, CDN, and WAF make the same decision.
Service routing, instance selection, representation reuse, and request policy have separate ownership.
A gateway response arrival or CDN hit completes the entire origin flow.
Gateway arrival is not browser arrival; a cache hit proves neither an origin call nor origin health.
YOUR TURN
Work through this story.
Predict the outcome, find the evidence boundary, and explain it in your own words.
The eligible-instance list is empty. Where does the selected balancer forward the request?
- It forwards to an arbitrary presumed-healthy default instance.
- Nowhere; forwarded=false and status 503.
Read the explained answer
Nowhere; forwarded=false and status 503. — A null selection from the readiness list creates neither fan-out nor a default trusted node.
The gateway received a result. Is it proved that the browser learned the Tea note title?
Selected lesson artifact fields; teaching example
- normal.selected
- notes-b
- normal.response
- {"id":"tea","title":"Tea note","category":"Tea"}
- normal.stopsAt
- gateway received result; browser delivery not shown
- No; the trace ends at gateway receipt.
- Yes; once an upstream response exists, all consumers know it.
Read the explained answer
No; the trace ends at gateway receipt. — The gateway knows the representation; browser delivery/body/view are absent from the selected ledger.
The public edge-cache hit has originCalls=0. The closed-policy case has status 403 and no forwarding. Why do these outcomes not prove private-resource authorization?
Read the explained answer
The cache hit returns the selected public-cover body without the origin. The predefined MaintenanceClosed branch stops local forwarding. Neither validates private subject/object permission; realWaf/Cdn/vendorGateway/networkExecuted remain false.
□ I did not count edge maintenance/cache decisions as private authorization.
□ I did not count declared topology as vendor-deployment proof.
Open the application console · request / response / browser
Also open request, URL, cookie and DOM examples
Sources and scope
- Microsoft Learn — Microservices architecture styleWhat are microservices? · Components · Challenges · Best practices
- Microsoft Learn — Gateway Routing patternSolution · Multiple instances of the same service · Issues and considerations
- Microsoft Learn — Load balancing optionsOpening paragraphs: distribution across computing resources · Azure load balancing services
- RFC 9110 — HTTP Semantics3.6. Origin Server · 3.7. Intermediaries · 3.8. Caches · 15.6.3. 502 Bad Gateway · 15.6.4. 503 Service Unavailable · 15.6.5. 504 Gateway Timeout
- Amazon CloudFront — How CloudFront delivers contentHow CloudFront delivers content to your users · How CloudFront works with regional edge caches
- AWS WAF — What is AWS WAF?What is AWS WAF?
- OWASP — REST Security Cheat SheetHTTPS · Access Control · Input validation · Error handling