Model or dataset
eugene1g/agent-safehouse avatar
eugene1g/agent-safehouse

Agent Safehouse: a deny-first macOS sandbox for coding agents

Sandbox your local AI agents so they can read/write only what they need

2,086 stars98 forksShellApache-2.0

At a glance

What is it?
Agent Safehouse wraps LLM coding agents in macOS sandbox-exec profiles so they can only touch the files and integrations you allow. It is a hardening layer for Mac developers, not a security boundary.
Who is it for?
Adopt Agent Safehouse if you run coding agents on macOS and want a deny-first default that still lets normal development work, especially if you already use --dangerously-skip-permissions style flags. Skip it if you are on Linux or Windows, since it depends on macOS sandbox-exec, and skip it if you need a boundary that holds against a determined attacker rather than a hardening layer.
Can I use it commercially?
Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository received new commits within the last day.
What is it written in?
Mainly Shell, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 30, 2026, and from our analysis. They are not legal advice.

Editorial analysis

The problem: agents with broad filesystem access on your Mac

A coding agent running with permission prompts disabled can read and write anything your user account can. That includes SSH keys, cloud credentials, browser profiles, and every unrelated repository on the machine. The practical question is not whether an agent will do something malicious, but how much damage a wrong command or a prompt-injected instruction can do before you notice.

Agent Safehouse targets that gap on macOS specifically. Its stated philosophy is practical least privilege: start from deny-all, allow only what the agent needs to do useful work, and keep developer workflows productive. The README is explicit that this is a hardening layer, not a perfect security boundary against a determined attacker. That framing matters. You are reducing blast radius, not building an airlock.

The intended audience is developers who already run agents like Claude Code, Codex, or Amp locally and want the convenience of skipped permission prompts without handing over the whole home directory.

How the sandbox-exec profiles and deny-first policy work

The mechanism is macOS sandbox-exec driven by composable policy profiles written in the Scheme-like sandbox profile language. Policies are assembled at render time from built-in modules in profiles/ plus anything you append. The model is deny-first: nothing is readable or writable unless a rule grants it.

Two variables drive the rendering. HOME_DIR is used to produce precise home-relative rules; the README states that by itself it does not grant recursive read access to your home directory. WORK_DIR exposes the selected workdir to rules through workdir-literal, workdir-subpath, and workdir-prefix. Those helper arguments begin with a slash, which is what lets a reusable profile target something like <workdir>/.env without hardcoding an absolute project path.

The default behavior is narrower than people assume. There is metadata-only traversal on /, the path to $HOME, and $HOME itself, so runtimes can probe allowed home-scoped paths. Directory-root reads are granted for ~/.config and ~/.cache so tools can find XDG locations. A few explicit home-scoped files and directories come from always-on profiles, such as git and ssh metadata and shared agent instruction folders. The README's own illustration: stat "$HOME" can succeed while ls "$HOME" and cat ~/secret.txt still fail unless a more specific rule grants the path.

There is a second mechanism worth knowing about. Built-in profiles may reference macOS compatibility paths such as /etc, /private/etc/resolv.conf, or /private/etc/localtime. At render time, Safehouse resolves built-in absolute paths from allow file-read* rules and emits matching grants for the real target when the authored path is a symlink. The scope is deliberately limited: built-in absolute literal and subpath read grants only. User-provided path grants normalize separately, and writable or metadata-only built-in rules are not auto-expanded by this today. That last sentence is a limitation, not a feature list.

Installing Agent Safehouse and running an agent under it

Two install paths are documented. Homebrew is the shorter one:

bash
brew install eugene1g/safehouse/agent-safehouse

If you prefer not to use a tap, the README gives a standalone script install that downloads the release artifact to ~/.local/bin and marks it executable:

bash
mkdir -p ~/.local/bin
curl -fsSL https://github.com/eugene1g/agent-safehouse/releases/latest/download/safehouse.sh \
  -o ~/.local/bin/safehouse
chmod +x ~/.local/bin/safehouse

After installing, the documented usage pattern is a shell wrapper rather than a long command line. The README's POSIX example exports a profile path and defines a safe function that adds a read-only directory and the appended profile before passing through your arguments:

bash
# ~/.zshrc or ~/.bashrc
export SAFEHOUSE_APPEND_PROFILE="$HOME/.config/agent-safehouse/local-overrides.sb"

safe() {
  safehouse \
    --add-dirs-ro="$HOME/server" \
    --append-profile="$SAFEHOUSE_APPEND_PROFILE" \
    "$@"
}

safe-claude() { safe claude --dangerously-skip-permissions "$@" }

The fish equivalent uses set -gx and $argv instead. Once the wrapper is in place, safe-claude runs Claude Code with permission prompts skipped, but with the sandbox policy applied. That is the whole point of the tool: the risky flag becomes tolerable because the filesystem surface is constrained.

Machine-local exceptions go in the appended profile. The README's example file grants a few host-specific paths and then closes a hole with a deny:

scheme
;; ~/.config/agent-safehouse/local-overrides.sb
(allow file-read*
  (home-literal "/.gitignore_global")
  (home-subpath "/Library/Application Support/CleanShot/media")
  (subpath "/Volumes/Shared/Engineering")
)

;; Keep root environment files unavailable even though the workdir is writable.
(deny file-read* file-write* (workdir-literal "/.env"))

Appended profiles load last, so their deny rules can narrow earlier defaults. That ordering is the documented way to remove even the default home exceptions. The README's guidance is to use --add-dirs-ro or --add-dirs for ordinary shared-folder access and reserve --append-profile for machine-local policy exceptions and final overrides.

Worktree detection and where the snapshot stops

Git worktrees get special handling. When the selected workdir is itself a Git worktree root, Safehouse auto-detects it at launch. That worktree receives the shared Git metadata access it needs when its common dir lives outside the selected workdir, and the other existing linked worktrees for the same repo become readable by default for cross-tree inspection.

The catch is stated plainly in the README: that snapshot does not update for already-running processes. If you create worktrees under a stable parent such as ~/worktrees, the documented recommendation is to add that root explicitly with --add-dirs-ro rather than relying on detection. This is a good example of the project's general posture: defaults are narrow, and the escape hatches are explicit flags you are expected to understand.

Limitations and cases where this is the wrong tool

The most important limitation is the one the project states about itself. Agent Safehouse is a hardening layer, not a perfect security boundary against a determined attacker. If your threat model includes a motivated adversary with code execution inside the sandbox, this is not the control you are looking for.

Platform lock-in is the second constraint. The tool is built on macOS sandbox-exec, and the README's own Linux section exists because the mechanism does not carry over. If your team runs agents on Linux CI runners, Safehouse does nothing for those jobs.

The system path resolution mechanism has a narrow scope, and the README says so: it covers built-in absolute literal and subpath read grants only. Writable or metadata-only built-in rules are not auto-expanded by it today, and user-provided path grants normalize through a separate path. If you author your own profiles and expect symlink resolution to behave the same way for your grants as it does for the built-ins, you will be surprised.

Finally, the default home exceptions are a real trade-off. Metadata-only traversal plus directory-root reads for ~/.config and ~/.cache are what make tools work without constant profile edits, but they are still grants. The README tells you how to remove them with --append-profile. Whether you should depends on how much friction you will tolerate when a cache lookup fails.

Alternatives on Linux and how they differ

The README lists several Linux-native options, and the differences are architectural rather than cosmetic. vetto is described as a zero-daemon kernel sandbox using Landlock LSM and seccomp-bpf on Linux, with Seatbelt on macOS, plus automated PATH shims via vetto's enable command. bubblewrap is the unprivileged user namespaces utility that many container and desktop tools already build on. firejail is a mature SUID sandbox with ready-made application profiles. nono.sh combines Landlock with seccomp-notify and supports privilege elevation without a restart. sandlock is pure Python, combining Landlock, seccomp-bpf and seccomp user notification, with no root, containers, or C compiler required.

The practical distinction: those tools hook into Linux kernel primitives that do not exist on macOS, while Safehouse is a wrapper around the macOS-specific sandbox-exec profile language. If you are choosing for a mixed fleet, you are choosing two different sandboxes, not one tool with two backends. The README does not claim otherwise.

Licence, maintenance, and upgrade cost

The project is Apache-2.0, both in the repository LICENSE and in the package.json metadata. That is a permissive licence with an explicit patent grant, and it is compatible with commercial use. Nothing here is legal advice; read the licence text if your organisation has specific requirements around patent clauses or attribution.

The repository is not archived, and the last push was on 2026-09-09, with v0.12.0 released on 2026-09-07. Releases have been arriving at a steady cadence: v0.11.0 on 2026-07-08, v0.11.1 on 2026-07-17, v0.12.0 on 2026-09-07. That is recent enough that pinning to a specific version is reasonable, but the version numbers are still in the 0.x range, which usually signals that interfaces can change.

The upgrade cost lives in your profiles. The README warns that built-in path resolution currently covers only certain rule types and that user-provided grants normalize separately. If you maintain local-overrides.sb with hand-written rules, a change to how built-in grants are expanded can affect what your appended denies actually override. Keep that file small and commented, and re-check it after each version bump rather than assuming appended rules behave identically across releases.

Editorial conclusion

Adopt Agent Safehouse if you run coding agents on macOS and want a deny-first default that still lets normal development work, especially if you already use --dangerously-skip-permissions style flags. Skip it if you are on Linux or Windows, since it depends on macOS sandbox-exec, and skip it if you need a boundary that holds against a determined attacker rather than a hardening layer. Before rolling it out, verify two things yourself: that your agent's normal workflow still functions under the default policy, and that your machine-local exceptions live in an appended profile rather than in shared repo config. The README's own example puts host-specific paths in ~/.config/agent-safehouse/local-overrides.sb, and that file is the first place to look when a command that worked outside the sandbox starts failing inside it.

Frequently asked questions

What is a CIA safe house?

This question is about intelligence tradecraft, not about Agent Safehouse. The project borrows the word for a different purpose: an isolated environment that limits what a local AI coding agent can reach on macOS.

What does "safehouse" mean?

In general usage it is a secure location used as a refuge or base. In this project the term refers to a sandboxed execution environment built on macOS sandbox-exec with deny-first policy profiles, so an agent can only access the files and integrations it needs.

What is an AI agent environment?

It is the set of files, tools and integrations an AI agent can reach while it runs. Agent Safehouse narrows that environment on macOS by assembling composable sandbox-exec profiles, with HOME_DIR and WORK_DIR used to render precise home-relative and workdir-relative rules.

What is an agent in simple words?

An agent is a program that takes actions on your behalf rather than only answering questions. Agent Safehouse assumes such a program may run commands and edit files, and constrains it so it can only read or write paths granted by the assembled policy.

Official sources

  1. eugene1g/agent-safehouse on GitHub
  2. License: Apache-2.0
  3. Project website
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/eugene1g-agent-safehouse.svg)](https://hysenlabs.com/projects/eugene1g-agent-safehouse)