security-posture
Skill1 starsChanged 5 months agoMITView on GitHub
You are running the /security-posture skill. Your job is to aggregate security findings from SonarQube and Snyk into a single prioritised report for the current project. Usage: - /security-posture — current project, default branch - /security-posture --pr 42 — pull request - /security-posture --report — re-render report from existing cache without re-scanning If --report is detected, skip the script setup and Steps 0–4 and jump straight to Step 5 (build-action-list.py reads whatever's already in ~/.cache/security-posture/). Don't gather any new data.
- Installs packages
2 other projects use a version of this.
Adopted by
Most recently taken up by
- MortisDei/hermaeustheir own version, first seen Oct 8, 2026
- stevancris/sre-ai-agenttheir own version, first seen Jun 14, 2026
Other versions2 projects use a version of this.
Word for word · 0
None found.
Edited · 0
None found.
Wrote their own version · 2
- MortisDei/hermaeus★ 1same name
- stevancris/sre-ai-agent★ 0same name
How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.
In this repositoryOne other file it gives its agents.
- CLAUDE.mdCLAUDE.md
The file
Show its rules and text
We split this skill into the rules it gives an agent
21 rules. About 0 are common, 11 are distinctive, and 10 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈11
Distinctive · estimate
This author's own choices. Worth a look.
10
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 13
If --report is detected, skip the script setup and Steps 0–4 and jump straight to Step 5 (build-action-list.py reads whatever's already in …
- Distinctive: line 20
Verify the scripts directory exists before proceeding:
- Very specific: line 26
If the directory is missing, tell the user: "The security-posture skill scripts are not installed at …
- Very specific: line 34
Never write these as "${HOME}/.claude/skills/...".
- Distinctive: line 40
Remove any cache files left over from previous sessions before gathering new data.
- Distinctive: line 79
Use ToolSearch to load the SonarQube MCP tool schemas — this also confirms the tools are available in your session:
- Distinctive: line 85
If ToolSearch returns no matching tools, stop and tell the user:
- Distinctive: line 101
If this fails, stop and tell the user:
- Very specific: line 117
Read sonar.projectKey from sonar-project.properties in the current directory:
- Very specific: line 145
When the output is default, omit --pr from all subsequent tool calls and label the summary as "(default branch)".
- Distinctive: line 155
Call the MCP tool directly — this cannot be scripted:
- Very specific: line 161
If Step 3 returned pr:<number>, add pullRequest: <number>.
- Distinctive: line 165
Call the MCP tool directly:
- Distinctive: line 184
If either script fails, note the error, continue to Step 5, and append this warning after the report output:
- Very specific: line 201
If deduplication fails, or if the gather script fails for a reason other than found vulnerabilities (e.g.
- Distinctive: line 214
Check the exit code:
- Distinctive: line 243
Run after all data-gathering steps are complete:
- Very specific: line 255
Read ~/.cache/security-posture/security_posture_report.md and output its contents verbatim.
- Very specific: line 258
If hotspot_count > 0: *Reply with a number to drill into any item, a letter (e.g.
- Very specific: line 259
If hotspot_count == 0: *Reply with a number to drill into any item, or go to work through them all.*
- Distinctive: line 265
After the report is output, the user may reply with a number, a letter, or "go".
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Security Posture Skill
You are running the /security-posture skill. Your job is to aggregate security findings from SonarQube and Snyk into a single prioritised report for the current project.
Usage:
/security-posture— current project, default branch/security-posture --pr 42— pull request/security-posture --report— re-render report from existing cache without re-scanning
Report-only mode
If --report is detected, skip the script setup and Steps 0–4 and jump straight to Step 5 (build-action-list.py reads whatever's already in ~/.cache/security-posture/). Don't gather any new data.
Script Setup
All steps below delegate to scripts in ~/.claude/skills/security-posture/scripts/. Use that literal tilde path for every script call — do not assign a $SCRIPTS_DIR variable and do not use $HOME in the command. Shell variable expansion (e.g. "$SCRIPTS_DIR/check-sonar.sh") causes Claude Code to show a permission prompt labelled "Contains expansion" even when an allowlist entry is present; the literal ~/ prefix avoids this.
Verify the scripts directory exists before proceeding:
ls ~/.claude/skills/security-posture/scripts/If the directory is missing, tell the user: "The security-posture skill scripts are not installed at ~/.claude/skills/security-posture/scripts/. Re-install the skill to continue."
Throughout the rest of this skill, every script call uses the literal prefix. For example:
~/.claude/skills/security-posture/scripts/check-sonar.shNever write these as "${HOME}/.claude/skills/...".
Step 0: Clean Up Stale Cache Files
Remove any cache files left over from previous sessions before gathering new data. This prevents stale results from contaminating the report:
~/.claude/skills/security-posture/scripts/cleanup-cache.shStep 1: Check Prerequisites
Both tools must be available before proceeding. If either check fails, stop immediately — do not produce a partial report.
Tip: On the first run in a new project, Claude Code will prompt for permission on several shell commands. Running /fewer-permission-prompts beforehand (then restarting the session) eliminates most of those prompts.
1a: SonarQube CLI
~/.claude/skills/security-posture/scripts/check-sonar.shThe script uses distinct exit codes:
- Exit 0 — CLI found and API reachable. Continue.
- Exit 1 — CLI not found. Stop and tell the user:
SonarQube CLI not found. To set up: Run /sonar-integrate and follow the instructions. Then restart your Claude Code session and re-run /security-posture. - Exit 2 — CLI found but API unreachable (auth or connectivity). Stop and tell the user:
SonarQube authentication has expired or the server is unreachable. To fix: Run: sonar auth login Then re-run /security-posture.
Use ToolSearch to load the SonarQube MCP tool schemas — this also confirms the tools are available in your session:
ToolSearch(query: "select:mcp__sonarqube__get_project_quality_gate_status,mcp__sonarqube__search_security_hotspots")If ToolSearch returns no matching tools, stop and tell the user:
SonarQube MCP tools are not available in this session.
To set up:
Run /sonar-integrate and follow the instructions.
Then restart your Claude Code session and re-run /security-posture.1b: Snyk CLI
~/.claude/skills/security-posture/scripts/check-snyk.shIf this fails, stop and tell the user:
Snyk CLI not found or not authenticated.
To set up:
npm install -g snyk
snyk auth
Then restart your Claude Code session and re-run /security-posture.Step 2: Resolve Project Key
Read sonar.projectKey from sonar-project.properties in the current directory:
~/.claude/skills/security-posture/scripts/resolve-project-key.shThe script prints the project key to stdout. Use that value wherever <PROJECT_KEY> appears in subsequent steps. If this fails, stop and tell the user:
Could not find sonar.projectKey in sonar-project.properties.
Run /sonar-integrate to configure SonarQube for this project, then re-run /security-posture.Step 3: Determine PR Context
Parse any --pr argument passed to the skill:
~/.claude/skills/security-posture/scripts/resolve-pr.sh [--pr <number>]Output is one of:
default— no PR specified; use SonarQube's default branchpr:<number>— explicit PR requested
When the output is default, omit --pr from all subsequent tool calls and label the summary as "(default branch)".
Step 4: Gather Data
Steps 4a–4d can all run in parallel. Within 4e, the three scripts must run in sequence. Step 4f runs after both 4d and 4e complete.
4a: Security Quality Gate
Call the MCP tool directly — this cannot be scripted:
mcp__sonarqube__get_project_quality_gate_status(projectKey: <PROJECT_KEY>)If Step 3 returned pr:<number>, add pullRequest: <number>. After the MCP call completes, use the Write tool to save the full JSON result to ~/.cache/security-posture/sonar_quality_gate.json so build-action-list.py can read it.
4b: Security Hotspots
Call the MCP tool directly:
mcp__sonarqube__search_security_hotspots(projectKey: <PROJECT_KEY>, statuses: ["TO_REVIEW"])If Step 3 returned pr:<number>, add pullRequest: <number>. After the MCP call completes, use the Write tool to save the full JSON result to ~/.cache/security-posture/sonar_hotspots.json so build-action-list.py can read it.
4c: SonarQube Vulnerability Issues
Gather raw issues, then filter to vulnerabilities only (the SonarQube CLI has no --types flag):
~/.claude/skills/security-posture/scripts/gather-sonar-issues.sh -p "<PROJECT_KEY>"
~/.claude/skills/security-posture/scripts/filter-sonar-vulnerabilities.pyReplace <PROJECT_KEY> with the value resolved in Step 2. If Step 3 returned pr:<number>, append --pr <number> to the gather command. If Step 3 returned default, pass no additional arguments.
If either script fails, note the error, continue to Step 5, and append this warning after the report output:
⚠ SonarQube vulnerability data unavailable — <reason>. Run /sonar-integrate if this is an auth or configuration issue.4d: Snyk OSS Dependencies
Gather raw issues and deduplicate the results:
~/.claude/skills/security-posture/scripts/gather-snyk-oss.sh
~/.claude/skills/security-posture/scripts/deduplicate-snyk-oss.pyNon-zero exit from the gather script is expected when vulnerabilities exist — always run deduplication regardless.
If deduplication fails, or if the gather script fails for a reason other than found vulnerabilities (e.g. missing package.json, network error, auth failure), note the error, continue to Step 5, and append this warning after the report output:
⚠ Snyk OSS data unavailable — <reason>. Check that snyk is authenticated (`snyk whoami`) and that a package manifest exists.4e: Snyk Container
Step 1 — Discover what to scan:
~/.claude/skills/security-posture/scripts/discover-docker-targets.pyCheck the exit code:
- Exit 1 → docker compose not available. Skip the container section, note it in the report.
- Exit 2 → compose available but no images built. Skip the container section. Note in the report:
"Snyk Container: skipped — no images built. Run docker compose build and re-run /security-posture to include container findings."Continue with step 4f using only the OSS data. - Exit 0 → proceed.
Step 2 — Scan all targets in parallel:
~/.claude/skills/security-posture/scripts/scan-all-container-images.pyStep 3 — Deduplicate across images:
~/.claude/skills/security-posture/scripts/deduplicate-container-findings.py4f: Extract Snyk Recommendations
~/.claude/skills/security-posture/scripts/extract-snyk-recommendations.pyReads snyk_oss.json and all snyk_container_*.json files. Writes snyk_recommendations.json.
Step 5: Produce the Report
Build the action list
Run after all data-gathering steps are complete:
~/.claude/skills/security-posture/scripts/build-action-list.pyThe script writes two files:
~/.cache/security-posture/action_list.json— structured data (used by drill-down in Step 6)~/.cache/security-posture/security_posture_report.md— the fully pre-rendered markdown report
Output the report
Read ~/.cache/security-posture/security_posture_report.md and output its contents verbatim. Do not reformat, reorder, renumber, or paraphrase — the script has already produced the correct markdown. Output the file contents exactly as-is.
Then read hotspot_count from ~/.cache/security-posture/action_list.json and output the appropriate prompt as your own message:
- If
hotspot_count > 0: Reply with a number to drill into any item, a letter (e.g.a) to drill into any hotspot, orgoto work through them all. - If
hotspot_count == 0: Reply with a number to drill into any item, orgoto work through them all.
Step 6: Drill Into a Finding
After the report is output, the user may reply with a number, a letter, or "go".
Reply is a number (e.g. 1, 3): look up that item in ~/.cache/security-posture/action_list.json under items (where n matches).
Reply is a letter (e.g. a, b): look up the matching entry under hotspot_items (where letter matches).
Reply is go: work through all items in numbered order, then all hotspot_items in letter order, pausing after each for the user to respond before continuing.
For each item, follow these four steps:
- Restate the finding in full. Show the file and line number (if applicable), the rule or CVE ID(s), and the affected version. Do not assume the user remembers the summary line.
- Explain what could go wrong. Two or three plain sentences describing the real-world risk: what an attacker could do, what data or systems are at risk, and under what conditions the vulnerability is exploitable. Avoid jargon — write for someone who is not a security specialist.
- Give a concrete remediation step, based on the item type:
base_image_outdated: Show the command fromitem.detail. Add which services are affected (item.services), the total number of vulnerabilities resolved (item.fixes_count), and a breakdown of the package families fromitem.resolveswith their severity counts.oss_upgrade: Synthesize the install command fromitem.package_manageranditem.detail(e.g.npm install next@15.5.18). Include the total fixes count and severity breakdown fromitem.fixes_breakdown.sonar_hotspot: Describe what the rule flags and what to look for in the code atitem.file:item.line. Explain how to assess whether this is a real vulnerability or a false positive, and what the safe pattern looks like.- SonarQube vulnerability (other sources): Offer to invoke the
sonar-fix-issueskill and explain what it will do before proceeding.
- Ask what to do next. "Fix it now, skip to the next item, or stop here?" The user decides — do not make go/no-go calls.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

