# Firewall and Response

> The firewall and respond operations on whisper.agents: which layer each acts on, what holds on an owned host, and the scope each one requires.

*Source: https://www.whisper.security/docs/control-plane/operations/contain*

---
Two operations stop traffic without ending an identity. `firewall` acts on Whisper infrastructure, away from the machine. `respond` hands an action to the sensor running on it.

## Which layer reaches what

| Layer | Action | What it does |
|---|---|---|
| Network | Default-deny firewall | Flips the default for the identity's `/128` from allow to deny, so every flow not explicitly allowed stops at the edge. Reversible. |
| Network | `revoke` | Cuts the `/128` itself. Permanent, and on its own page. |
| Host | Terminate a process | The sensor ends a running process, pinned so the one it names is the one that stops. |
| Host | Quarantine a file | The sensor moves a file into quarantine and verifies it by hash. |

Network-layer actions hold on a host that is already fully owned, because they act on Whisper infrastructure rather than on the endpoint. Host-layer actions need the sensor installed and armed for response, and they travel through `respond`.

## firewall

Sets the network rules carried on one identity's `/128`. Needs `dns:firewall:write`. Flipping the default to deny is reversible: setting it back restores the flows that were allowed before.

```whisper-call
CALL whisper.agents({op: 'firewall', args: {agent: 'checkout-bot', contain: {layer: 'all', action: 'deny'}}})
```

| Argument | Contract |
|---|---|
| `agent` or `address` | Which identity. One or the other, never both omitted. |
| `rules` | The rule set to carry on the `/128`. Omit it and the call reads back the set in force. Each rule carries `action`, `match` and `value`, and `match` is `ip`, `cidr`, `host` or `port`. |
| `default` | What happens when no rule matched. `deny` is the hold. |
| `contain` | The hold: `{layer, action}`, or the action word on its own. |

`layer` is `resolver`, `egress` or `all`, and `action` is `deny` or `allow`. The two layers are one argument on one call because an endpoint that resolves DNS but holds no tunnel is still reachable by name, and an operator mid-incident should not have to know which half enforces which.

Omitting `rules` and `contain` reads the identity's current rule set back.

## respond

Dispatches a host-layer action to the sensor on the named endpoint. Needs `dns:respond:write`, which is the one scope never enrolled on a key automatically, so ask for it before you build against this operation.

```whisper-call
CALL whisper.agents({op: 'respond', args: {agent: 'checkout-bot', action: 'process.stop', params: {}}})
```

| Argument | Contract |
|---|---|
| `agent` or `address` | Which endpoint. One or the other. |
| `action` | `process.stop`, `quarantine.file`, `service.restart` or `package.update`. Omit it and the call reads the backlog back. |
| `params` | The arguments for that action. Checked against the grammar the sensor accepts, so an unknown key or an oversized value is refused rather than dispatched. |
| `id` | With `action: 'cancel'`, the command to pull back. |

Each command is queued, then dispatched, then terminal. A command still queued can be cancelled; one already dispatched cannot. Sending no `action` returns the live queue and the recent results, and an empty backlog is an ordinary answer rather than an error.

## Choosing between them

Reach for the network hold when you need traffic to stop now and you do not trust the machine. Reach for the host actions when you need a specific process or file dealt with and the sensor is reporting. [Contain an endpoint](/docs/endpoint/operate/contain) runs the job end to end, and [The response ladder](/docs/endpoint/operate/response) sets out the order to work through. When the identity is not coming back, [Revoke](/docs/control-plane/operations/revoke) is the call.

## Errors

| Code | Status | Meaning |
|---|---|---|
| `BAD_ARGS` | 400 | An argument is missing or the wrong shape. |
| `FORBIDDEN_SCOPE` | 403 | The key does not carry the write scope. See [Keys and scopes](/docs/control-plane/auth). |
| `AGENT_REVOKED` | 403 | The identity has already been cut. |
| `NOT_FOUND` | 404 | No such endpoint under this account. |
| `ACTION_LIMIT` | `429` | Too many actions in flight. Retry after the interval in `retry_after`. |
