feat(agents): add strict security hardening for Pi and OpenCode

Pi Guardrails:
- Enables @aliou/pi-guardrails with strict default config
- Sets onboarding.completed = true to skip onboarding prompt
- Enables pathAccess in ask mode for /nix/store and /tmp
- Adds noAccess policies for: SSH keys, GPG keys, AWS config,
  Kubernetes config, cloud CLI configs (gh/gcloud/1password/sops),
  agenix secrets, Pi auth/sessions, env files, private keys/certs
- Adds auto-deny patterns for env leakage commands:
  env, printenv, /proc/*/environ, GPG secret exports,
  ssh-add -D, password manager reads

OpenCode permissions:
- Adds permission section with global security rules
- external_directory: ask by default, allow /nix/store and /tmp
- read/edit: allow by default, deny SSH/GPG/AWS/Kube/cloud configs,
  agenix secrets, Pi auth/sessions, env files, private keys/certs
- glob: restrict sensitive path patterns
- grep: deny SSH/GPG/agenix, ask for PASSWORD/SECRET/API_KEY/PRIVATE_KEY
- bash: ask by default, allow safe git/nix commands,
  deny env/printenv/proc/GPG secret/sudo/ssh-add deletion/curl|sh
- webfetch: ask by default, allow github/nixos search
- doom_loop: ask
This commit is contained in:
2026-04-29 19:48:29 +02:00
parent 9c3d10836f
commit 6a5d8f0011
2 changed files with 354 additions and 0 deletions

View File

@@ -49,6 +49,150 @@
};
};
# Security: permission hardening for OpenCode
# Last matching rule wins. Glob patterns: * = any chars, ? = single char.
# ~ and $HOME are expanded to the user's home directory.
# external_directory gates paths outside the working directory.
permission = {
# External directory access: ask by default, allow safe paths
"external_directory" = {
"*" = "ask";
"/nix/store/**" = "allow";
"/tmp/**" = "allow";
};
# Read access: allow by default, deny sensitive paths
"read" = {
"*" = "allow";
"~/.ssh/**" = "deny";
"~/.gnupg/**" = "deny";
"~/.aws/**" = "deny";
"~/.kube/**" = "deny";
"~/.config/gh/**" = "deny";
"~/.config/gcloud/**" = "deny";
"~/.config/op/**" = "deny";
"~/.config/sops/**" = "deny";
"/run/agenix/**" = "deny";
"~/.pi/agent/auth.json" = "deny";
"~/.pi/agent/sessions/**" = "deny";
"*.env" = "deny";
"*.env.*" = "deny";
"*.pem" = "deny";
"*.key" = "deny";
"*.p12" = "deny";
"*.pfx" = "deny";
"*id_rsa*" = "deny";
"*id_ed25519*" = "deny";
"*id_ecdsa*" = "deny";
"*.example.env" = "allow";
"*.sample.env" = "allow";
"*.test.env" = "allow";
".env.example" = "allow";
".env.sample" = "allow";
".env.test" = "allow";
"~/.ssh/*.pub" = "allow";
"*.pub" = "allow";
"*.csr" = "allow";
};
# Edit access: ask by default, deny sensitive paths
"edit" = {
"*" = "ask";
"~/.ssh/**" = "deny";
"~/.gnupg/**" = "deny";
"~/.aws/**" = "deny";
"~/.kube/**" = "deny";
"~/.config/gh/**" = "deny";
"~/.config/gcloud/**" = "deny";
"~/.config/op/**" = "deny";
"~/.config/sops/**" = "deny";
"/run/agenix/**" = "deny";
"~/.pi/agent/auth.json" = "deny";
"~/.pi/agent/sessions/**" = "deny";
"*.env" = "deny";
"*.env.*" = "deny";
"*.pem" = "deny";
"*.key" = "deny";
"*.p12" = "deny";
"*.pfx" = "deny";
"*id_rsa*" = "deny";
"*id_ed25519*" = "deny";
"*id_ecdsa*" = "deny";
"~/.ssh/*.pub" = "allow";
"*.pub" = "allow";
"*.csr" = "allow";
};
# Glob patterns: same rules as read for file matching
"glob" = {
"*" = "allow";
"~/.ssh/**" = "deny";
"~/.gnupg/**" = "deny";
"/run/agenix/**" = "deny";
"*.env" = "deny";
"*.env.*" = "deny";
"*.pem" = "deny";
"*.key" = "deny";
"*.p12" = "deny";
"*.pfx" = "deny";
};
# Grep: allow search, but deny searching for secrets
"grep" = {
"*" = "allow";
"~/.ssh/**" = "deny";
"~/.gnupg/**" = "deny";
"/run/agenix/**" = "deny";
"*PASSWORD*" = "ask";
"*SECRET*" = "ask";
"*API_KEY*" = "ask";
"*PRIVATE_KEY*" = "ask";
};
# Bash: ask by default, deny dangerous and env-leak commands
"bash" = {
"*" = "ask";
"git status*" = "allow";
"git diff*" = "allow";
"git log*" = "allow";
"git branch*" = "allow";
"git show*" = "allow";
"git remote*" = "allow";
"nix --version" = "allow";
"nix eval*" = "allow";
"nix build*" = "allow";
"nix develop*" = "allow";
"nix shell*" = "allow";
"nix search*" = "allow";
"alejandra*" = "allow";
"git add*" = "allow";
"git commit*" = "allow";
"git push*" = "ask";
"git pull*" = "allow";
"rm *" = "ask";
"rm -rf *" = "deny";
"sudo *" = "ask";
"env" = "deny";
"printenv" = "deny";
"cat /proc/*/environ" = "deny";
"gpg *--export-secret*" = "deny";
"ssh-add -D" = "deny";
"docker run --privileged*" = "deny";
"curl *| *sh" = "deny";
"wget *| *sh" = "deny";
};
# Web fetch: ask for sensitive URLs
"webfetch" = {
"*" = "ask";
"https://api.github.com*" = "allow";
"https://search.nixos.org*" = "allow";
};
# Doom loop guard
"doom_loop" = "ask";
};
# AZ-Gruppe LiteLLM endpoint + available models
provider = {
litellm = {