# Verify a running app cannot reach www.google.com on Yeeted

A five-file app whose entire job is to try to leave the sandbox and **fail**.
No `network_access` section in `yeeted.yaml` - on purpose. The platform
default is no external network for a running app, and this example is the
check that the default is real, not documentation.

This is the denied half of the egress pair. Its sibling,
[egress-allowed](egress-allowed.md), proves a **build** can reach
the same site and shows how external access is declared when an app genuinely
needs it.

## What it does

- `server.py` serves `GET /egress`, which attempts
  `https://www.google.com`: a DNS resolve first, then an HTTPS fetch. The
  outcome is reported as JSON - which stage stopped it (dns, connect, or the
  10s deadline), and the error.
- On a correctly configured deployment the attempt always fails. DNS itself
  is denied on the platform, so the record usually reads: stage `dns`, a
  resolver timeout. The whole attempt is bounded to 10 seconds - Google
  answers in a second or two when a route exists, so an attempt that has not
  finished by then is a denial, not a slow site - and the record then reads:
  stage `deadline`. The bound keeps the request under the platform gateway's
  15 second response timeout, which denied DNS would otherwise run out the
  clock on (the gateway then answers 502 instead of the record).
- The one forbidden outcome is `"ok": true`. Google answering anything -
  even a 30x redirect or a 429 error page - would mean packets left the
  sandbox, which is what the smoke script fails on.

## Run locally

From `python/egress-denied`:

```sh
python3 server.py
curl -s localhost:8080/egress
```

Your laptop has internet, so `/egress` reports `"ok": true` locally. That is
correct and is exactly why the deployed smoke exists: the same code that
succeeds on your laptop must fail on the platform. **The difference between
those two results is the entire test.**

## Deploy and verify

Follow the [deployment walkthrough](getting-started.md). Deploy this
folder as-is - the manifest deliberately declares no external access.

```sh
sh smoke.sh "$PREVIEW_URL"
```

The script checks that the app is up and that the fetch attempt failed with a
recorded stage and reason. The attempt bounds itself to 10 seconds, so the
request returns promptly either way.

## Endpoints

- `GET /healthz` - `ok`
- `GET /egress` - the attempt record; must contain `"ok": false` in production

## Caveats

- This example proves the default for an app with **no** declaration. An app
  that genuinely needs an external endpoint declares it with `network_access`
  (see [egress-allowed](egress-allowed.md)); the declaration is
  recorded as an access request for Admin review and never opens traffic by
  itself.
- If the deployed smoke ever FAILS with `"ok": true`, that is not a flaky
  test - it is evidence the isolation boundary leaked, and worth reporting
  with the `/egress` record attached.
- The probe targets one well-known site for legibility. It is a reachability
  check, not a monitoring tool; the page is never parsed beyond the status.
