Make the agent structurally unable to read your secrets starter
You want .env, keys, and credentials off the table entirely — not "the model was told not to".
on the sheet: permissionsconfig
-
Deny by pattern. The rules take globs, so you can name whole shapes of file rather than enumerating them.
.cursor/cli.json
{
"permissions": {
"allow": [
"Shell(git)",
"Shell(npm run test)",
"Read(src/**/*.ts)"
],
"deny": [
"Read(.env*)",
"Write(**/*.key)",
"Shell(rm)"
]
}
}
A deny on Read(.env*) beats any instruction in a prompt, because it holds even when the agent has a good reason to look — a failing test that needs the database URL is exactly the moment a polite "don't read secrets" gets rationalized away.
Permissions
Give a CI agent exactly one job intermediate
An agent runs on every PR and should comment — but never push, never branch, never merge.
on the sheet: permissionsheadless
-
State the boundary in the prompt and enforce it in the config. The prompt tells it what you want; the deny list is what holds when the prompt doesn't.
agent -p "Review the diff and post findings as a PR comment.
IMPORTANT: Do NOT create branches, commit, push, or merge." \
--model gpt-5
-
Back it with a config the prompt can't talk its way past.
.cursor/cli.json
{
"permissions": {
"allow": ["Shell(gh pr comment)", "Shell(git diff)", "Shell(git log)"],
"deny": ["Shell(git push)", "Shell(git commit)", "Shell(gh pr merge)"]
}
}
Two layers, because they fail differently. The prompt shapes intent and produces better work; the deny list is what's left standing when the model decides pushing a fix would be helpful.
GitHub Actions