Skip to main content
Agent Safehouse is built with Bash and Sandbox Profile Language (.sb) policy modules. Contributions should maintain least-privilege security boundaries while prioritizing agent productivity and developer experience.

Project Layout

bin/ and bin/lib/

Runtime CLI and policy assembly logic (Bash)

profiles/

Authored policy modules (.sb), organized by numeric stage

tests/

Policy behavior tests and helpers

scripts/generate-dist.sh

Deterministic packaging pipeline

dist/

Generated distribution artifacts (do not edit directly)

docs/

VitePress documentation site and Cloudflare deploy tooling
Never hand-edit dist/* files. Make functional changes in bin/ and profiles/, then regenerate dist/ with ./scripts/generate-dist.sh.

Development Setup

To test your local changes (not an installed safehouse on PATH):
1

Add shell override

Add this to your ~/.zshrc or ~/.bashrc:
~/.zshrc
2

Reload shell

3

Verify override is active

You should see your function listed first, before any installed binary.

Contribution Rules

  • Do not hand-edit dist/*
  • Make functional changes in bin/ and profiles/, then regenerate dist/ when required
  • Keep policy changes least-privilege; avoid broad grants unless needed
  • Preserve stage ordering semantics (later rules win)
  • Keep each .sb module standalone for its capability

Contribution Philosophy

Agent Safehouse balances security and developer experience:
  • Follow least-privilege boundaries, but prioritize agent productivity
  • Prefer the narrowest rule that unblocks real workflows
  • If adding access to sensitive paths/integrations, document why it is needed and why narrower alternatives were insufficient
  • Avoid policy churn that improves theoretical security but breaks common agent/toolchain behavior without clear benefit

Authoring .sb Profiles

File Organization

Profiles are organized by numeric stage prefix:
Later rules win. A deny rule in stage 60 overrides an allow rule from stage 10.

Profile Header Template

Every .sb file should start with:
profiles/55-integrations-optional/docker.sb
Components:
  • Category: Profile classification (Base, System Runtime, Toolchain, Integration, Agent, App)
  • Integration/App: Human-readable name
  • Description: Brief summary of what access is granted
  • Source: Relative path to this file
  • Test ID marker (optional): #safehouse-test-id:*# for ordering tests

Dependency Metadata

Use $$require=path/to/profile.sb$$ when implicit optional integration injection is needed:
profiles/60-agents/cursor.sb
$$require=...$$ is machine-read by policy assembly. ;; Requires: comments are documentation only.

Rule Snippets

Prefer literal over subpath whenever possible. Recursive directory grants expand the attack surface.

Local Validation

1

Run policy tests

Validate behavior (macOS only, must be outside an existing sandbox):
2

Regenerate dist artifacts

Required after profile or runtime changes:
3

Verify generated output

Check that dist/ artifacts updated correctly:
If tests cannot run because your session is already sandboxed, call that out in your PR and include static validation details instead.

Required Steps by Change Type

Adding Tests

When adding new policy behavior:
1

Add test section

Create or update a file in tests/sections/:
tests/sections/20-integrations.sh
2

Use existing helpers

Leverage helpers from tests/lib/common.sh:
  • assert_allowed / assert_denied
  • assert_policy_contains / assert_policy_not_contains
  • assert_policy_order_literal
3

Validate behavior

Prefer precise tests for ordering and policy-shape regressions when changing assembly logic or module dependencies.

Pull Request Checklist

Before submitting:
  • Explain what changed and why
  • Describe security/least-privilege impact (especially for new allow rules)
  • Include test evidence (./tests/run.sh output) or state why tests were not runnable
  • Confirm whether dist/ was regenerated and committed (when required)
  • Verify CI passes on your branch

Design Guidance for Reviews

When reviewing contributions:
  • Prefer narrow path matchers (literal > subpath when possible)
  • Avoid introducing new sensitive-path exposure unless justified
  • Keep optional integrations opt-in unless required by selected profiles
  • Treat policy assembly order as a first-class behavior constraint

Reference Material

For Sandbox Profile Language examples:
  • Primary source: Authored modules under profiles/ (style/source-of-truth for this project)
  • Assembled examples: dist/profiles/safehouse.generated.sb and dist/profiles/safehouse-for-apps.generated.sb
  • macOS built-in profiles: /System/Library/Sandbox/Profiles/ and /usr/share/sandbox/
  • External prior art: Listed in README.md under Reference & Prior Art

Next Steps

Testing

Run the test suite and validate behavior

Debugging

Learn how to diagnose sandbox denials