# Network access approvals

Source: https://codeherder.com/docs/egress-approvals/

How a session asks for a blocked network destination, who can answer, what each answer allows, and how to revoke it.

When a session needs a network destination that its policy blocks, it can ask a person. This page explains what you see, what each answer does, and how to manage the answers later.

A network request is not a question. It has no free-text answer. You approve one exact destination, or you deny it.

## Which sessions this applies to

Approvals apply only to sessions whose network is enforced. An enforced session runs in a container, and its stage connects through its own proxy. See [Isolating agent runs on a device](https://codeherder.com/docs/agent-isolation/).

A session that runs without that proxy is not enforced. Its **Network access** panel says “This session’s network is not enforced. Approvals here do not limit what it can reach.” A request for such a session is refused.

## Where requests appear

- **Dashboard.** The “Egress approvals” panel lists pending requests. The attention badge in the sidebar counts them together with open questions.
- **My work.** The “Egress approvals” section lists pending requests in the current workspace. See [My work](https://codeherder.com/docs/my-work/).
- **Session page.** The **Network access** panel shows the policy of that session. A separate “Egress requests” panel lists its requests. A task-free session has both panels.
- **Task page.** The “Egress requests” panel keeps the history after the session ends.

The Dashboard and My work group requests for the same host, port and transport. Each session keeps its own request and its own buttons. One answer never reaches another session.

## What a request shows

- The exact host, the port and the transport. The transport is “HTTPS tunnel (CONNECT)” or “HTTP”. A request never holds a URL.
- **Requested by**, **Session**, **Task** and **Device**. A request with no task or device shows a dash.
- **Blocked because.** The reason the destination was blocked.
- **Origin.** “Raised by the proxy” or “Asked by the agent”.
- **Reason given by the agent (unverified).** The agent wrote this text. Treat it with care.
- **Seen.** How often the proxy saw the connection, and when it last did.
- **Expires.** Shown on a pending request. A request that nobody decides within 24 hours expires. You cannot decide an expired request.

A request has one status: Pending, Denied, “Allowed for this session”, “Allowed in this workspace” or Expired.

A target is exact: one host, one port and one transport. A rule for `github.com` does not cover `api.github.com`. A target never uses a wildcard, an IP address or a URL.

Only two reasons can be approved: “Host not on the allow list” and “Port not approved”. Other reasons cannot be approved. Examples are “Always blocked”, “Reserved address”, “Blocked by the operator”, “Restricted by session purpose” and “Blocked by a workspace rule”. The buttons then explain: “A protected rule blocks this target. No approval can lift it.”

## The three answers

Only a human workspace admin or owner can answer. An agent can never answer, and a session credential cannot either.

- **Deny.** The destination stays blocked. The same session cannot file an automatic request for that exact target for 24 hours.
- **Allow for this session.** The destination opens for this one session. A package manager can open many connections, and all of them are allowed. The access ends when the session ends, when you revoke it, or after 12 hours.
- **Always allow in this workspace.** CodeHerder saves an exact rule. Current and later sessions in this workspace can reach this destination until you revoke the rule. This answer asks you to confirm first. If the session has ended, the dialog says that the rule applies to later sessions only.

If the session has ended, **Allow for this session** is disabled. The reason reads “The session has ended. Allow this target for the workspace instead.”

If you cannot decide, a request card says “Ask an admin to decide” and names who can.

## After you decide

CodeHerder saves your decision first. The session’s proxy applies it a moment later. The request shows one state:

- **Applying.** “Saved. Waiting for the session’s proxy to apply it.”
- **Applied.** The proxy applied the decision. The destination is open.
- **Device offline.** “Saved. The device is offline. Added access stays closed until it reconnects.” Deny rules stay in force.
- **Not supported** or **Failed.** The proxy cannot apply the decision. The request shows the reason.
- **Session ended.** “Saved for later sessions. The requesting session has ended.”

After the proxy applies an allow, CodeHerder tells the session to retry. It never replays the connection for the session. A session that muted this notice gets no advice and must retry on its own.

## Workspace rules, allowances and settings

Open **Settings**, then **Network access**. The sections appear in this order:

- **Automatic requests.** When on, a blocked connection files a request by itself. This is the default. When off, enforcement does not change, and agents can still ask on purpose. Automatic requests also need a device that reports blocked connections. Otherwise the session shows “The device needs an update to report blocked connections.”
- **Policy status.** How far the saved policy has reached the sessions running now.
- **Inherited policy.** The read-only defaults every session starts with.
- **Workspace rules.** Exact targets saved for every session. Choose **Add rule** and fill in Host, Port, Transport and Effect. Choose Allow or Deny. A deny rule beats an allow rule and an open network. A rule with the opposite effect of an active rule for the same target conflicts. To remove a rule, choose **Revoke**. Turn on **Show revoked** to see revoked rules as history.
- **Session allowances.** Allowances for one session. Revoke one to end it at once.
- **Requests.** Every request stays visible after the session ends. Use **Request status** to narrow the list.

A person who is not an admin sees a read-only view. It says “Read-only view. Changing network access requires a workspace owner or admin.”

## Limits

Each session can file 5 new requests a minute. It can hold 20 pending automatic requests. Past a limit, the app shows “Some blocked connections were not filed”. The destination can ask again after the limit passes.

## From the command line

Triage pending requests, then decide:

```
ch egress list --status pending
ch egress show <requestId>
ch egress approve <requestId> --scope session
ch egress deny <requestId>
```

`ch egress approve` has no default scope. Choose `session` or `workspace`. Add `--yes` when you do not run it at a terminal.

An agent or a person can file a request. A person names the session:

```
ch egress request registry.npmjs.org:443 --reason "install the lockfile deps"
ch egress request example.com:80 --transport http --session <sessionId>
```

The reason holds 500 characters at most. A URL is refused.

Read policy, rules and allowances, and manage them:

```
ch egress policy <sessionId>
ch egress rules list --all
ch egress rules create blocked.example:443 --effect deny --yes
ch egress rules revoke <ruleId> --yes
ch egress grants list --session <sessionId>
ch egress grants revoke <grantId> --yes
ch egress settings show
ch egress settings edit --auto-request off
```

See [Using the CLI](https://codeherder.com/docs/using-the-cli/) for sign-in and output options.

## Related

- [My work](https://codeherder.com/docs/my-work/)
- [Isolating agent runs on a device](https://codeherder.com/docs/agent-isolation/)
- [Approvals](https://codeherder.com/docs/approvals/)
