Hacker DirectoryHacker Directory

WEB / WEB-09.01

Proxy roles and forwarded context

Distinguish who chooses a proxy, which message fields it changes, and the provenance of the context it forwards.

CORE · RED · BLUE · ARTIFACT · PRACTICE

1. Core · Mechanism

Read every scenario without motion

Owned chain

  1. Initial context

    The client is ready to request GET /notes. The Atlas edge and proxy have not received it; the application has not accepted external-client or scheme context. Receipt and a later local provenance check determine the result.

    Client / local peer
    Normal GET /notes ready; external context untrusted
    Owned edge
    Owned edge idle; own observations ready
    Owned proxy
    Owned proxy idle; edge gate not evaluated
    Application
    Application idle; derived context unused
  2. Normal request at edge

    The browser’s normal HTTP message arrived at the owned edge; external forwarded context has not been accepted as trust evidence.

    Client / local peer
    Normal GET /notes ready; external context untrusted
    Owned edge
    Request received; external context untrusted pending
    Owned proxy
    Owned proxy idle; edge gate not evaluated
    Application
    Application idle; derived context unused
  3. Approved context reconstructed

    The owned edge reconstructs fields from approved authority and observed scheme; it selects client node 192.0.2.10 without claiming user authentication.

    Client / local peer
    Normal GET /notes ready; external context untrusted
    Owned edge
    External context discarded; first rebuilt; for=192.0.2.10; proto=https
    Owned proxy
    Owned proxy idle; edge gate not evaluated
    Application
    Application idle; derived context unused
  4. Rebuilt request received

    The edge’s reconstructed message arrived at the reverse proxy; its local peer/topology gate has not completed yet.

    Client / local peer
    Normal GET /notes ready; external context untrusted
    Owned edge
    External context discarded; first rebuilt; for=192.0.2.10; proto=https
    Owned proxy
    Edge message received; provenance gate pending
    Application
    Application idle; derived context unused
  5. Owned hop append

    The selected approved-edge and intact-channel conditions are true; the proxy appends its incoming peer context as the rightmost element.

    Client / local peer
    Normal GET /notes ready; external context untrusted
    Owned edge
    External context discarded; first rebuilt; for=192.0.2.10; proto=https
    Owned proxy
    Edge trusted; second element appended; for=198.51.100.20
    Application
    Application idle; derived context unused
  6. Forwarded message received

    The normal two-element message arrived at the application; receipt alone is not acceptance of derived context.

    Client / local peer
    Normal GET /notes ready; external context untrusted
    Owned edge
    External context discarded; first rebuilt; for=192.0.2.10; proto=https
    Owned proxy
    Edge trusted; second element appended; for=198.51.100.20
    Application
    Message received; context acceptance pending
  7. Application context gate

    Approved immediate peer, secured transport, topology, and edge reconstruction are all true; context is accepted while user permissions remain separate and unmodeled.

    Client / local peer
    Normal GET /notes ready; external context untrusted
    Owned edge
    External context discarded; first rebuilt; for=192.0.2.10; proto=https
    Owned proxy
    Edge trusted; second element appended; for=198.51.100.20
    Application
    Context accepted; client=192.0.2.10; userAuth=false; resourceAuth=false

Privacy alias

  1. Initial context

    The client is ready to request GET /notes; this branch will use the edge’s per-request _atlasOnce alias. The alias has not reached the application. Accepting context will establish neither a stable user identity nor resource permission.

    Client / local peer
    Normal GET /notes ready; external context untrusted
    Owned edge
    Owned edge idle; own observations ready
    Owned proxy
    Owned proxy idle; edge gate not evaluated
    Application
    Application idle; derived context unused
  2. Normal request at edge

    The browser’s normal HTTP message arrived at the owned edge; external forwarded context has not been accepted as trust evidence.

    Client / local peer
    Normal GET /notes ready; external context untrusted
    Owned edge
    Request received; external context untrusted pending
    Owned proxy
    Owned proxy idle; edge gate not evaluated
    Application
    Application idle; derived context unused
  3. Approved context reconstructed

    The owned edge reconstructs fields from approved authority and observed scheme; it selects client node _atlasOnce without claiming user authentication.

    Client / local peer
    Normal GET /notes ready; external context untrusted
    Owned edge
    External context discarded; first rebuilt; for=_atlasOnce; proto=https
    Owned proxy
    Owned proxy idle; edge gate not evaluated
    Application
    Application idle; derived context unused
  4. Rebuilt request received

    The edge’s reconstructed message arrived at the reverse proxy; its local peer/topology gate has not completed yet.

    Client / local peer
    Normal GET /notes ready; external context untrusted
    Owned edge
    External context discarded; first rebuilt; for=_atlasOnce; proto=https
    Owned proxy
    Edge message received; provenance gate pending
    Application
    Application idle; derived context unused
  5. Owned hop append

    The selected approved-edge and intact-channel conditions are true; the proxy appends its incoming peer context as the rightmost element.

    Client / local peer
    Normal GET /notes ready; external context untrusted
    Owned edge
    External context discarded; first rebuilt; for=_atlasOnce; proto=https
    Owned proxy
    Edge trusted; second element appended; for=198.51.100.20
    Application
    Application idle; derived context unused
  6. Forwarded message received

    The normal two-element message arrived at the application; receipt alone is not acceptance of derived context.

    Client / local peer
    Normal GET /notes ready; external context untrusted
    Owned edge
    External context discarded; first rebuilt; for=_atlasOnce; proto=https
    Owned proxy
    Edge trusted; second element appended; for=198.51.100.20
    Application
    Message received; context acceptance pending
  7. Application context gate

    Approved immediate peer, secured transport, topology, and edge reconstruction are all true; context is accepted while user permissions remain separate and unmodeled.

    Client / local peer
    Normal GET /notes ready; external context untrusted
    Owned edge
    External context discarded; first rebuilt; for=_atlasOnce; proto=https
    Owned proxy
    Edge trusted; second element appended; for=198.51.100.20
    Application
    Context accepted; client=_atlasOnce; userAuth=false; resourceAuth=false

Peer not approved

  1. Initial context

    An unapproved local peer is ready to send an ordinary GET /notes message directly to the application. No edge/proxy provenance chain exists; the application has neither received the message nor decided whether to use derived context.

    Client / local peer
    Normal GET /notes ready; external context untrusted
    Owned edge
    Owned edge idle; own observations ready
    Owned proxy
    Owned proxy idle; edge gate not evaluated
    Application
    Application idle; derived context unused
  2. Normal message receipt

    A selected different local peer delivers a normal typed message to the application; field bytes are not shown and immediate-peer provenance is a separate input.

    Client / local peer
    Normal GET /notes ready; external context untrusted
    Owned edge
    Owned edge idle; own observations ready
    Owned proxy
    Owned proxy idle; edge gate not evaluated
    Application
    Message received; immediate peer unapproved-local-peer
  3. Peer gate fails

    Selected approvedPeer=false and approvedTopology=false conditions prevent use of derived context; parseability does not establish trust.

    Client / local peer
    Normal GET /notes ready; external context untrusted
    Owned edge
    Owned edge idle; own observations ready
    Owned proxy
    Owned proxy idle; edge gate not evaluated
    Application
    Context accepted=false; derived client/scheme absent
  4. Connection facts separate

    The application retains direct-peer facts separately; it manufactures no external scheme or client identity, and no resource-authorization outcome exists here.

    Client / local peer
    Normal GET /notes ready; external context untrusted
    Owned edge
    Owned edge idle; own observations ready
    Owned proxy
    Owned proxy idle; edge gate not evaluated
    Application
    Direct peer retained; userAuth=false; resourceAuth=false

ACTORS · STATE · DATA FLOW

An intermediary takes two roles in the same program

An HTTP intermediary can be a server receiving a request on one connection and a client sending a request on the next. When the Atlas browser requests GET /notes, a CDN or reverse proxy may create a new message for the application, answer from cache, or stop under normal policy. “In the middle” explains neither routing role nor TLS plaintext access by itself; draw connection and message boundaries separately.

Requests progress toward the origin (inbound) and responses toward the browser (outbound); connections may already be open and reused. RFC upstream/downstream terminology is relative to message flow, rather than the fixed direction often implied by a reverse-proxy upstream label. Do not treat every request on an upstream connection as the same human user: an intermediary can pool traffic from many clients. This lesson selects an ordinary read request. The artifact separates the direct socket peer, external resource authority, and reconstructed context.

A forward proxy is chosen by the client

A forward proxy is an intermediary chosen through the client’s configuration or policy. The client knows which origin resource it wants; the proxy mediates access to that target. Ordinary HTTP forwarding uses absolute-target information. For HTTPS, a CONNECT tunnel can carry subsequent bytes without terminating TLS; a tunnel does not imply the proxy can read the enclosed HTTP body.

The CONNECT target, origin request authority, and authentication context for the proxy itself are different. Do not equate a proxy login with origin resource authorization. No CONNECT command or network tunnel is opened here; the role table distinguishes a client-selected forwarder from an opaque encrypted tunnel. Browser and origin can remain the TLS peers, while inspection would require a different architecture.

A reverse proxy is selected on the service side

A reverse proxy acts as a gateway answering the client on behalf of an origin service. An Atlas user requests notes.example.org; service configuration chooses app.example.org upstream. Load balancing, caching, and routing may be present, but the role does not require every feature. A CDN can perform a reverse-proxy role; the CDN and proxy labels do not imply one TLS endpoint or one trust decision.

A reverse proxy can preserve public authority through an approved mapping or use a different upstream authority. Do not explain gateway behavior using exactly the same target-preservation rules as a client-selected forwarding proxy. The selected artifact preserves public notes.example.org context while the application’s direct peer is proxy.example.org. Make clear which name is used for application routing and generated links.

The word transparent does not prove plaintext access

In modern HTTP semantics, an interception proxy receives redirected network flows without being selected by the client; transparent is often used in that sense. Obsolete RFC2616 instead defined a transparent proxy by not changing messages beyond necessary proxy processing; its semantically transparent cache preserves response semantics. Those historical uses do not replace the current interception definition. State which meaning applies rather than forcing both into one definition. The interception role does not automatically mean TLS termination either.

An architecture with TLS inspection changes the browser trust context and actual terminating peer; a pass-through tunnel can preserve application TLS endpoints. This lesson only distinguishes the concepts and contains no trust-store installation or interception procedure. Its role table therefore separates “redirected without client choice” from conditional plaintext access. A role name alone cannot produce a cryptographic guarantee.

A forwarded message carries its own hop context

An intermediary need not blindly clone the received message. For HTTP/1.1 forwarding, it removes Connection and fields named by it as connection-specific before forwarding to the next hop; some protocol versions prohibit such fields altogether. Via communicates intermediary protocol information, while Forwarded is a separate extension for client-facing context parameters. Matching their positions does not establish one certain topology.

In an RFC7239 Forwarded list, the earliest participating proxy’s element is on the left, followed on the right by later participating proxies. for identifies the node requesting that proxy, by its client-facing interface, host the received Host context, and proto the incoming protocol. Some proxies may omit this optional field, so element count does not prove total network hops. IPv6 brackets and colons require quoted strings; the artifact uses only valid typed IPv4 examples and is not a general parser.

Provenance for Forwarded and X-Forwarded-*

X-Forwarded-For, X-Forwarded-Proto, and X-Forwarded-Host are common conventions, not one standard syntax or necessarily identical hop lists. Forwarded provides standardized element grouping; separate X-Forwarded-* lists cannot always be converted without loss when their insertion order is unknown. Neither format independently proves identity. An IP address or the word https inside a header does not establish an authenticated peer.

The Atlas owned edge separates incoming forwarded context as an external assertion, then reconstructs approved fields from its observed client endpoint, validated public authority, and incoming scheme. The owned reverse proxy accepts the edge channel identity and topology policy before appending its own hop element. The application uses this bounded chain as context only with an approved immediate peer and intact internal transport. Resource-user authentication and authorization remain separate.

2. Red · Trust & Impact

Read every scenario without motion

Approved chain

  1. External assertions were separated from edge observations

    GET /notes carries an untrusted external-context class without showing external bytes. The edge reconstructs approved authority notes.example.org, endpoint 192.0.2.10 and scheme https from its own observations.

    Hop context
    External assertion untrusted / edge observes context
    Provenance gate
    Review pending
    Identity boundary
    No verdict
  2. Reconstruction followed one explicit policy

    The edge discards incoming forwarded context and reconstructs it from owned observations. This policy does not erase every unknown HTTP field; Accept application/json, GET and /notes retain their meaning. Connection close is hop-specific and is not forwarded.

    Hop context
    External assertion untrusted / edge observes context
    Provenance gate
    Edge rebuild / GET-path-Accept preserved
    Identity boundary
    No verdict
  3. Header parsing was not treated as user authentication

    Normal contextAccepted can be true while userAuthenticated and resourceAuthorized stay false. Provenance controls the interpretation of client endpoint and scheme; correct context does not create a principal or object grant.

    Hop context
    External assertion untrusted / edge observes context
    Provenance gate
    Edge rebuild / GET-path-Accept preserved
    Identity boundary
    Context accepted / user=false / resource=false
  4. The second writer described its own incoming hop

    The owned proxy appends forNode 198.51.100.20 and by 203.0.113.30. Each element describes its writer’s incoming context. Selecting the first address as the real client in every topology is not a general security rule.

    Hop context
    Writers: owned-edge then owned-proxy
    Provenance gate
    Edge rebuild / GET-path-Accept preserved
    Identity boundary
    Context accepted / user=false / resource=false
  5. The trusted conjunction used explicit predicates

    Approved immediate peer, secured internal transport, approved topology and edge reconstruction are all true. Derived context may be used for this bounded chain. The Forwarded list does not prove the entire route or nonparticipating hops.

    Hop context
    Writers: owned-edge then owned-proxy
    Provenance gate
    Peer + transport + topology + rebuild = true
    Identity boundary
    Context accepted / user=false / resource=false
  6. Acceptance scope was not expanded into identity

    Derived client 192.0.2.10 and scheme https are accepted for this fixed topology. NAT or proxy context does not turn an endpoint into an account identity. Protected requests need independent principal and resource-policy evidence.

    Hop context
    Writers: owned-edge then owned-proxy
    Provenance gate
    Peer + transport + topology + rebuild = true
    Identity boundary
    Derived context accepted / authn-authz separate

Unapproved peer

  1. The same typed context came from another peer

    The unapproved-peer case supplies immediatePeer unapproved-local-peer. Method and path are ordinary, with no hostile header value. Parseable context and a trusted writer are different questions.

    Hop context
    Immediate peer unapproved-local-peer
    Provenance gate
    Review pending
    Identity boundary
    No verdict
  2. Channel success did not repair other predicates

    securedInternalTransport is true, but approvedPeer and approvedTopology are false, as is edgeReconstructed. The conjunction fails. A secured channel does not permit skipping provenance predicates.

    Hop context
    Immediate peer unapproved-local-peer
    Provenance gate
    Transport true / peer-topology-rebuild false
    Identity boundary
    No verdict
  3. Derived context was not used

    contextAccepted is false and derivedClient and derivedScheme remain null. This does not erase connection facts; it refuses untrusted derivation. Application receipt and policy acceptance are not collapsed into one field.

    Hop context
    Immediate peer unapproved-local-peer
    Provenance gate
    Transport true / peer-topology-rebuild false
    Identity boundary
    Context rejected / derived values null
  4. List syntax did not close the provenance gap

    Forwarded and X-Forwarded-* do not have one uniform syntax. Zipping independent lists by index can misassociate host, proto and node. Via and Forwarded likewise do not permit automatic same-hop matching.

    Hop context
    Syntax and list positions do not establish writer trust
    Provenance gate
    Transport true / peer-topology-rebuild false
    Identity boundary
    Context rejected / derived values null
  5. A deployment change requires reevaluating trust

    This profile uses explicit peer aliases and a fixed topology. A trusted hop count can select the wrong peer after topology changes. Control ties incoming provenance and reconstruction to observations actually owned by the system.

    Hop context
    Syntax and list positions do not establish writer trust
    Provenance gate
    Explicit peer/topology contract required
    Identity boundary
    Context rejected / derived values null
  6. The negative outcome did not attribute an attack

    This ordinary typed negative case demonstrates refusal to use derived context. No real proxy or network-trust verification runs. User and resource decisions remain false; provenance rejection does not establish actor intent.

    Hop context
    Syntax and list positions do not establish writer trust
    Provenance gate
    Explicit peer/topology contract required
    Identity boundary
    Derived context withheld / intent unknown

ASSUMPTION · BOUNDARY · CONTROL

The assumption that turns context into identity

A parseable Forwarded field does not prove correct provenance. The direct peer and the client described in the field are separate observations; NAT, proxy pooling, and privacy aliases also prevent treating them as one person. The broken assumption is using client-originated context as server-authoritative identity. This model needs no particular hostile value: a provenance class alone distinguishes the trust decision.

The selected chain requires an immediate-peer identity, approved topology, secured internal transport, and an owned reconstruction policy. If one is false, the application does not use derived external context; direct-connection facts remain separate. This is not attack or bypass evidence, but an explanation of control conditions. Establish the application principal independently rather than treating a header as authentication proof.

Hop order does not prove the whole route

Forwarded elements preserve the order of participating writers, but omit hops that do not write the field. Equating the first listed address with the actual client requires a defined first trusted observation and treatment of older untrusted prefixes. Atlas selects reset/reconstruction at the edge, so its bounded two-element provenance is explicit; this does not establish a general first-address rule for arbitrary Internet chains.

Arbitrarily zipping separate X-Forwarded-* lists can associate a host, protocol, and node incorrectly. Do not pair Via and Forwarded by index either. Explaining these risks requires no live header-mutation workflow: distinguish relationships guaranteed by the source from choices made by local policy.

The privacy and retention impact of context

A client endpoint can help diagnostics without being a user identity, and may be privacy-sensitive. Retaining a full for-address across every internal hop and log is not required merely because the chain is trusted. Atlas’s privacy branch selects a per-request obfuscated alias at the first writer and makes no IP inference. The alias is neither a stable tracking identity nor an authorization principal.

Even accepted derived context leaves business authorization false in the model. Positive topology evidence therefore does not spread to another policy domain. Answer “is the field accurate?” separately from “do we need to retain this data?” Returning the metadata in responses can expose internal topology and endpoint information.

3. Blue · Secure development & defense

Read every scenario without motion

Writer review

  1. Writer and direct peer were read together

    The inspected record is a typed ledger of the example edge/proxy operations, not a live proxy log. edgeOutbound and proxyOutbound identify each writer’s appended element; cases record the application peer-gate outcome. The privacy branch reveals _atlasOnce without allowing recovery of the omitted IP. The first writer is owned-edge with observedDirectPeer 192.0.2.10; the second is owned-proxy with direct peer 198.51.100.20. Review does not collapse listed client and immediate peer into one person.

    Writer ledger
    Two participating writers / two direct peers
    Provenance comparison
    Review pending
    Evidence scope
    No verdict
  2. Normal field relationships were compared with policy

    Edge reset/reconstruct and proxy append are the fixed-chain contract. approvedAuthority matches forwarded host notes.example.org. This does not validate arbitrary Internet chains or every intermediary.

    Writer ledger
    Two participating writers / two direct peers
    Provenance comparison
    Owned rebuild + append / approved authority matches
    Evidence scope
    No verdict
  3. A role label was not a plaintext-access guarantee

    A client-configured forward proxy may keep a CONNECT tunnel opaque. The reverse proxy can read plaintext in this selected termination profile. A role label alone is not evidence of TLS interception.

    Writer ledger
    Role selection ≠ universal plaintext access
    Provenance comparison
    Owned rebuild + append / approved authority matches
    Evidence scope
    No verdict
  4. The negative case checked the conjunction requirement

    The unapproved-peer row has transport true but other required predicates false, leaving derived values null. Normal and negative outcomes check separate control predicates, not a general header parser.

    Writer ledger
    Role selection ≠ universal plaintext access
    Provenance comparison
    Approved accepts / unapproved withholds derivation
    Evidence scope
    No verdict
  5. Missing writer evidence limited the conclusion

    If a new trace lacks writer identity or reconstruction evidence, the normal fixture’s relationship cannot be transferred. Derived-client provenance remains UNKNOWN. Header text alone cannot establish identity when its observation source is unknown.

    Writer ledger
    Role selection ≠ universal plaintext access
    Provenance comparison
    Approved accepts / unapproved withholds derivation
    Evidence scope
    UNKNOWN without writer/reconstruction coverage
  6. Regression required minimal provenance evidence

    Immediate-peer role, trusted-channel outcome, reconstruction decision and bounded correlation may suffice. Echoing the full chain or collecting session secrets is unnecessary. Actual proxy-integration claims need separate owned-runtime evidence.

    Writer ledger
    Role selection ≠ universal plaintext access
    Provenance comparison
    Approved accepts / unapproved withholds derivation
    Evidence scope
    Needed: peer/channel/rebuild/correlation scope

Privacy alias

  1. The per-request alias was separated from identity

    The inspected record is a typed ledger of the example edge/proxy operations, not a live proxy log. edgeOutbound and proxyOutbound identify each writer’s appended element; cases record the application peer-gate outcome. The privacy branch reveals _atlasOnce without allowing recovery of the omitted IP. In the privacy case derivedClient is _atlasOnce and stableUserIdentity is false. The alias preserves the provenance outcome while omitting the original IP. It is neither a stable tracking identity nor a principal.

    Writer ledger
    Derived client _atlasOnce / stable identity false
    Provenance comparison
    Review pending
    Evidence scope
    No verdict
  2. The privacy choice did not change the acceptance predicate

    Approved peer, secured transport, topology and reconstruction remain true. contextAccepted is true and derivedScheme stays https. The same trust outcome shows that IP retention is unnecessary in this selected profile.

    Writer ledger
    Derived client _atlasOnce / stable identity false
    Provenance comparison
    Context accepted / scheme https / IP omitted
    Evidence scope
    No verdict
  3. Absence of the original endpoint was not an alarm

    Per-request obfuscation is deliberate minimization. Expecting the original IP here would misclassify the ordinary privacy branch as missing-data failure. Review reads the selected retention policy together with correlation needs.

    Writer ledger
    IP deliberately absent / no stable tracking claim
    Provenance comparison
    Context accepted / scheme https / IP omitted
    Evidence scope
    No verdict
  4. Response-echo policy was checked separately

    responseEchoAllowed is false. Returning the internal chain to the reader is not a consequence of acceptance. Diagnostic records and public responses have different recipient scopes, each needing its own minimization review.

    Writer ledger
    IP deliberately absent / no stable tracking claim
    Provenance comparison
    Response echo disallowed
    Evidence scope
    No verdict
  5. The privacy outcome was not authentication or authorization

    User authenticated and resource authorized remain false in this profile. Correct alias use grants no access. Privacy and protected-request authority are different controls with different owners.

    Writer ledger
    IP deliberately absent / no stable tracking claim
    Provenance comparison
    Response echo disallowed
    Evidence scope
    Privacy preserved / authn-authz false
  6. The evidence result stayed within the selected topology

    This privacy branch reviews a fixed typed context without a real proxy, arbitrary parser or network-trust verification. Sufficiency of the same alias policy in another topology needs separate evidence.

    Writer ledger
    IP deliberately absent / no stable tracking claim
    Provenance comparison
    Response echo disallowed
    Evidence scope
    Fixed privacy contract / external topology unknown

IMPLEMENTATION · SECURITY CONTROL · VERIFICATION

One reconstruction policy at the owned edge

The inspected record is a typed ledger of the example edge/proxy operations, not a live proxy log. edgeOutbound and proxyOutbound identify each writer’s appended element; cases record the application peer-gate outcome. The privacy branch reveals _atlasOnce without allowing recovery of the omitted IP. Document the edge’s accepted public-authority mapping, observed incoming scheme, and source for the direct client endpoint. Remove incoming external context from the normal request and reconstruct approved fields from the edge’s own observations. This is not a policy of deleting all unknown HTTP fields or arbitrarily changing client message semantics. One explicit compatibility contract for Forwarded and legacy X-Forwarded-* reduces conflicting interpretations.

Record which fields internal writers preserve or append. The application must establish immediate-peer and channel provenance before using derived context. Implementation options such as trusted-hop counts are not a universal trust solution: a topology change can make the same count trust a different peer. The selected fixture uses explicit peer aliases and a fixed chain, not an arbitrary-header parser.

Regression should observe provenance decisions

Edge reconstruction, proxy append, and application context acceptance are separate local actions in the normal case. A completed message transfer updates receiver receipt state; acceptance occurs only at the later local gate. The unapproved-peer branch brings a normal typed request to the application but refuses derived context because the trust conjunction is false. Network receipt, syntax, and policy trust do not fit into one success field.

Positive evidence is the relationship among an approved peer, a secured hop, and a reconstructed first element. Negative evidence is that external scheme and client endpoint are not used without provenance. User-authenticated and resource-authorized results remain false in this fixture; evidence from another application layer is not manufactured here. This distinction also identifies what an actual integration test would need to measure separately.

Preserve forwarding compatibility and privacy

The selected inert HTTP/1.1 message uses the reserved Connection option close for the current hop. Its outbound message removes that field while preserving GET and /notes. This canonical example does not resolve every framing or field-parsing edge case; in particular it does not treat the same Connection field as valid in HTTP/2 or HTTP/3. Gateway authority mapping is separate configuration, not unlimited rewriting permission for a client-selected proxy.

Prefer an outcome category, immediate-peer role, and bounded correlation where needed over logging the full chain. The privacy branch’s per-request obfuscated for alias preserves the selected trust outcome while deliberately omitting original-IP information. Do not copy a Forwarded chain into responses. Data minimization, diagnostics, and application authorization can then remain distinct.

NOW APPLY IT TO THE CASE

Why distinguish the forwarded client, direct peer and authenticated subject?

The owned edge discards external context for /notes and reconstructs it from its endpoint and scheme observations. The owned proxy appends an element. The application evaluates both writers’ provenance predicates; the privacy branch uses _atlasOnce instead of a client endpoint.

Which cache owner supplies the case representation? Evaluate key scope, freshness and viewer context together; a hit does not establish the correct viewer.

Open the related case file ↗

READ THE EXAMPLE TOGETHER

Atlas · Proxy roles and forwarded context

Select a field and examine what it supports and where the evidence ends.

Read the raw artifact and field explanations
{
  "profile": {
    "httpVersion": "HTTP/1.1 teaching representation",
    "actualProxyNetworkRun": false,
    "arbitraryHeaderParserRun": false
  },
  "roles": [
    {
      "role": "forward-proxy",
      "selection": "client configuration",
      "tlsPlaintextAccess": "not implied; CONNECT tunnel can remain opaque"
    },
    {
      "role": "reverse-proxy",
      "selection": "service routing",
      "tlsPlaintextAccess": "yes in selected termination profile"
    },
    {
      "role": "interception-proxy",
      "selection": "network redirect without client selection",
      "tlsPlaintextAccess": "conditional architecture, not implied"
    },
    {
      "role": "semantically-transparent",
      "selection": "historical semantic usage",
      "tlsPlaintextAccess": "not a peer guarantee"
    }
  ],
  "inputMessage": {
    "method": "GET",
    "path": "/notes",
    "authority": "notes.example.org",
    "fields": {
      "Connection": "close",
      "Accept": "application/json"
    },
    "incomingExternalContextClass": "untrusted external assertion",
    "incomingExternalContextBytesIncluded": false
  },
  "edgePolicy": {
    "discardIncomingForwardedContext": true,
    "reconstructFromOwnedObservations": true,
    "approvedAuthority": "notes.example.org",
    "observedClientEndpoint": "192.0.2.10",
    "observedIncomingScheme": "https"
  },
  "edgeOutbound": {
    "method": "GET",
    "path": "/notes",
    "fields": {
      "Accept": "application/json",
      "Forwarded": "for=192.0.2.10;by=198.51.100.20;host=notes.example.org;proto=https"
    }
  },
  "forwardedElements": [
    {
      "forNode": "192.0.2.10",
      "by": "198.51.100.20",
      "host": "notes.example.org",
      "proto": "https",
      "writer": "owned-edge",
      "observedDirectPeer": "192.0.2.10"
    },
    {
      "forNode": "198.51.100.20",
      "by": "203.0.113.30",
      "host": "notes.example.org",
      "proto": "https",
      "writer": "owned-proxy",
      "observedDirectPeer": "198.51.100.20"
    }
  ],
  "proxyOutbound": {
    "fields": {
      "Accept": "application/json",
      "Forwarded": "for=192.0.2.10;by=198.51.100.20;host=notes.example.org;proto=https, for=198.51.100.20;by=203.0.113.30;host=notes.example.org;proto=https"
    }
  },
  "legacyConventions": {
    "names": [
      "X-Forwarded-For",
      "X-Forwarded-Proto",
      "X-Forwarded-Host"
    ],
    "uniformNormativeSyntax": false,
    "arbitraryListsCanAlwaysBeLosslesslyConverted": false
  },
  "privacy": {
    "perRequestForAlias": "_atlasOnce",
    "stableUserIdentity": false,
    "responseEchoAllowed": false
  },
  "cases": [
    {
      "case": "normal",
      "immediatePeer": "owned-proxy",
      "approvedPeer": true,
      "securedInternalTransport": true,
      "approvedTopology": true,
      "edgeReconstructed": true,
      "contextAccepted": true,
      "derivedClient": "192.0.2.10",
      "derivedScheme": "https",
      "userAuthenticated": false,
      "resourceAuthorized": false
    },
    {
      "case": "unapproved-peer",
      "immediatePeer": "unapproved-local-peer",
      "approvedPeer": false,
      "securedInternalTransport": true,
      "approvedTopology": false,
      "edgeReconstructed": false,
      "contextAccepted": false,
      "derivedClient": null,
      "derivedScheme": null,
      "userAuthenticated": false,
      "resourceAuthorized": false
    },
    {
      "case": "privacy",
      "immediatePeer": "owned-proxy",
      "approvedPeer": true,
      "securedInternalTransport": true,
      "approvedTopology": true,
      "edgeReconstructed": true,
      "contextAccepted": true,
      "derivedClient": "_atlasOnce",
      "derivedScheme": "https",
      "userAuthenticated": false,
      "resourceAuthorized": false
    }
  ]
}
roles
Role selection does not guarantee plaintext access.
forwardedElements
Participating writers appear left to right; each element describes its own incoming context.
cases
A conjunction of approved peer, topology, transport, and reconstruction; user permissions remain separate.

An owned fixed topology with typed normal context; no general Forwarded parser, real proxy, client-header mutation, or network trust verification. Context acceptance is not authentication or authorization.

Two reality checks

The first IP in Forwarded is an authenticated user.

The field asserts context; NAT, proxying, and provenance do not replace user authentication.

A transparent proxy reads every HTTPS body.

Interception selection, TLS termination, and an opaque tunnel have different architectural conditions.

YOUR TURN

Work through this story.

Predict the outcome, find the evidence boundary, and explain it in your own words.

The immediate peer is not approved. Is Forwarded context accepted in this profile?

  1. Yes; every writer is trusted because Forwarded is a standard header.
  2. No; derived client/scheme remain null.
Read the explained answer

No; derived client/scheme remain null. — Approved-peer/topology/edge-reconstruction gates are not established, so contextAccepted=false.

Why is forNode in the second Forwarded element not the first client IP?

Selected lesson artifact fields; teaching example

forwardedElements[0]
{"forNode":"192.0.2.10","by":"198.51.100.20","host":"notes.example.org","proto":"https","writer":"owned-edge","observedDirectPeer":"192.0.2.10"}
forwardedElements[1]
{"forNode":"198.51.100.20","by":"203.0.113.30","host":"notes.example.org","proto":"https","writer":"owned-proxy","observedDirectPeer":"198.51.100.20"}
  1. The second proxy’s direct peer is the owned edge.
  2. Every element must repeat the same original client IP.
Read the explained answer

The second proxy’s direct peer is the owned edge. — The selected hop order is the edge observation followed by the proxy observation; the field chain is interpreted using this approved topology.

Compare plaintext visibility in a forward-proxy CONNECT tunnel and reverse-proxy TLS termination.

Read the explained answer

A forward proxy may be client-selected and remain unable to read TLS plaintext inside a CONNECT tunnel. A selected reverse proxy terminating TLS is a plaintext reader. Interception placement alone also does not prove TLS decryption; accepted forwarded context is neither user authentication nor resource authorization.

□ I separated role from selected termination architecture.

□ I did not count forwarded context as user permission.

Open the application console · request / response / browser
Also open request, URL, cookie and DOM examples

Sources and scope

  • HTTP Semantics3.3 Connections, Clients, and Servers; 3.7 Intermediaries · 4.2.2 https; 4.3.4 Certificate Verification · 7.4 Rejecting Misdirected Requests · 7.6.1 Connection; 7.6.3 Via; 7.7 Message Transformations · 9.3.6 CONNECT
  • Forwarded HTTP Extension4 Forwarded HTTP Header Field · 5.1 by; 5.2 for; 5.3 host; 5.4 proto · 7.1 HTTP Lists; 7.3 Relation to Via; 7.4 Transition · 8.1 Header Validity and Integrity; 8.2 Information Leak; 8.3 Privacy
  • HTTP/1.1 — historical terminology only (obsolete)1.3 Terminology: transparent proxy and semantically transparent cache, historical only