rivet-dev / rivet-dev/agentos

Network permission rule sets never match; explicit permission objects also bypass the documented merge-over-default

Open
#1,884 2 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Rust
Stars
4.6k
Forks
251
Avg merge
2d 15h
Merged PRs (30d)
34

Description

Problem

A network permission rule set ({ default: 'deny', rules: [...] }) never allows anything — every outbound connection fails with EACCES even when a rule explicitly allows the host, while the plain scope string 'allow' works. This makes the documented per-host egress allowlist (the recommended posture for agent VMs) unusable:

ERR TypeError: fetch failed Error: EACCES: EACCES: permission denied,
tcp://api.openai.com:443: blocked by network.http policy

Reproduced on 0.2.15 and 0.2.16-rc.1, macOS arm64, Node 25, via the Core path (AgentOs.create(), no actor layer involved).

Reproduction

Exit codes: 42 = HTTP reached (any status), 43 = blocked.

import { AgentOs } from '@rivet-dev/agentos';

const PROBE = `fetch('https://api.openai.com/v1/models')
  .then(() => process.exit(42)).catch(() => process.exit(43));`;

const CASES: [string, unknown][] = [
  ['scope-allow', 'allow'],
  ['rules-exact-host', { default: 'deny', rules: [{ mode: 'allow', patterns: ['api.openai.com'] }] }],
  ['deny-control', 'deny'],
];

for (const [name, network] of CASES) {
  const vm = await AgentOs.create({
    permissions: { fs: 'allow', childProcess: 'allow', process: 'allow', env: 'allow', binding: 'allow', network } as never,
  });
  await vm.filesystem.writeFile('/tmp/t.js', PROBE);
  const r = await vm.process.exec('node /tmp/t.js', { captureStdio: true });
  console.log(name, '→', r.exitCode);
  await vm.dispose();
}

Observed:

scope-allow        → 42   (reached)
rules-exact-host   → 43   (blocked — should be 42)
deny-control       → 43   (blocked, correct)

Also tried: patterns: ['api.openai.com:443'], patterns: ['*'], patterns: ['**'], explicit operations: ['fetch','http','dns','connect'] — all blocked identically.

Related: explicit permission objects skip the documented merge and the binding auto-grant

The permissions docs say a partial policy is "merged over a secure default" and that binding is auto-granted when bindings are registered. In agentos-core/dist/agent-os.js the actual behavior is wholesale replacement:

const hostPermissions = options?.permissions ?? { ...allowAll, binding: "allow" };

Any explicit permissions object replaces the default entirely — so { network: 'allow' } alone silently denies fs/childProcess/process/env, and registering bindings while passing any explicit policy leaves binding undefined→denied. Either the merge should be implemented as documented, or the docs should state replacement semantics.

Expected behavior

  • A matching mode: 'allow' rule permits the connection (at minimum for a bare-host pattern, per the documented patterns: ["api.example.com"] example).
  • Partial permission objects merge over the documented secure default, or the docs are corrected.
  • binding auto-grant behavior is consistent between the no-permissions and explicit-permissions paths.

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with agentos-core/dist/agent-os.js and the Core AgentOs.create() path. Run the supplied permission probe on the listed Node and macOS setup, comparing scope-allow, rules-exact-host, and deny-control. Done means matching network rules permit the connection and explicit permission policies have behavior consistent with the documented merge and binding auto-grant expectations, or the documentation clearly reflects the actual behavior.

Written by the indexing model from the issue text.

Assessment

Tech stack
node.js, typescript
Domain
networking, security
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
52/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.