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

# Linux access support

> Supported Linux endpoint Access policy fields, actions, examples, and unsupported conditions.

Linux Device Agent route enforcement is local network enforcement for headless
hosts, developer VMs, and server-style rollouts. It is useful for proving
bounded destination controls from a Linux endpoint, but it does not have every
browser, account, product, and model fact that other Forge control points can
observe.

<Warning>
  Linux devices omit an entire route rule when a condition cannot be enforced
  exactly. They do not drop the unsupported condition and enforce a broader
  rule.
</Warning>

## Recommended Linux use cases

Use these cases when you need a reliable Linux proof point:

| Scenario | Conditions | Action | Test command |
| - | - | - | - |
| Block an AI API domain | `destination.domain eq api.deepseek.com` | `block` | `curl -I --connect-timeout 8 https://api.deepseek.com` |
| Block an exact IP and port | `destination.ip eq <ip>` and `destination.port eq 443` and `destination.protocol eq tcp` | `block` | `nc -vz <ip> 443` |
| Block one process to one destination | `destination.domain eq api.openai.com` and `process.name eq python3` | `block` | Python HTTPS request to `api.openai.com` |
| Review without blocking | `destination.domain eq example.com` | `flag_for_review` | `curl -I --connect-timeout 8 https://example.com` |
| Approval or fail-closed hold | `destination.domain eq api.anthropic.com` | `require_approval` | `curl -I --connect-timeout 8 https://api.anthropic.com` |

## Supported local route selectors

Linux local enforcement supports route rules that can be represented as bounded
network facts:

| Selector | Linux behavior |
| - | - |
| `destination.domain` | Supported. The agent resolves the domain into bounded local route rules. |
| `destination.ip` | Supported for exact IP values. |
| `destination.port` | Supported for exact ports using `eq` or `in`. |
| `destination.protocol` | Supported for TCP or UDP. |
| `process.name` | Supported as a narrowing condition when paired with a route anchor such as domain, IP, or exact port. |
| `identity.user_id` and `identity.group_ids` | Supported only when the Linux endpoint has resolved identity context. Missing identity does not widen the policy to everyone. |
| `device.id` | Supported for device scoping. Prefer the policy scope picker for device-specific validation. |

Endpoint-route policies must include an executable route anchor. Use an AI
product, provider, destination domain, destination IP, or exact destination port
so Forge can emit a route rule. For Linux endpoint validation, prefer explicit
`destination.domain`, `destination.ip`, or exact `destination.port` conditions
because they produce the clearest local evidence.

## AI product and provider targeting

`product.id` and `provider.id` are valid Access policy fields. On endpoint
routes, Forge can lower them only when the selected catalog target has active
host or API identifiers, or when the policy also includes a concrete
destination. If no endpoint route identifiers are available, Forge records a
coverage-gap diagnostic and emits no endpoint rule.

For a Linux proof, avoid a product-only policy unless the generated endpoint
artifact shows a concrete rule in `ruleSummaries`. A stronger policy example is:

```json theme={"system"}
{
  "all": [
    {
      "field": "product.id",
      "op": "eq",
      "value": "openai/chatgpt"
    },
    {
      "field": "destination.domain",
      "op": "eq",
      "value": "chatgpt.com"
    }
  ]
}
```

That keeps the product story visible while giving Linux a concrete destination
to enforce.

## Unsupported Linux local conditions

The following fields are not reliable Linux local route selectors. Depending on
the full policy, Forge rejects endpoint-route activation or omits the Linux
local route rule instead of broadening it:

| Unsupported field group | Fields |
| - | - |
| AI classification | `classification.state` |
| Process identity beyond name | `process.id`, `process.entrypoint_id` |
| Process facts not used by Linux local routing | `process.path`, `process.local_port` |
| Browser extension | `browser.extension_id`, `browser.extension_identity_id`, `browser.extension_surface` |
| Browser account | `browser.account_id`, `browser.account_domain`, `browser.account_state`, `browser.account_truth_state` |
| Route posture | `route.posture` |
| Account posture and profiles | `account.posture`, `account.access_state`, `account.profile_id` |
| Control path | `control.path_kind` |
| Source capability and health | `source.family`, `source.capability`, `source.health_state` |
| Local model evidence | `local_model.governance_state`, `local_model.proof_level`, `local_model.name` |
| Platform condition | `device.platform` |

Do not use browser account, browser extension, local model, source health, or
classification-state scenarios as the primary Linux endpoint proof. Use a
macOS, Windows, browser, gateway, provider, or inline source that can observe
and enforce those facts.

## Unsupported condition shapes

Linux follows the endpoint-route projection rules. These policies are rejected
or omitted rather than broadened:

| Shape | Result |
| - | - |
| Negated Access conditions | Not executable on endpoint route. |
| Stateful Content-style history such as event counts or sequences | Not executable for Access endpoint routes. |
| Rego Access logic on endpoint route | Not lowered into Linux route rules. |
| Numeric ranges such as `destination.port gte 443` | Not exact enough for endpoint route; use `eq` or `in`. |
| `process.name` with no route anchor | Rejected because it would block a process broadly without a destination or port boundary. |
| Expiring endpoint-route exceptions | Not lowered because the local route rule must preserve the exact exception semantics. |
| Content-only actions on Access policies | `redact`, `filter`, and `nudge` are Content actions, not Access actions. |

## Action behavior on Linux

| Action | Linux route behavior |
| - | - |
| `allow` | Records the match. It does not override a stronger matching block or approval policy. |
| `flag_for_review` | Allows traffic and records workflow evidence for review. |
| `require_approval` | Uses an online decision or fail-closed behavior when the route-control artifact requires it. The exact behavior depends on the connected path's hold capability. |
| `block` | Blocks locally when the rule is representable. |

When multiple matching policies apply, the strongest action wins: `block`,
then `require_approval`, then review or allow.

## Inspect the delivered Linux artifact

After saving a policy and waiting for the device to refresh, inspect the local
configuration:

```bash theme={"system"}
sudo jq '{
  endpointControlEnabled: .endpointControl.enabled,
  deploymentMode: .endpointControl.bridge.deploymentMode,
  routeDiagnostics: (.endpointControl.routeControlArtifact.ruleDiagnostics // []),
  ruleSummaries: (.endpointControl.routeControlArtifact.ruleSummaries // [])
}' /var/lib/forge/sensor/config.json
```

`ruleSummaries` shows route rules Linux can enforce locally.
`routeDiagnostics` explains omitted rules and coverage gaps.

Useful runtime evidence:

```bash theme={"system"}
journalctl -u forge-device-agent -f
tail -f ~/.forge/linux-ebpf/flows.jsonl
sudo /opt/forge/sensor/forge-sensor --state-dir /var/lib/forge/sensor run-linux-ebpf-collector --duration-seconds 10
```

## Linux test examples

### Domain block

Create an **Access policy** with `destination.domain eq example.com`, action
`block`, and endpoint-route enforcement. Then run:

```bash theme={"system"}
curl -I --connect-timeout 8 https://example.com
```

Expected: HTTPS traffic to `example.com` is blocked. Domain-only Linux route
blocks default to TCP `443`.

### Exact IP block

Create an **Access policy** with these conditions:

```json theme={"system"}
{
  "all": [
    {
      "field": "destination.ip",
      "op": "eq",
      "value": "1.1.1.1"
    },
    {
      "field": "destination.port",
      "op": "eq",
      "value": 443
    },
    {
      "field": "destination.protocol",
      "op": "eq",
      "value": "tcp"
    }
  ]
}
```

Then run:

```bash theme={"system"}
nc -vz 1.1.1.1 443
```

Expected: TCP traffic to `1.1.1.1:443` is blocked. Other ports are outside this
policy unless another rule matches them.

### Process-narrowed block

Create an **Access policy** with `destination.domain eq api.openai.com` and
`process.name in ["python", "python3"]`, action `block`, and endpoint-route
enforcement. Then run:

```bash theme={"system"}
python3 - <<'PY'
import urllib.request
urllib.request.urlopen("https://api.openai.com", timeout=8)
PY
curl -I --connect-timeout 8 https://api.openai.com
```

Expected: the Python request is blocked. The curl request is allowed unless
another policy blocks the same destination.

### Unsupported browser account condition

Create an **Access policy** with `destination.domain eq chatgpt.com` and
`browser.account_state eq personal_account`, action `block`, and endpoint-route
enforcement. Then run:

```bash theme={"system"}
curl -I --connect-timeout 8 https://chatgpt.com
```

Expected on Linux: no local generic `chatgpt.com` block is emitted. Inspect
`routeDiagnostics` for the unsupported browser-account field. Test this policy
with a browser or account-aware source instead.

## Content policies on Linux

Content policies are not Linux route rules. They run where the agent, gateway,
MCP, or model surface provides the prompt, tool, result, response, or
classification checkpoint. Linux coding-agent workflows can still be good
Content policy use cases when the governed agent integration emits those
checkpoints.

Use these Linux-safe Content policy use cases:

| Scenario | Content checkpoint | Condition | Expected result |
| - | - | - | - |
| Prompt secret redaction | `prompt` | `request.prompt matches <secret-pattern>` | Secret-shaped text is transformed before the model step. |
| Production command approval | `pre_tool` | `tool.input.command contains production` | Tool call waits for approval before execution. |
| Tool result block | `post_tool` | `tool.result contains <test-token>` | Tool executes, then result is blocked before reuse. |
| Response block | `response` | `response.content contains <test-token>` | Final response is blocked when the surface supports response inspection. |

If a Content policy does not fire on Linux, check whether the tested agent path
emits the selected checkpoint. Do not diagnose it as a Linux eBPF route issue.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.