agentleFS
DanSessionsDanSessions/security-posture-skill/skills/security-posture/SKILL.md

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

  • Other versions2 projects use a version of this.

    Word for word · 0

    None found.

    Edited · 0

    None found.

    Wrote their own version · 2

    1. MortisDei/hermaeus★ 1same name
    2. 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.

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
  1. Very specific:

    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 …

    line 13
  2. Distinctive:

    Verify the scripts directory exists before proceeding:

    line 20
  3. Very specific:

    If the directory is missing, tell the user: "The security-posture skill scripts are not installed at …

    line 26
  4. Very specific:

    Never write these as "${HOME}/.claude/skills/...".

    line 34
  5. Distinctive:

    Remove any cache files left over from previous sessions before gathering new data.

    line 40
  6. Distinctive:

    Use ToolSearch to load the SonarQube MCP tool schemas — this also confirms the tools are available in your session:

    line 79
  7. Distinctive:

    If ToolSearch returns no matching tools, stop and tell the user:

    line 85
  8. Distinctive:

    If this fails, stop and tell the user:

    line 101
  9. Very specific:

    Read sonar.projectKey from sonar-project.properties in the current directory:

    line 117
  10. Very specific:

    When the output is default, omit --pr from all subsequent tool calls and label the summary as "(default branch)".

    line 145
  11. Distinctive:

    Call the MCP tool directly — this cannot be scripted:

    line 155
  12. Very specific:

    If Step 3 returned pr:<number>, add pullRequest: <number>.

    line 161
  13. Distinctive:

    Call the MCP tool directly:

    line 165
  14. Distinctive:

    If either script fails, note the error, continue to Step 5, and append this warning after the report output:

    line 184
  15. Very specific:

    If deduplication fails, or if the gather script fails for a reason other than found vulnerabilities (e.g.

    line 201
  16. Distinctive:

    Check the exit code:

    line 214
  17. Distinctive:

    Run after all data-gathering steps are complete:

    line 243
  18. Very specific:

    Read ~/.cache/security-posture/security_posture_report.md and output its contents verbatim.

    line 255
  19. Very specific:

    If hotspot_count > 0: *Reply with a number to drill into any item, a letter (e.g.

    line 258
  20. Very specific:

    If hotspot_count == 0: *Reply with a number to drill into any item, or go to work through them all.*

    line 259
  21. Distinctive:

    After the report is output, the user may reply with a number, a letter, or "go".

    line 265

≈ “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.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

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.sh

Never 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.sh

Step 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.sh

The 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.sh

If 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.sh

The 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 branch
  • pr:<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.py

Replace <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.py

Non-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.py

Check 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.py

Step 3 — Deduplicate across images:

~/.claude/skills/security-posture/scripts/deduplicate-container-findings.py

4f: Extract Snyk Recommendations

~/.claude/skills/security-posture/scripts/extract-snyk-recommendations.py

Reads 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.py

The 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, or go to work through them all.
  • If hotspot_count == 0: Reply with a number to drill into any item, or go to 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:

  1. 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.
  2. 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.
  3. Give a concrete remediation step, based on the item type:
    • base_image_outdated: Show the command from item.detail. Add which services are affected (item.services), the total number of vulnerabilities resolved (item.fixes_count), and a breakdown of the package families from item.resolves with their severity counts.
    • oss_upgrade: Synthesize the install command from item.package_manager and item.detail (e.g. npm install next@15.5.18). Include the total fixes count and severity breakdown from item.fixes_breakdown.
    • sonar_hotspot: Describe what the rule flags and what to look for in the code at item.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-issue skill and explain what it will do before proceeding.
  4. 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.

Download now (ZIP)

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
What did you use it for? e.g. Reviewing pull requests in a Rails app

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.