Prima Get an API key

Primacode

The egress guard

A default-deny allowlist on outbound requests. It is not a sandbox and must not be described as one.

Live Built and working today on the surface this card describes.

What it does

The binary refuses any outbound request to a host that is not explicitly allowed, and the refusal names the host and the setting that would permit it.

The baseline allowlist is empty. What is allowed is loopback, the host of the gateway you configured, the host of a model catalogue you pointed the tool at, the host of a skills catalog when one is configured, and anything you name yourself. A named host also admits its subdomains.

It is default-deny because the alternative is documentation, and documenting "do not use those commands" is not a control. The upstream project this is forked from contacts four hosts by design, for its model catalogue, accounts, conversation sharing and a GitHub app; on a normal boot exactly two were measured, and neither is allowlisted.

It fails closed. A request whose target it cannot parse into a host is refused, not passed through, because the set of shapes fetch accepts is not fixed.

It is installed as an added file at startup rather than as a patch across call sites, so a network call introduced by a future upstream version is caught too.

Inputs and outputs

Covered The global fetch, in all three entry points, imported first in each because a module that captured fetch into a constant before the guard installed would escape it.
Not covered Node's own HTTP modules, and child processes. Plugin and extension installs go through those and are not intercepted.
On refusal An error naming the blocked host, the current allowlist, and the environment variable that would permit it.
Always allowed Loopback: localhost, 127.0.0.1, ::1 and the like. Local model servers, language servers and test fixtures live there.

Configuration

PRIMACODE_EGRESS Unset or 0 is off, which is the default. audit logs what it would refuse. 1 enforces.
PRIMACODE_ALLOWED_HOSTS Comma-separated. Hosts you are deliberately permitting.
Derived hosts The gateway host is allowed because you configured it (PRIMA_BASE_URL). The model catalogue host is allowed when you set one (OPENCODE_MODELS_URL). The skills catalog host is allowed only when a catalog is configured, and only the host you named. Nothing is derived from a default.

Limits

  • It is not a sandbox. It covers one function in one scope. A process that shells out is not covered, and neither is any library that uses Node's HTTP modules directly.
  • The package registry is deliberately not on the allowlist, because installs do not go through the guarded path. Permitting something that is never checked would be a control in name only.
  • Off by default. It is a control you turn on, and audit is the way to find out what turning it on would break.
  • Blocking the upstream model catalogue is survivable in a compiled binary, which carries a snapshot, and is not survivable on a cold cache in a development checkout, where the tool fails to start. Point OPENCODE_MODELS_URL at a mirror, or name the host.

Example

enforce it

export PRIMACODE_EGRESS=1
export PRIMACODE_ALLOWED_HOSTS=api.prima.li,git.prima.li

Source of truth

  • philosophers_stone/platform/primacode.md § The egress guard (default-deny, the three modes, the measured boot hosts, why it is not a sandbox, the Worker wiring)
  • primacode/packages/primacode/src/egress-guard.ts (the loopback set, the allowlist build, subdomain matching, the unparseable-target refusal, the refusal message, the four upstream hosts)
  • primacode/packages/opencode/src/primacode/egress.ts (the three modes, what the allowlist is made of, `OPENCODE_MODELS_URL`, the two measured boot hosts and why neither is baselined, the stated limit: `globalThis.fetch` only)