To stop Devin CLI from reading .env files, register a PreToolUse hook that rejects common credential paths and environment dumps. A playbook instruction alone does not enforce access restrictions.
Save this script as .devin/guard-env.sh in your project. Create .devin/ first. This setup targets Devin CLI; it is not a cloud Devin playbook integration.
#!/usr/bin/env bash
# Devin PreToolUse Hook (Read/Bash/Grep):
# Blocks tool calls touching secret/credential files or dumping the environment.
PAYLOAD=$(cat)
block() {
# Exit code 2 blocks the proposed tool call in Devin CLI.
echo "SECURITY: Blocked $1. Read .env.example or a schema file (env.ts/env.mjs) instead." >&2
exit 2
}
# Secret paths and env dumps
DENIED='\.dev\.vars|\.pem\b|\.p12\b|\.pfx\b|\.ppk\b|\.p8\b|\bid_rsa\b|\bid_dsa\b|\bid_ed25519\b|\bid_ecdsa\b|\.ssh/|\.gnupg/|\.aws/|\.kube/config|\.docker/config|\.config/gh/|\.htpasswd\b|\.tfstate\b|\.[a-z0-9]+_history\b|(~|'"$HOME"')/\.(netrc|npmrc|pypirc|yarnrc|git-credentials|pgpass|my\.cnf|cargo/credentials|config/git/credentials|codex/config\.toml)|/proc/[^[:space:]]*/environ|\bprintenv\b|(^|[[:space:];&|"])env[[:space:]]*($|[";|&])'
printf '%s' "$PAYLOAD" | grep -Eiq "$DENIED" && block "a secret file or env dump"
KEYFILE='["'"'"'][A-Za-z0-9._~/-]*(\.key|credentials\.(json|ya?ml|toml)|secrets\.(json|ya?ml|toml))["'"'"']|(/|\./|~/)[^[:space:]"'"'"'{}()$]*(\.key|credentials\.(json|ya?ml|toml)|secrets\.(json|ya?ml|toml))\b'
printf '%s' "$PAYLOAD" | grep -Eiq "$KEYFILE" && block "a key/credential file"
while IFS= read -r tok; do
case "${tok##*/}" in
.env.example|.env.template|.env.sample|.env.defaults|env.ts|env.mjs|env.d.ts) ;;
.env|.env.*|.envrc) block "a .env file" ;;
esac
done < <(printf '%s' "$PAYLOAD" | grep -Eio '[^[:space:]"'"'"';|&<>()]*\.env[A-Za-z0-9._-]*')
exit 0Merge this hook into .devin/hooks.v1.json, preserving existing hooks:
{
"PreToolUse": [
{
"hooks": [
{
"type": "command",
"command": "bash .devin/guard-env.sh"
}
]
}
]
}Use /hooks to verify registration. With dummy values, test that .env is denied and .env.example is allowed. Devin CLI uses exit code 2 to block; other nonzero codes are errors that do not block.
Filename checks can miss indirect reads. Keep production secrets outside the agent's workspace and environment. See the shared AI secret-protection approach.