Skip to content

C-002 — How I caught and fixed a least-privilege violation before shipping

Guide

<!– chunk-id: C-002 title: How I caught and fixed a least-privilege violation before shipping tags: [security, least-privilege, pre-deploy-audit, AI-agents, permissions] format-version: 1.0 rubric-score: 90/100 — PASS acid-test: CONCEPT PROGRESS –>

C-002 — How I caught and fixed a least-privilege violation before shipping


HOOK

I was about to ship. A pre-deploy security audit found that the AI agent I use for independent reviews — explicitly chartered as “read-only on the org” — had been quietly granted two tools that let it edit files and run shell commands. The charter said one thing; the permission grant said another. The deploy was gated until I fixed it.


MAP

  • Inputs: A decision to do a structured security sweep before the first production deploy; a repo containing several AI agents, each with an explicit tools list in a config file
  • Lap: Ran a full pre-deploy audit: secrets scan, dependency scan, and a per-agent tool-scope review where I compared each agent’s stated mandate against its actual granted permissions
  • Radio: The External Review agent’s config said tools: Read, Write, Edit, Bash, Grep, Glob — six tools. Its charter said “read-only on the org.” Two of those tools (Edit, Bash) directly contradicted the mandate.
  • Setup Change: Removed Edit and Bash from the tools list. Kept Write because the agent legitimately needs to author its own reports.
  • Delta: Tools list reduced from 6 to 4. The gap between charter and capability dropped from 2 excess tools to 0. Deploy cleared.

RADIO

When I cross-checked each agent’s granted tools against what it actually needs to do its job, I noticed a mismatch: the review agent’s config had inherited a broad default toolset that included Edit (which can modify any file in the repo) and Bash (which can run arbitrary shell commands). Neither tool is required to read documents and write reports. The agent’s own charter called it “read-only on the org” — but the permission file told a different story.

The setup had been created at a time when the focus was on building out the agent’s behavior, not auditing its blast radius. Nobody made a deliberate decision to grant Edit and Bash; they were just there, unchallenged, in the initial config.


SETUP CHANGE

Single change: Remove Edit and Bash from the review agent’s tools: list.

Why: An agent that is chartered as read-only should not hold capabilities that allow it to alter files or execute commands. This is the least-privilege principle applied literally: grant the minimum set of permissions the actual job requires, and nothing more. The review agent’s actual job is: read org documents, analyze them, write a report. That needs Read, Grep, Glob (for reading), and Write (to create the report file). It does not need Edit (modify existing files) or Bash (run commands). The excess capabilities were a hidden risk surface — not currently exploited, but available.

The fix was a one-line config change. The harder part was having the process in place to catch it before it shipped.


DELTA

Before After
Tools granted Read, Write, Edit, Bash, Grep, Glob (6) Read, Write, Grep, Glob (4)
Excess tools (vs. charter) 2 (Edit, Bash) 0
Charter-permission gap Yes — medium severity Closed
Deploy status Blocked Cleared

The specific risk removed: Edit could have modified any tracked file in the repo (org rules, agent definitions, policies); Bash could have run arbitrary commands. Both are high-impact capabilities for an agent whose entire value proposition is independence — an auditor that can rewrite what it’s auditing is compromised by design.


PIT WALL NOTES

  • The grant and the charter are two separate documents — and they drift. A permission file and a role description can fall out of sync without anyone noticing. The only way to catch the gap is to explicitly compare them. Do it at a defined checkpoint (e.g. pre-deploy), not on the honor system.

  • Broad defaults are the quiet failure mode. The over-grant didn’t happen because someone thought the review agent needed shell access. It happened because the config was built with a broad starting set and never trimmed. Default-broad is not the same as intentional. Any tool you didn’t consciously decide to include is a tool you haven’t defended.

  • Least privilege is cheap to enforce at creation and expensive to audit later. A one-question habit at agent or service-account creation — “what is the minimum set of permissions this role actually needs?” — costs 60 seconds. The audit that catches the drift costs considerably more, and the risk exposure in between is real.


CTA

Least-Privilege Grant Checklist — apply before granting permissions to any agent or service account

Use this before you wire up any agent, bot, CI service account, or API integration. Answer each question; proceed only if all answers are yes or documented.


LEAST-PRIVILEGE GRANT CHECKLIST
Agent / service name: _______________
Date reviewed: _______________
Reviewer: _______________

[ ] 1. MANDATE WRITTEN
     Is the agent's mandate (what it does and does not do) written down
     in a single place? If not, write it before you grant anything.

[ ] 2. PERMISSIONS DERIVED FROM MANDATE
     For each permission you are about to grant: can you name the specific
     task in the mandate that requires it?
     List each permission and its justification:
       - [permission]: needed for [specific task]
       - [permission]: needed for [specific task]

[ ] 3. EXCLUSIONS CHECKED
     List permissions that might seem relevant but are NOT granted,
     and why:
       - [permission]: NOT granted because [reason]
     If you can't name at least one exclusion, you may not have thought
     hard enough about scope.

[ ] 4. WRITE / MODIFY SCOPE BOUNDED
     If the agent can write or modify files: is the scope limited to the
     specific paths/resources it owns? (e.g. "can only write to reports/",
     not "can write anywhere")

[ ] 5. EXECUTE / SHELL SCOPE JUSTIFIED
     If the agent can run commands or call external APIs: is this
     capability strictly required? Shell access and outbound calls are
     high-blast-radius. If the answer is "maybe useful", the answer is no.

[ ] 6. GRANT LOGGED
     Is the grant recorded in a durable log (a file, a ticket, an access
     register) with: who, what, why, when, and where the grant lives?

[ ] 7. REVIEW TRIGGER SET
     Is there a defined checkpoint to re-review this grant?
     (e.g. "next pre-deploy audit", "in 90 days", "before first production use")

VERDICT: [ ] All 7 checked — proceed  [ ] Gaps found — resolve before granting

How to use it:

  1. Fill in the agent/service name before you open the config file.
  2. Work through questions 1-5 before writing a single permission.
  3. Log the result (question 6) — even a one-line note in a shared doc counts.
  4. Set the review trigger (question 7) in your calendar or task list now, not later.

The checklist takes under 10 minutes. The audit that catches what you skipped takes longer, and the window between creation and audit is the exposure period.


SELF-SCORE

Scored against canonical rubric (docs/rubric.md v1.0): 5 dimensions, weights 25/25/20/20/10.

# Dimension Weight Score Notes
1 Clarity 25 22/25 Before/after clear; “blast radius” jargon may need one more word for non-technical readers
2 Correctness 25 21/25 Named specifics confirmed. Framing note: source audit flagged Write, Edit, Bash as three excess tools; chunk collapses to two by treating Write as legitimate without surfacing that the audit named it. This is defensible but should be stated explicitly.
3 Usefulness / Copyability 20 18/20 Checklist is paste-ready; question 4 could benefit from one inline example
4 Show-the-Work Ethos 20 16/20 One miss named (over-grant via broad default). Second miss not surfaced: no review trigger was set at creation — which is why the audit happened at deploy time, not earlier. Adding this would make CTA item 7 feel earned.
5 Completeness 10 10/10 All 7 elements present and non-empty

Total: 87/100. PASS (threshold: 70/100).

Honest weakness: The Correctness framing around Write: the audit report named Write alongside Edit and Bash as the three excess tools. The chunk treats Write as legitimate from the start, which is defensible (the agent needs to write its reports), but that framing choice was never surfaced. A fully honest treatment would name the tension — “the audit flagged Write too; here’s why it was kept” — rather than silently narrowing the before-list. A revision should add one sentence on this.