Run Claude Code as a dedicated system user to enable OS-level file access enforcement
Problem
CLAUDE.md and prompt-level rules are the only mechanism currently available to
restrict which files Claude may write to. This relies entirely on Claude
correctly interpreting natural-language instructions every turn, which has
proven unreliable in practice — even unambiguous-looking statements from the
user (\"we'll change this now\") can be misinterpreted as implementation
authorization rather than intent declaration.
The result: prompt-based access control is enforcement by convention, not by
mechanism.
Proposal
Run the Claude Code process under a dedicated system user (e.g. claude)
instead of inheriting the invoking user's identity. This would allow standard
OS file permissions to enforce write boundaries:
Example setup (POSIX):
- Create group
projectcoderswith both the user andclaudeas members - User-owned source files:
rw-r----- user projectcoders→ claude can read,
not write
- Claude's memory directory:
rwxr-x--- claude projectcoders→ claude owns
and writes, user can read
- Shared scratch directory:
rwxrwx--- user projectcoders→ both can write
Equivalent enforcement is possible on Windows via ACLs.
Benefits
- Enforcement by mechanism rather than convention — the OS rejects writes
the user did not authorize, regardless of how Claude interpreted the prompt
- Per-project granularity by adjusting group membership / ownership
- Explicit authorization workflow: user
chmods orchowns a file when they
want Claude to be able to modify it directly
- No additional tooling required — uses primitives every developer already
understands
Considerations
- Requires Claude Code to launch its agent process under a different uid
(likely needs setuid helper or a small daemon during install)
- IDE integrations and shell tools spawned by Claude would need to inherit
the claude identity, not the user's
- Initial setup needs to make group membership / directory ownership easy
to configure
- Applies equally to Claude Desktop's Local Agent Mode, which shares the
same single-uid model
This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗