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:
@@ -54,6 +54,216 @@
|
||||
defaultThinkingLevel = "high";
|
||||
};
|
||||
|
||||
# pi-guardrails: strict security config
|
||||
# NOTE: Path access checks are lexical (not symlink-safe).
|
||||
# NOTE: Local project .pi/extensions/guardrails.json can override same rule IDs.
|
||||
# For immutable global policies, consider a wrapper or upstream patch.
|
||||
guardrails = {
|
||||
enable = true;
|
||||
config = {
|
||||
enabled = true;
|
||||
applyBuiltinDefaults = true;
|
||||
|
||||
onboarding = {
|
||||
completed = true;
|
||||
};
|
||||
|
||||
features = {
|
||||
policies = true;
|
||||
permissionGate = true;
|
||||
pathAccess = true;
|
||||
};
|
||||
|
||||
pathAccess = {
|
||||
mode = "ask";
|
||||
allowedPaths = [
|
||||
"/nix/store/"
|
||||
"/tmp/"
|
||||
];
|
||||
};
|
||||
|
||||
policies = {
|
||||
rules = [
|
||||
# ── SSH keys ───────────────────────────────────────────
|
||||
{
|
||||
id = "home-ssh";
|
||||
enabled = true;
|
||||
protection = "noAccess";
|
||||
onlyIfExists = false;
|
||||
patterns = [
|
||||
{pattern = "~/.ssh/**";}
|
||||
{pattern = "~/.ssh/*_rsa";}
|
||||
{pattern = "~/.ssh/*_ed25519";}
|
||||
{pattern = "~/.ssh/*.pem";}
|
||||
];
|
||||
allowedPatterns = [
|
||||
{pattern = "~/.ssh/*.pub";}
|
||||
];
|
||||
}
|
||||
|
||||
# ── GPG keys ─────────────────────────────────────────
|
||||
{
|
||||
id = "home-gpg";
|
||||
enabled = true;
|
||||
protection = "noAccess";
|
||||
onlyIfExists = false;
|
||||
patterns = [
|
||||
{pattern = "~/.gnupg/**";}
|
||||
{pattern = "~/*.gpg";}
|
||||
{pattern = "~/.gpg-agent.conf";}
|
||||
];
|
||||
}
|
||||
|
||||
# ── AWS credentials ────────────────────────────────────
|
||||
{
|
||||
id = "home-aws";
|
||||
enabled = true;
|
||||
protection = "noAccess";
|
||||
onlyIfExists = false;
|
||||
patterns = [
|
||||
{pattern = "~/.aws/**";}
|
||||
{pattern = "~/.aws/credentials";}
|
||||
{pattern = "~/.aws/config";}
|
||||
];
|
||||
}
|
||||
|
||||
# ── Kubernetes configs ────────────────────────────────
|
||||
{
|
||||
id = "home-kube";
|
||||
enabled = true;
|
||||
protection = "noAccess";
|
||||
onlyIfExists = false;
|
||||
patterns = [
|
||||
{pattern = "~/.kube/**";}
|
||||
{pattern = "*kubeconfig*";}
|
||||
];
|
||||
}
|
||||
|
||||
# ── Cloud CLI configs ────────────────────────────────
|
||||
{
|
||||
id = "home-config";
|
||||
enabled = true;
|
||||
protection = "noAccess";
|
||||
onlyIfExists = false;
|
||||
patterns = [
|
||||
{pattern = "~/.config/gh/**";}
|
||||
{pattern = "~/.config/gcloud/**";}
|
||||
{pattern = "~/.config/op/**";}
|
||||
{pattern = "~/.config/sops/**";}
|
||||
];
|
||||
}
|
||||
|
||||
# ── agenix secrets ───────────────────────────────────
|
||||
{
|
||||
id = "agenix-secrets";
|
||||
enabled = true;
|
||||
protection = "noAccess";
|
||||
onlyIfExists = false;
|
||||
patterns = [
|
||||
{pattern = "/run/agenix/**";}
|
||||
];
|
||||
}
|
||||
|
||||
# ── Pi auth and sessions ────────────────────────────
|
||||
{
|
||||
id = "pi-auth-sessions";
|
||||
enabled = true;
|
||||
protection = "noAccess";
|
||||
onlyIfExists = false;
|
||||
patterns = [
|
||||
{pattern = "~/.pi/agent/auth.json";}
|
||||
{pattern = "~/.pi/agent/sessions/**";}
|
||||
];
|
||||
}
|
||||
|
||||
# ── Environment files ─────────────────────────────────
|
||||
{
|
||||
id = "secret-files";
|
||||
enabled = true;
|
||||
protection = "noAccess";
|
||||
onlyIfExists = true;
|
||||
patterns = [
|
||||
{pattern = ".env";}
|
||||
{pattern = ".env.*";}
|
||||
{pattern = ".dev.vars";}
|
||||
];
|
||||
allowedPatterns = [
|
||||
{pattern = "*.example.env";}
|
||||
{pattern = "*.sample.env";}
|
||||
{pattern = "*.test.env";}
|
||||
{pattern = ".env.example";}
|
||||
{pattern = ".env.sample";}
|
||||
{pattern = ".env.test";}
|
||||
];
|
||||
}
|
||||
|
||||
# ── Private keys and certificates ───────────────────
|
||||
{
|
||||
id = "private-keys";
|
||||
enabled = true;
|
||||
protection = "noAccess";
|
||||
onlyIfExists = false;
|
||||
patterns = [
|
||||
{pattern = "*.pem";}
|
||||
{pattern = "*.key";}
|
||||
{pattern = "*.p12";}
|
||||
{pattern = "*.pfx";}
|
||||
{pattern = "*id_rsa*";}
|
||||
{pattern = "*id_ed25519*";}
|
||||
{pattern = "*id_ecdsa*";}
|
||||
];
|
||||
allowedPatterns = [
|
||||
{pattern = "*.pub";}
|
||||
{pattern = "*.csr";}
|
||||
];
|
||||
}
|
||||
];
|
||||
};
|
||||
|
||||
permissionGate = {
|
||||
explainCommands = false;
|
||||
# Auto-deny patterns: env leakage and credential dumping
|
||||
autoDenyPatterns = [
|
||||
{
|
||||
pattern = "\\benv\\b";
|
||||
regex = true;
|
||||
description = "env command (may dump environment)";
|
||||
}
|
||||
{
|
||||
pattern = "\\bprintenv\\b";
|
||||
regex = true;
|
||||
description = "printenv command (dumps environment variables)";
|
||||
}
|
||||
{
|
||||
pattern = "/proc/[0-9]+/environ";
|
||||
regex = true;
|
||||
description = "reading process environment files";
|
||||
}
|
||||
{
|
||||
pattern = "gpg\\s+--export-secret-keys";
|
||||
regex = true;
|
||||
description = "GPG secret key export";
|
||||
}
|
||||
{
|
||||
pattern = "gpg\\s+--export-secret-subkeys";
|
||||
regex = true;
|
||||
description = "GPG secret subkey export";
|
||||
}
|
||||
{
|
||||
pattern = "ssh-add\\s+-D";
|
||||
regex = true;
|
||||
description = "delete all SSH identities";
|
||||
}
|
||||
{
|
||||
pattern = "\\b(op|pass)\\s+(read|show|get)";
|
||||
regex = true;
|
||||
description = "password manager read operations";
|
||||
}
|
||||
];
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
# MCP servers auto-inherited from programs.mcp in default.nix
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user