<!-- Generated from product/firewall.html at build time. Do not edit. -->

> Canonical: https://antifailure.dev/product/firewall

> Fail-closed egress with a per-host decision: block, allow, sandbox, capture, mock, or synth.

# The twin cannot act on the real world.

No default public egress. Clone-local DNS. A stateful Stripe that answers offline, mail rendered and captured rather than sent. Unknown destinations are denied and written to the attempted-effect ledger.

Side-effect containment architecture: application requests pass through clone-local resolution and a mandatory gateway before being simulated, captured, or blocked, with each gateway decision written to the attempted-effect ledger.

## Every outbound attempt is recorded, including the denials. Six per-host modes, from refusing outright to answering from an offline pack. Never a live processor.

Attempted-effect ledger containing six gateway decisions: four safely handled by mock or capture modes, two blocked, and zero requests escaping the twin.

- stripe.pack.local MOCK FIG. P-FW-02 stateful offline pack Stripe charge lifecycle contained request POST /v1/charges amount 4900; usd; cus_sim_11 -> mock response 200 OK; ch_sim_08f2 status succeeded; livemode false + Clone-local state transition persisted cus_sim_11; charge.created; api.stripe.com never resolved A Stripe charge request is answered by the stateful clone-local pack, which returns a simulated charge and records the state transition without contacting Stripe.

- capture inbox CAPTURE FIG. P-FW-03 searchable artifact Rendered, not delivered 202 shape Order #4182 msg_sim_2a91; multipart/alternative not sent from checkout@twin.local to customer@example.test subject Your order #4182 plain html POST /v3/mail/send returns provider-shaped 202; no delivery attempted. A SendGrid API call is terminated inside the twin and rendered as a captured MIME message that can be inspected, but is never delivered.

- policy trace BLOCK FIG. P-FW-04 unknown destination CONNECT example.com:443 refused 01 Resolve host example.com

- 02 Match explicit rule none

- 03 Apply default BLOCK

- 04 Write decision deny_02

An unlisted connection to example.com is evaluated by the gateway, matches no explicit rule, inherits the BLOCK default, and receives a denial receipt in the decision log.

Illustrative Six rows chosen to show mocked calls, captured messages and denials. The hosts, the modes and the decision log are real: af net log prints every request the gateway decided, allowed as well as refused, and af ci summarises them on the pull request. A packet that never reaches the gateway, such as a connection straight to a public address, leaves no row: it fails at the network instead, which is stronger and is the section below. A denied destination is denied inside the twin; it does not on its own fail the check.

## Containment is not a rule you can edit. A direct-IP attempt does not get out.

Clone-local DNS is not enough if the twin dials an address. The gateway matches domain, IP, protocol, method, and operation. Unknown destinations, unresolved secrets, or missing isolation block the run. Convenience does not silently override containment.

- No default egress There is no default public internet route from the twin.

- Clone-local DNS Production hostnames do not resolve to production.

- Mandatory gateway Domain, IP, protocol, method, and operation policies at the edge.

- A stateful Stripe One built-in pack answers the Stripe API from a clone-local ledger. Other mocked hosts answer without keeping state.

Comparison of a hostname request routed through clone-local DNS and the mandatory gateway with a direct-IP request stopped by the network namespace because no public default route exists. The direct-IP failure returns ENETUNREACH and creates no gateway ledger row.

## Charging a live processor is an existential failure. Not a warning. Not a retry.

- Isolated Twin Where containment is applied. Read

- Load Traffic sent at the contained twin. Read

- Egress docs Controls and example behavior. Read

## Know what happens before you deploy.

Create a disposable production twin for every risky change. Catch migration failures before they reach customers.
