diff --git a/.claude/settings.json b/.claude/settings.json new file mode 100644 index 00000000..9f471bab --- /dev/null +++ b/.claude/settings.json @@ -0,0 +1,19 @@ +{ + "permissions": { + "allow": [ + "WebFetch(domain:acpedia.org)" + ], + "deny": [ + "Bash", + "Write", + "Edit", + "Read", + "Glob", + "Grep", + "NotebookEdit", + "WebSearch" + ], + "ask": [] + }, + "enableAllProjectMcpServers": true +} diff --git a/.gitignore b/.gitignore index e7b24d9a..5eb460cd 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,8 @@ __pycache__ static/v2/ frontend/node_modules/ + +# Claude Code per-machine permissions (do NOT deploy to server — production +# agent must run with the strict permissions in committed .claude/settings.json) +.claude/settings.local.json +.claude/settings.local.json.* diff --git a/agent/overlord-agent.service b/agent/overlord-agent.service index d9f75220..6f40f5dd 100644 --- a/agent/overlord-agent.service +++ b/agent/overlord-agent.service @@ -5,18 +5,23 @@ Wants=network-online.target [Service] Type=simple -User=erik -Group=erik -# Working directory MUST be the repo root so: -# - claude -p sessions land at ~/.claude/projects/-home-erik-MosswartOverlord/ -# - .mcp.json is auto-loaded +# Dedicated unprivileged user — kernel-level isolation from `erik`. +# overlord-agent has NO access to /home/erik/.claude (mode 0700), +# /home/erik/.ssh, /home/erik/.bash_history, /home/erik/.gitconfig, etc. +# Its own claude state lives at /var/lib/overlord-agent/.claude/ and its +# claude session JSONLs land there — completely separate from any +# interactive Claude Code use by the human user. +User=overlord-agent +Group=overlord-agent +# Working directory: the repo root (group-readable to overlord-agent). +# claude session JSONLs path-encode this cwd so it's important to keep +# stable across restarts. WorkingDirectory=/home/erik/MosswartOverlord -# Secrets moved OUT of /home/erik/ to /etc/overlord/agent.env so -# ProtectHome=read-only blocks their read entirely. The file is -# root-owned, mode 0640, group=erik. +# HOME explicitly set so claude reads /var/lib/overlord-agent/.claude/* +# instead of trying /home/erik/.claude/* (which is now 0700, locked out). +Environment="HOME=/var/lib/overlord-agent" +# Secrets file (root:overlord-agent 0640). EnvironmentFile=-/etc/overlord/agent.env -# Backwards-compat: also try the old location during transition. -EnvironmentFile=-/home/erik/MosswartOverlord/.env # Run inside the venv populated by install.sh. ExecStart=/home/erik/MosswartOverlord/agent/.venv/bin/python -m agent.service Restart=on-failure @@ -37,12 +42,11 @@ ProtectHome=read-only # Allow writing only to the explicit paths claude / our service need. # - ~/.claude — session JSONL files # - .venv pycache — minor pip cache writes -ReadWritePaths=/home/erik/.claude +ReadWritePaths=/var/lib/overlord-agent/.claude ReadWritePaths=/home/erik/MosswartOverlord/agent/.venv ReadWritePaths=/var/log/overlord-agent -# Keep $HOME visible to the venv python so it can find pip cache etc. -# (read-only via ProtectHome=read-only — this writable carve-out is -# narrowly the .claude session dir above.) +# StateDirectory creates/owns /var/lib/overlord-agent automatically. +StateDirectory=overlord-agent LogsDirectory=overlord-agent LogsDirectoryMode=0755 PrivateTmp=true