> For the complete documentation index, see [llms.txt](https://docs.nebulablock.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.nebulablock.com/api-reference/platform-api/list-products/firewall-rules.md).

# Firewall Rules

List, add, and delete per-instance firewall rules on a Nebula Block GPU or CPU instance.

Each instance has its own set of firewall rules controlling which traffic reaches it. Rules are managed per instance, addressed by the instance's UUID.

> **Note:** On all three endpoints an unknown instance id is rejected with **HTTP 404** `Instance not found`, and an instance belonging to someone else with **HTTP 403** `Permission denied`. Those are the only real HTTP errors here — everything else below comes back as HTTP 200, and the status field is what distinguishes the cases.

> **Important:** **Not every instance supports firewall rules** — it depends on the instance's configuration. Check `firewall_supported` on [Get Instance](/api-reference/platform-api/list-products/get-instance.md), or the `supported` flag that the list endpoint below returns, before building on these endpoints.

## List firewall rules

### HTTP Request

`GET` `{API_URL}/computing/instance/{instance_uuid}/firewall-rules`

where `API_URL = https://api.nebulablock.com/api/v1`.

### Response Attributes

#### data `dict`

* **supported** `boolean`: Whether firewall rules are available on this instance.
* **rules** `list`: The instance's current rules. Always empty when `supported` is `false`.

#### status `string`

`success` or `failed`.

#### message `string`

A description of the result.

> **Important:** When firewall rules are not supported, this endpoint still returns **HTTP 200 with `"status": "success"`** and `data: {"supported": false, "rules": []}`. That is indistinguishable from a supported instance with no rules if you only look at `status` — **read `supported`**.

### Example

```bash
curl -X GET '{API_URL}/computing/instance/{instance_uuid}/firewall-rules' \
-H 'Authorization: Bearer {TOKEN}'
```

## Add a firewall rule

### HTTP Request

`POST` `{API_URL}/computing/instance/{instance_uuid}/firewall-rules`

### Body Parameters

| Parameter          | Requirement | Type      | Description                                               |
| ------------------ | ----------- | --------- | --------------------------------------------------------- |
| `direction`        | Required    | `string`  | `inbound` or `outbound`                                   |
| `protocol`         | Required    | `string`  | `tcp`, `udp`, `icmp`, or `any`                            |
| `ethertype`        | Optional    | `string`  | `IPv4` or `IPv6`. Defaults to `IPv4`                      |
| `remote_ip_prefix` | Optional    | `string`  | The CIDR the rule applies to. Defaults to `0.0.0.0/0`     |
| `port_range_min`   | Conditional | `integer` | Start of the port range. **Required for `tcp` and `udp`** |
| `port_range_max`   | Conditional | `integer` | End of the port range. **Required for `tcp` and `udp`**   |
| `description`      | Optional    | `string`  | A note describing what the rule is for                    |

Validation to be aware of, since these are rejected before the rule is created:

* `remote_ip_prefix` must be a valid CIDR, and its IP version must match `ethertype` — an IPv6 CIDR with `ethertype: IPv4` is refused.
* `port_range_min` and `port_range_max` are mandatory for `tcp` and `udp` rules, must be supplied together, must each fall within `1`–`65535`, and `port_range_min` cannot exceed `port_range_max`.

> **Important:** The instance must be `Running` or `Stopped`. Adding a rule to an instance in any other state — while it is still deploying, for instance — returns **HTTP 200 with `"status": "failed"`** and `"Instance status is invalid for firewall operations"`, so the rule is silently not applied.

> **Note:** On an instance where firewall rules are not available, this returns **HTTP 200 with `"status": "failed"`** and `"Firewall rules are not supported for this instance"`. The same applies to deleting a rule.

### Example

```bash
curl -X POST '{API_URL}/computing/instance/{instance_uuid}/firewall-rules' \
-H 'Authorization: Bearer {TOKEN}' \
-H 'Content-Type: application/json' \
-d '{
    "direction": "inbound",
    "protocol": "tcp",
    "ethertype": "IPv4",
    "remote_ip_prefix": "203.0.113.0/24",
    "port_range_min": 22,
    "port_range_max": 22,
    "description": "SSH from the office"
}'
```

> **Important:** Instances default to being reachable from anywhere on the ports their image opens. Narrow `remote_ip_prefix` to the addresses you actually connect from rather than leaving `0.0.0.0/0`.

## Delete a firewall rule

### HTTP Request

`DELETE` `{API_URL}/computing/instance/{instance_uuid}/firewall-rules/{rule_id}`

### Example

```bash
curl -X DELETE '{API_URL}/computing/instance/{instance_uuid}/firewall-rules/{rule_id}' \
-H 'Authorization: Bearer {TOKEN}'
```

## See also

* [Get Instance](/api-reference/platform-api/list-products/get-instance.md)
* [GPU Cloud](/products/gpu-cloud.md)
