rivet-dev / rivet-dev/agentos

Explicit permissions object replaces the secure default instead of merging over it (drops binding auto-grant)

Open
#1,960 0 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

Split out from #1884 so that #1958 (which fixes the other half of that report — network rule patterns never matching the URI-formatted resource) can close cleanly without silently closing this one.

Problem

The permissions docs state that a partial policy is merged over a secure default:

Your policy is merged over this baseline. Omitted scopes keep their default; they are not denied. So { network: "allow" } grants the network while keeping the execution essentials.

docs/content/docs/permissions.mdx:32

The implementation does a wholesale replacement instead:

// packages/core/src/agent-os.ts:3276
const hostPermissions = options?.permissions ?? {
    ...allowAll,
    binding: "allow",
};

The ?? only supplies the default when permissions is entirely absent. Any explicit object replaces it in full.

Consequences

  1. Omitted scopes are denied, not defaulted. { network: "allow" } leaves fs, childProcess, process, and env undefined. Whatever the sidecar treats as the missing-scope default applies — not the documented baseline — so the documented one-liner for "grant the network, leave everything else alone" silently removes the execution essentials.

  2. The binding auto-grant is lost. The docs say binding is auto-granted when bindings are registered. Because the binding: "allow" in the fallback lives inside the branch that only runs when no policy is passed, registering bindings alongside any explicit policy leaves binding undefined → denied.

  3. It masks unrelated bugs. Verifying #1958's fix end-to-end requires spelling out all six scopes in the repro, otherwise { network: { default: "deny", rules: [...] } } alone also denies fs/process and the failure looks like a network-policy bug. The original reporter in #1884 hit exactly this.

Reproduction

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

// Documented as: grant network, keep execution essentials.
const vm = await AgentOs.create({ permissions: { network: 'allow' } });
await vm.filesystem.writeFile('/tmp/t.js', 'console.log("hi")');
// fs/process operations do not behave as the documented baseline implies

Reported against 0.2.15 and 0.2.16-rc.1 in #1884.

Suggested fix

Merge scope-by-scope over the baseline rather than replacing:

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

…with the binding auto-grant applied whenever bindings are registered, independent of whether an explicit policy was supplied. Either that, or update permissions.mdx to document replacement semantics — but the merge behavior is the one the docs promise and the safer default, since the failure mode of replacement is silent over-denial.

Worth a test asserting that { network: "allow" } leaves fs at its documented baseline, and that registering a binding with an explicit policy still grants binding.

/cc @Scorpion197 — this is the half of #1884 your PR intentionally doesn't cover.

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 in packages/core/src/agent-os.ts around line 3276, then compare the behavior with docs/content/docs/permissions.mdx around line 32. Verify how explicit permissions are combined with the baseline and how binding registration affects the binding scope. Add coverage for an explicit network-only policy preserving the documented baseline and for bindings remaining allowed, then run the relevant core tests.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
security
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Active
Clarity
Clearly specified
Newbie friendliness
78/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.