From 2d636c50bf29ce0152608daa59dddfedbab9deec Mon Sep 17 00:00:00 2001 From: Prasanth Kotaru <17078723+vkotaru@users.noreply.github.com> Date: Sun, 30 Aug 2026 14:27:31 -0400 Subject: [PATCH] security: narrow Bash(bun run:*) to the six shipped portal CLIs (#396) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The upstream template pre-approves `Bash(bun run:*)`, which auto-approves `bun run ` — arbitrary TypeScript from anywhere on disk — on every fork. Each portal SKILL.md already declares the tight form in its own allowed-tools; this makes settings.json agree with them. Blast radius drops from "any file on the machine" to the repo's own CLIs, with no new prompts in the /scrape path. tools/security_guards.py's ALLOWED_PERMISSIONS is updated in the same commit, as its docstring requires. Local: security_guards OK, lint_skills OK, 318 tests pass. Claude-Session: https://claude.ai/code/session_01HHqEAQqGS2KKXASiYcrAHQ --- .claude/settings.json | 7 ++++++- tools/security_guards.py | 12 +++++++++++- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/.claude/settings.json b/.claude/settings.json index 347018c..42e51d1 100644 --- a/.claude/settings.json +++ b/.claude/settings.json @@ -2,7 +2,12 @@ "permissions": { "allow": [ "Skill(job-application-assistant)", - "Bash(bun run:*)", + "Bash(bun run .agents/skills/jobbank-search/cli/src/cli.ts:*)", + "Bash(bun run .agents/skills/jobdanmark-search/cli/src/cli.ts:*)", + "Bash(bun run .agents/skills/jobindex-search/cli/src/cli.ts:*)", + "Bash(bun run .agents/skills/jobnet-search/cli/src/cli.ts:*)", + "Bash(bun run .agents/skills/linkedin-search/cli/src/cli.ts:*)", + "Bash(bun run .agents/skills/freehire-search/cli/src/cli.ts:*)", "Bash(python salary_lookup.py:*)", "Bash(python3 salary_lookup.py:*)", "Bash(python tools/verify_pdf.py:*)", diff --git a/tools/security_guards.py b/tools/security_guards.py index 0285367..20988ad 100644 --- a/tools/security_guards.py +++ b/tools/security_guards.py @@ -38,7 +38,17 @@ errors: list[str] = [] # an entry must add it here too - that is the point: the diff shows both. ALLOWED_PERMISSIONS = { "Skill(job-application-assistant)", - "Bash(bun run:*)", + # Narrowed from the upstream template's blanket Bash(bun run:*), which + # pre-approved `bun run `. One entry per shipped portal CLI, + # matching what each SKILL.md already declares in its allowed-tools. + # A portal added by /add-portal needs its own entry here and in + # .claude/settings.json - that review step is the point. + "Bash(bun run .agents/skills/jobbank-search/cli/src/cli.ts:*)", + "Bash(bun run .agents/skills/jobdanmark-search/cli/src/cli.ts:*)", + "Bash(bun run .agents/skills/jobindex-search/cli/src/cli.ts:*)", + "Bash(bun run .agents/skills/jobnet-search/cli/src/cli.ts:*)", + "Bash(bun run .agents/skills/linkedin-search/cli/src/cli.ts:*)", + "Bash(bun run .agents/skills/freehire-search/cli/src/cli.ts:*)", "Bash(python salary_lookup.py:*)", "Bash(python3 salary_lookup.py:*)", "Bash(python tools/verify_pdf.py:*)",