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

# Firewalls

> Control inbound traffic to an instance with ingress rules

<Warning>
  This feature is in [public preview](/preview/roadmap).
</Warning>

A firewall is a set of rules controlling inbound traffic to an instance. Firewalls are
workspace-scoped.

## Default firewall

Every workspace has a built-in `default` firewall with two ingress rules:

* Allow SSH (TCP port 22) from anywhere
* Allow ICMP (ping) from anywhere

The `default` firewall is auto-managed: it cannot be modified or deleted.

Firewall rules control traffic between instances and the public internet. Instances in the same
subnet communicate freely on all ports. Instances in different subnets are isolated and cannot
communicate.

Firewalls only apply to instances with a public IP (created with `--public-ipv4`). When creating an
instance with a public IP, you may specify a firewall. If unspecified, the `default` firewall will
be assigned. Firewalls cannot be attached to an instance without a public IP.

Password authentication is disabled on all SFC base images, so open SSH is safe by default. Only key holders can connect.

## Creating a firewall

Create a firewall from a TOML file that defines the rules.

```bash theme={null}
sf firewall create --name web --file firewall.toml
```

### API

```json theme={null}
POST /v2/firewalls
{
  "workspace": "production",
  "name": "web",
  "rules": [
    { "direction": "ingress", "protocol": "tcp", "port": "22", "source": "0.0.0.0/0" },
    { "direction": "ingress", "protocol": "tcp", "port": "8080", "source": "0.0.0.0/0" }
  ]
}
```

### Rule format

Each rule specifies a direction, protocol, port (or port range), and source CIDR. Only `ingress`
rules are supported. The protocol is `tcp`, `udp`, or `icmp`; ICMP rules take no port.

```toml theme={null}
[[rules]]
direction = "ingress"
protocol = "tcp"
port = "22"
source = "0.0.0.0/0"

[[rules]]
direction = "ingress"
protocol = "tcp"
port = "8080"
source = "0.0.0.0/0"
```

This creates a firewall that allows SSH and port 8080 from anywhere.

Source CIDRs must be publicly routable. Private, reserved, and other non-public ranges (e.g.
`10.0.0.0/8`, `192.168.0.0/16`) are rejected; the wildcard `0.0.0.0/0` (allow from anywhere) is the
only exception.

### Restricting access

Restrict SSH to a specific network.

```toml theme={null}
[[rules]]
direction = "ingress"
protocol = "tcp"
port = "22"
source = "8.8.8.0/24"

[[rules]]
direction = "ingress"
protocol = "tcp"
port = "8080"
source = "0.0.0.0/0"
```

### Port ranges

Allow a range of ports.

```toml theme={null}
[[rules]]
direction = "ingress"
protocol = "tcp"
port = "22"
source = "0.0.0.0/0"

[[rules]]
direction = "ingress"
protocol = "tcp"
port = "8000-8999"
source = "0.0.0.0/0"
```

## Attaching a firewall to an instance

Specify the firewall when creating an instance.

```bash theme={null}
sf instance create \
  --name worker-1 \
  --image image_abc123 \
  --public-ipv4 \
  --firewall web
```

{user.groups?.includes("internal") && (
<>
Or set it on an instance template so every instance created with that template gets the same firewall.

```bash
sf instance-template create \
--name my-worker \
--image image_abc123 \
--firewall web
```
</>
)}

## Changing the firewall on an instance

Swap the attached firewall on an existing instance. The instance must have been created with
`--public-ipv4`. The new rules take effect without a reboot.

```bash theme={null}
sf instance set worker-1 --firewall restricted
```

The firewall can be replaced but not detached.

## Listing firewalls

```bash theme={null}
sf firewall list
```

```
NAME         RULES   WORKSPACE
default      2       default
web          2       default
restricted   2       default
```

## Getting firewall details

```bash theme={null}
sf firewall get web
```

Add `--toml` to output the rule set as TOML, which round-trips with `sf firewall set`:

```bash theme={null}
sf firewall get web --toml > firewall.toml
```

## Updating a firewall

Replace a firewall's rule set from a TOML file. The replacement is atomic.

```bash theme={null}
sf firewall set web --file firewall.toml
```

### API

`PUT /v2/firewalls/{id}` replaces the full rule set.

```json theme={null}
PUT /v2/firewalls/{id}
{
  "rules": [
    { "direction": "ingress", "protocol": "tcp", "port": "22", "source": "0.0.0.0/0" }
  ]
}
```

## Deleting a firewall

```bash theme={null}
sf firewall delete web
```

Deleting a firewall fails if any instances still reference it.

## Limits

* 100 rules per firewall
* 100 firewalls per workspace, including the built-in `default`
