keepout
Files AI agents can't touch, enforced by the OS kernel.
keepout claude
Install:
uv tool install git+https://github.com/sahasrarjn/keepout # or: pipx install git+https://github.com/sahasrarjn/keepout
That's it. On first run, keepout writes a .keepout file protecting .env*, keys and
your SSH/AWS credentials, then starts the agent inside a kernel sandbox. It works with
any agent or command: keepout codex, keepout npm test. Works on macOS and Linux,
with no dependencies beyond Python 3.9+ (plus bubblewrap on Linux).
Why
Tool hooks and permission rules only see the agent's own file tools. cat .env,
python -c "open('.e'+'nv')", or a test that loads .env all slip past them.
keepout compiles your rules into an OS sandbox around the whole agent process tree,
so every one of those paths hits the same wall: Operation not permitted (Linux: Permission denied).
.keepout
gitignore syntax, three sections:
[no-read] # can't read, copy, move or edit
.env*
!.env.example
*.pem
~/.ssh/id_*
!~/.ssh/*.pub
[read-only] # can read, can't modify or delete
migrations/
[append-only] # can add to the end, can't rewrite, truncate or delete
logs/
DECISIONS.md
name matches anywhere in the project, dir/name is relative to the project root,
./name means the root only, ~/ is your home directory, and / is an absolute path.
Built for agents
keepout why <path> --json |
is it allowed, per operation, and which rule decides |
keepout status --json |
all rules, the files they match, and whether this shell is sandboxed |
keepout propose add|remove <section> <pattern> --reason ... |
the agent asks; a human runs keepout apply |
keepout test --json |
a 25-case attack matrix that checks enforcement on this machine |
keepout init |
also adds a rules note to AGENTS.md/CLAUDE.md and installs Claude Code hooks, so the model gets a clear reason instead of a bare EPERM and doesn't retry |
| skill | skills/keepout/SKILL.md, so agents discover it when a user says "don't let Claude read my .env" |
Agents can't loosen their own rules. Inside the sandbox, .keepout, keepout itself
and its state are write-protected, and keepout apply refuses to run. If .keepout
changes outside the sandbox, the next keepout <agent> shows the diff and requires a
human to approve it in a terminal.
How it works
macOS: Seatbelt
no-read: Seatbeltdeny file-read* file-write*. Blocking writes too stops "rename it, then read it".read-only: Seatbeltdeny file-write*.append-only: the kernel's user append-only flag (chflags uappnd), plus a Seatbelt rule denying flag changes, unlink and rename, so the agent can't remove it. Flags are cleared when the session ends.- Seatbelt matches the file itself, not the path you typed, so symlinks,
../, and case tricks (.ENV) are all caught.
Linux: bubblewrap
Landlock only supports allowlists, so it can't express "everything except .env".
keepout uses a bubblewrap mount namespace
instead:
no-read: each matching file or directory gets an empty, mode-000, read-only mount over it. Reads fail withPermission denied.mv,rmandlnfail because you can't rename, unlink or hardlink a mount point, andchmodfails because the mount is read-only.read-only: a read-only bind mount (--ro-bind).append-only:chattr +a. Setting it needsCAP_LINUX_IMMUTABLE, so it's enforced only when keepout runs as root. keepout warns when it can't enforce it. When run as root, keepout drops all capabilities inside the sandbox so the agent can't bypass the masks or runchattr -a.- Needs unprivileged user namespaces. On Ubuntu 24.04+, AppArmor may block them for
bwrap;keepout testtells you if it's broken.
Limits (v0.2)
- Linux: rules match files that exist when the session starts. New files matching a
no-readpattern created later aren't masked. append-only needs root (see above). - Seatbelt can't stack different profiles, so Claude Code's own
/sandboxmode can't run inside keepout. Use keepout instead of it. - Hardlinks to a secret that existed before the session aren't caught.
- New files in an
append-onlydirectory become append-only at the next launch. - Windows: use WSL2 (Linux).
[ask]rules (pause and ask the human) need FUSE or Endpoint Security. Planned.
Release files for keepout 0.2.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| keepout-0.2.0.tar.gz | 16.9 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| keepout-0.2.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 33.0 kB
Release files / keepout-0.2.0.tar.gz
| Download URL | keepout-0.2.0.tar.gz |
|---|---|
| Size | 16.9 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
bcdd39ba0d7191e2c7d0fd585b3f3c88af48bf5c5f6df30b81c21e22bac5a4fa
|
|
BLAKE2b-256 checksum How to use checksums |
9381d975df8fb568f18ca535684f85c8540e018cae8d199f0f0d945bd6539f23
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 26, 2026.
Transparency logRelease files / keepout-0.2.0-py3-none-any.whl
| Download URL | keepout-0.2.0-py3-none-any.whl |
|---|---|
| Size | 16.1 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
4882a65550625fa9502f555f6dd2e4d684120c33f5593da83e1e950087a00f06
|
|
BLAKE2b-256 checksum How to use checksums |
10a140916afb4a2e786d2ed9890e8be0d7bf08e25a1178f62abcf298e05ec0c2
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 26, 2026.
Transparency log