> ## Documentation Index
> Fetch the complete documentation index at: https://usenaive.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Environments enforcement

> How sandbox is made impossible to escape: the two closed chokepoints — the governor (environment is an input to every verdict) and the egress gateway (no real credential injection, narrowed CONNECT allowlist) — and why a sandbox operator cannot reach production before promotion.

The [Environments primitive](/docs/getting-started/environments) is only as good as
its enforcement. A sandbox operator must be *unable* to cause a real-world
effect — not merely discouraged. That guarantee rests on **two closed
chokepoints**. Neither is in the open plumbing; both live in the enforcement
engine.

## Chokepoint 1 — the governor

`environment` is an **input to every `evaluate` call** (`PROTOCOLS.md` §1). The
governor decides, and its `Verdict` carries a `target`:

* `target: "live"` — an allowed action routes to the real provider.
* `target: "sandbox"` — an allowed action routes to the sandbox adapter instead.

For a sandbox operator, allowed guarded actions come back `target: "sandbox"`.
The **open, per-primitive sandbox adapters** honor that verdict — they are
simply *where* a `sandbox` verdict is carried out, executing the documented
sandbox behavior of each primitive and writing synthetic resources stamped
`sandbox`. Policy still runs identically; approvals still freeze. The decision is
the governor's; the adapter only obeys the target it is handed.

### Per-primitive sandbox behavior

| Primitive        | Sandbox behavior                                                                                                                                                                                                                                                      |
| :--------------- | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **email**        | On-box **catch-all**: the message lands in the local inbound store, stamped `sandbox`. Resend is never called; no credits are consumed.                                                                                                                               |
| **cards**        | **Stripe test-mode** when an `sk_test_` key is configured; otherwise a **synthetic** card — a real stamped, listable row with `last4 0000`. (With only a live key present, the test-mode leg is `BLOCKED(stripe-test-key)` and synthetic is the documented behavior.) |
| **phone**        | **Synthetic** provisioning — a `+1…5550100` number, `active_sandbox`, no carrier call.                                                                                                                                                                                |
| **formation**    | **Synthetic** — `completed_sandbox` / `filed_sandbox`, no real filing.                                                                                                                                                                                                |
| **domains**      | **Synthetic** — `registered_sandbox`, no registrar purchase.                                                                                                                                                                                                          |
| **trading**      | **Paper** — orders acknowledge (`accepted_sandbox`) but never route.                                                                                                                                                                                                  |
| **search / LLM** | **Stay real reads.** These are non-mutating information calls with no real-world side effect, so sandbox does not synthesize them — you get real results.                                                                                                             |

Other guarded primitives (verification, connections, browser, compute, mobile)
return synthetic acknowledgements the same way. None can touch a real provider,
because a `sandbox` verdict never routes to the live adapter.

## Chokepoint 2 — the egress gateway

The [egress gateway](/docs/self-hosting/security-model) is the only egress-capable
process on a Tower, and it independently enforces the operator's environment —
which it resolves from the runtime token *before* asking the governor:

* **No real credential injection for sandbox.** On a terminating provider
  endpoint, a sandbox operator gets a **synthetic** body — the gateway never
  fetches or injects the platform credential via vaultd. Injection is only ever
  applied at a named terminating provider endpoint for a *production* operator,
  never generally.
* **A narrowed CONNECT allowlist.** The governor decides the host/SNI allowlist
  **per operator + environment**, so a sandbox operator's generic web egress is
  restricted to the sandbox-permitted set; anything else is refused (and
  audited by host + verdict only).

So even if a primitive had no on-box adapter, a sandbox agent still could not
reach a live provider: the box's single door checks the environment too.

## Why production is impossible before promotion

The two chokepoints compose into a closed guarantee:

1. Every operator **starts in sandbox** (the kit's mode; the DB default is a
   fail-safe `sandbox`).
2. The governor takes `environment` on **every** verdict, so a sandbox operator
   never receives a `target: "live"` for a guarded action.
3. The open adapters can only carry out the `sandbox` target they are handed —
   they have no path to the real provider.
4. The gateway refuses real injection and narrows egress for sandbox, so the
   *transport* to a live provider is closed too.
5. Promotion flips **only** the mode; it never re-stamps sandbox residue, and
   the governor **refuses to replay** a sandbox-stamped approval in production
   (`environment_mismatch`) — the action must be re-requested.

There is no config, header, or listing filter a sandbox operator can set to make
a real-world call. Reaching production requires an explicit promotion, evaluated
by the closed engine — which is exactly the point of the primitive.

<Note>
  Both chokepoints fail closed. Stop the governor and every gated action returns
  `403 enforcement_unavailable`; the gateway treats the same condition as
  deny-all. See [Security model](/docs/self-hosting/security-model) and
  [Open core](/docs/architecture/open-core).
</Note>
