# Internet access and IPv6

> Choose whether a machine can reach the internet, change it later, read its public IPv6 address, and know the limits and the operator's kill switch.

Every machine has an **egress policy** that decides what it can reach outside VMYard. The machine's host applies and enforces it; VMYard requests it and reports what the host applied.

| Policy | The machine can reach |
| --- | --- |
| `internet` | The public internet, within the host's limits (below). |
| `none` | Only the destinations your VMYard operator allows for every machine on the host. |

Nothing reaches a machine from outside because of its egress policy. Inbound traffic still needs an [exposed port](/docs/guides/ports) or an [SSH key](/docs/guides/ssh).

> [!NOTE]
> In the console, the create page has an **Internet access** choice (Host default, Internet, or None), and a machine's **Network** tab shows its policy and public IPv6 address and changes the policy. The CLI has `vy network` and the SDKs have `setNetwork` (`set_network` in Python); this page shows the HTTP API.

## What internet access allows

`internet` is the public internet only. Even with it:

- Private, link-local, metadata, and reserved address ranges stay unreachable, so a machine can't reach its host, your cloud's metadata service, or other machines.
- Port 25 (SMTP) is blocked. Send mail through a provider's submission port or API instead.
- Each machine has its own connection-rate and bandwidth limits, so one busy machine can't starve the others.

## Choose it when you create a machine

Add `network` to the body of `POST /v1/machines`, next to the image, plan, and region you already send:

```json
{
  "network": { "egress": "none" }
}
```

Leave `network` out and the host's default applies: `internet`, unless your operator chose `none`. The policy is part of the request: a retry with the same `Idempotency-Key` resends it, and replaying the key with a different policy answers `409 idempotency_conflict`.

`network` can't be combined with `template` (`422`). A machine created from a [template](/docs/guides/templates), like a [fork or a restore](/docs/guides/fork-and-restore), keeps its host's policy; change it afterwards.

`GET /v1/plans` lists the policies each plan offers in `network_access.egress_options`. Every plan offers both today.

## Change it later

```sh
curl -X PUT "$VMYARD_API_URL/v1/machines/$MACHINE_ID/network" \
  -H "Authorization: Bearer $VMYARD_API_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{"egress": "internet"}'
```

The machine must be running or stopped; any other state answers `422`. The change is a `network_set` [operation](/docs/concepts/operations) (`202 Accepted`, `requested_action: "network_set"`). It succeeds only when the host reports the requested policy applied, and it never starts, stops, or restarts the machine.

If the host refuses, for example because it has no guest networking or its operator turned internet access off, the operation ends `failed` and nothing changes. An uncertain change is retried with the exact same request. A failed change sends the `operation.failed` [webhook](/docs/guides/webhooks) and the opt-in `operation_failed` [email alert](/docs/guides/email-alerts); a successful one sends no event.

## Who may choose

Choosing a machine's egress is part of choosing the machine, so it needs the permission to create machines, both at create and when changing it later: Owner, Admin, and Operator members, and API keys with the `create_and_use` or `full_access` [preset](/docs/guides/api-keys). Other members see the policy but can't change it.

## Read it

`GET /v1/machines/{machine_id}` reports `network` as the machine's host last applied it:

```json
{
  "network": { "egress": "internet", "ipv6_address": "2001:db8:7a3:1::2f" }
}
```

| Field | Meaning |
| --- | --- |
| `egress` | `internet` or `none`. |
| `ipv6_address` | The machine's public IPv6 address when its host routes a global IPv6 prefix to its machines, otherwise `null`. Inbound traffic to it still reaches only exposed ports. |

`network` is `null` until a host has reported one, and stays `null` on hosts without guest networking. VMYard records the host's report after every operation it confirms on the machine, so a change made on the host (such as the kill switch below) shows up after the machine's next operation. Webhook events carry the same object as `data.machine.network`.

## The operator's kill switch

There is no organization setting for egress. The operator who runs a host can turn internet access off for the whole host. Then:

- Requests for `internet` on that host fail with nothing changed.
- Machines on it are moved to `none`, which their `network` shows after their next operation.
