ワンクリックで
security-scan
Run ASH (Automated Security Helper) security scan with delta detection
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
メニュー
Run ASH (Automated Security Helper) security scan with delta detection
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
SOC 職業分類に基づく
| name | security-scan |
| description | Run ASH (Automated Security Helper) security scan with delta detection |
| allowed-tools | Read, Grep, Glob, Bash(uvx:*), Bash(ash:*), Bash(jq:*), Bash(git:diff|status|log), Bash(cat:*), Bash(mkdir:*) |
Run ASH (Automated Security Helper) - a comprehensive security scanning tool that bundles multiple scanners into a unified interface. This skill includes delta detection to distinguish NEW findings (your changes) from PRE-EXISTING findings (inherited security debt).
This skill performs security scanning using ASH, which includes:
| Scanner | Type | What It Does |
|---|---|---|
| Semgrep | SAST | Multi-language code analysis (includes custom rules) |
| Bandit | SAST | Python-specific security analysis |
| Grype | SCA | Multi-language dependency scanning |
| detect-secrets | Secrets | All text files for hardcoded secrets |
| Checkov | IaC | Infrastructure-as-code validation |
/security-scan
Run this skill after implementing a story and staging changes, but BEFORE committing.
state/{project}/security-baseline.json (pre-existing findings)# Create output directory
mkdir -p .ash/ash_output
# Run ASH in local mode (provides built-in scanners)
uvx --from git+https://github.com/awslabs/automated-security-helper.git@v3.1.5 \
ash --mode local --source-dir . --output-dir .ash/ash_output
# Run custom semgrep rules separately (ASH doesn't pass custom config to semgrep)
if [ -f ".ash/rules/semgrep-rules.yml" ]; then
uvx semgrep --config .ash/rules/semgrep-rules.yml --json --quiet . > .ash/ash_output/custom-semgrep.json 2>/dev/null || true
fi
Note: ASH runs semgrep with its built-in rules. Custom rules in .ash/rules/semgrep-rules.yml are run separately and merged with ASH results.
# Read baseline from Ralph Loop state directory
# The baseline was captured at the start of the session, before you made changes
cat "$RALPH_PROJECT_STATE_DIR/security-baseline.json" | jq '.'
The baseline file contains findings captured before you started working:
[
{"file": "src/old-file.ts", "line": 15, "rule_id": "dangerous-eval", "severity": "ERROR"},
...
]
Compare current scan results (ASH + custom semgrep) against the baseline:
# Read ASH findings from OCSF format
ASH_FINDINGS=$(cat .ash/ash_output/reports/ash.ocsf.json | jq -c '[.[]? | .vulnerabilities[0] as $v | {file: $v.affected_code[0].file.path, line: $v.affected_code[0].start_line, rule_id: $v.cve.uid, severity: $v.severity, message: $v.desc}]')
# Read custom semgrep findings
CUSTOM_FINDINGS=$(cat .ash/ash_output/custom-semgrep.json 2>/dev/null | jq -c '[.results[]? | {file: .path, line: .start.line, rule_id: .check_id, severity: .extra.severity, message: .extra.message}]' || echo "[]")
# Merge all findings
CURRENT=$(echo "$ASH_FINDINGS" "$CUSTOM_FINDINGS" | jq -s 'add | unique_by(.file + ":" + (.line|tostring) + ":" + .rule_id)')
# Read baseline
BASELINE=$(cat "$RALPH_PROJECT_STATE_DIR/security-baseline.json" 2>/dev/null || echo "[]")
# A finding is NEW if it's not in the baseline
# Compare by: file + line + rule_id (signature matching)
Classification Logic:
{file, line, rule_id} tuple NOT found in baseline{file, line, rule_id} tuple found in baseline AND file not modified in current changes# Read aggregated results
cat .ash/ash_output/ash_aggregated_results.json | jq '.'
# Or read the summary
cat .ash/ash_output/reports/ash.summary.txt
ASH generates unified output in .ash/ash_output/:
| File | Description |
|---|---|
ash_aggregated_results.json | Machine-readable results |
reports/ash.summary.txt | Human-readable summary |
reports/ash.summary.md | Markdown summary |
reports/ash.sarif | SARIF format for IDE integration |
reports/ash.html | Interactive HTML report |
After running ASH and classifying findings, report in this format:
=== Security Scan Results ===
Status: PASS | FAIL (based on NEW findings only)
NEW Findings (N total):
- [ERROR] file:line - scanner/rule-id
Message: Description of the vulnerability
Fix: Recommended remediation
- [WARNING] file:line - scanner/rule-id
Message: Description
Fix: Recommendation
PRE-EXISTING Findings (M total):
⚠ These findings existed before your changes
⚠ They do NOT block your commit
- [ERROR] src/lib/old-file.ts:15 - dangerous-eval
This file was not modified in your changes.
Recommendation: Create GitHub issue for tracking.
Dependency Vulnerabilities (P total):
- [HIGH] package@version - CVE-YYYY-XXXXX
Title: Vulnerability title
Fix: Upgrade to version X.Y.Z
=== Summary ===
NEW: X findings (blocking)
PRE-EXISTING: Y findings (tracked, non-blocking)
Overall: PASS | FAIL
PASS/FAIL is based on NEW findings only:
Pre-existing findings are:
This allows you to proceed with legitimate work without being blocked by inherited security debt.
git add -A/security-scangh CLI)When stuck after 3 attempts on NEW findings:
gh issue create \
--title "Security: [STORY_ID] - Unable to resolve [VULN_TYPE]" \
--body "## Findings
[Paste scanner findings here]
## Attempted Fixes
1. [Description of first fix attempt]
2. [Description of second fix attempt]
3. [Description of third fix attempt]
## Context
Story: [STORY_ID] - [STORY_TITLE]
Files affected: [list files]
Generated by Securing Ralph Loop" \
--label "security,ralph-escalation"
Pre-existing vulnerabilities found in the baseline are:
You can disable GitHub issue creation for pre-existing findings:
./ralph-secure.sh --no-create-issues ...
ASH uses thresholds from .ash/ash.yaml:
global_settings:
severity_threshold: MEDIUM
fail_on_findings: true
Custom Semgrep rules in .ash/rules/semgrep-rules.yml are run separately from ASH (ASH v3.1.5 doesn't honor the custom config option). The scan process automatically:
.ash/rules/semgrep-rules.ymlThis gives you both ASH's comprehensive scanning AND your project-specific custom rules.
ASH runs via uvx, ensure UV is installed:
curl -LsSf https://astral.sh/uv/install.sh | sh
brew install uv
# or
pip install uv
Ensure the output directory exists and is writable:
mkdir -p .ash/ash_output
Check individual scanner logs in .ash/ash_output/logs/
If $RALPH_PROJECT_STATE_DIR/security-baseline.json doesn't exist:
ralph-secure.sh which handles baseline creation automatically