Run a Kedro security scan on the full codebase or just a pull request. This skill always runs Semgrep first and then evaluates the findings against the Kedro se
复制下面这句话,粘贴给 Claude Code、Codex、Cursor 等 AI 编程工具,它会读取安装说明并在你确认后完成安装。
请阅读 https://ai.atlankj.com/install/asset/gh-kedro-security-review-1f5b2c597582 ,按照其中的说明把「kedro-security-review」安装到你(当前 AI 工具)中。执行前先告诉我将运行的命令和写入的位置,等我确认。
查看 AI 将读取的安装说明正在读取 GitHub 原文…
内容来自 GitHub 原始文件,由原作者维护。在 GitHub 查看
Before scanning, decide three things:
## Mode selection)## Scan scope)## Delivery modes)Then run the numbered Workflow below:
mktemp -dreference.mdRead these before triaging findings:
Before scanning, ask once:
Are we scanning Kedro framework code (this repository's
kedro/) or a Kedro project (user pipelines, catalog, and project config)?
Use the answer to pre-classify findings (see reference.md). For example,
kedro-yaml-unsafe-load in kedro/ is candidate_kedro_vulnerability; the
same rule in project code is project_developer_responsibility.
If the user already stated the scope, do not ask again.
semgrepuvx --from semgrep semgrepuv tool run --from semgrep semgrepp/security-auditp/secretsp/python.agents/skills/kedro-security-review/rules/kedro-security-patterns.yml--exclude tests/--exclude docs/--exclude features/--exclude .agents/mktemp -dAlways use --metrics=off.
If a uvx or uv tool run Semgrep command fails with a permissions error on a
~/.cache/uv path, ask the user for permission to run outside the sandbox
(i.e. with full filesystem access) and then rerun the same command. Do not
treat a cache permission failure as a real scan failure.
Later workflow steps that invoke Semgrep should refer back to this note instead of repeating it.
Default mode. Show one final report in chat and do not expose intermediate scan output.
Only use when the user explicitly asks to post, submit, or publish the scan result to GitHub.
Post mode is only valid in PR mode — it produces a GitHub PR review payload and there is no PR to attach it to in full-codebase mode. If a user asks to post a full-codebase scan, fall back to chat mode and tell the user why.
In post mode:
Do not post partial results or progress updates.
Use when the user asks to scan the repo, codebase, project, or current branch without narrowing to a PR.
Target:
Use when the user asks to scan a PR or when the request names a PR number or URL.
Resolve the PR from:
gh pr viewThen get the changed files:
gh pr diff <number> --name-only
Only keep files that still exist in the working tree. Scan just those files.
If the PR has no scannable files, report that clearly and stop.
if command -v semgrep >/dev/null 2>&1; then
ENGINE_LABEL="Semgrep OSS (host CLI)"
SEMGREP_CMD=(semgrep)
elif command -v uvx >/dev/null 2>&1; then
ENGINE_LABEL="Semgrep OSS (uvx)"
SEMGREP_CMD=(uvx --from semgrep semgrep)
elif command -v uv >/dev/null 2>&1; then
ENGINE_LABEL="Semgrep OSS (uv tool run)"
SEMGREP_CMD=(uv tool run --from semgrep semgrep)
else
echo "ERROR: neither semgrep, uvx, nor uv is available."
exit 1
fi
SEMGREP_EXCLUDE=(
--exclude tests/
--exclude docs/
--exclude features/
--exclude .agents/
)
"${SEMGREP_CMD[@]}" --version
If the version check fails, apply the Runtime note above before treating the scan as failed.
Check whether the user explicitly asked to keep artifacts before emitting the script below.
If NOT keeping artifacts:
OUTPUT_DIR="$(mktemp -d "${TMPDIR:-/tmp}/kedro-security-review.XXXXXX")"
cleanup() {
rm -rf "$OUTPUT_DIR"
}
trap cleanup EXIT
mkdir -p "$OUTPUT_DIR/raw"
If keeping artifacts (omit the trap entirely):
OUTPUT_DIR="$(mktemp -d "${TMPDIR:-/tmp}/kedro-security-review.XXXXXX")"
mkdir -p "$OUTPUT_DIR/raw"
In that case, report $OUTPUT_DIR at the end of the scan so the user can
inspect it.
For full codebase mode:
SCAN_TARGETS=(.)
TARGET_LABEL="full codebase"
For PR mode:
PR_NUMBER="<resolved-pr-number>"
# Apply the same path exclusions as full-codebase mode.
# Semgrep's --exclude only filters during directory walk, so explicit file
# arguments would otherwise bypass the exclusion list (e.g. tests/foo.py).
EXCLUDE_PREFIXES=(tests/ docs/ features/ .agents/)
SCAN_TARGETS=()
while IFS= read -r path; do
[ -f "$path" ] || continue
skip=0
for prefix in "${EXCLUDE_PREFIXES[@]}"; do
[[ "$path" == "$prefix"* ]] && skip=1 && break
done
(( skip == 0 )) && SCAN_TARGETS+=("$path")
done < <(gh pr diff "$PR_NUMBER" --name-only)
TARGET_LABEL="PR #$PR_NUMBER"
If SCAN_TARGETS is empty, stop and report that there are no scannable files
(this also happens when a PR only touches excluded paths like tests/ or
docs/).
Set:
LOCAL_RULESET="$(pwd)/.agents/skills/kedro-security-review/rules/kedro-security-patterns.yml"
Run these in parallel (each command includes "${SEMGREP_EXCLUDE[@]}"):
(
"${SEMGREP_CMD[@]}" scan --metrics=off \
"${SEMGREP_EXCLUDE[@]}" \
--config p/security-audit \
--json --output "$OUTPUT_DIR/raw/security-audit.json" \
"${SCAN_TARGETS[@]}"
) &
(
"${SEMGREP_CMD[@]}" scan --metrics=off \
"${SEMGREP_EXCLUDE[@]}" \
--config p/secrets \
--json --output "$OUTPUT_DIR/raw/secrets.json" \
"${SCAN_TARGETS[@]}"
) &
(
"${SEMGREP_CMD[@]}" scan --metrics=off \
"${SEMGREP_EXCLUDE[@]}" \
--include="*.py" --config p/python \
--json --output "$OUTPUT_DIR/raw/python.json" \
"${SCAN_TARGETS[@]}"
) &
(
"${SEMGREP_CMD[@]}" scan --metrics=off \
"${SEMGREP_EXCLUDE[@]}" \
--include="*.py" \
--config "$LOCAL_RULESET" \
--json --output "$OUTPUT_DIR/raw/kedro-security-patterns.json" \
"${SCAN_TARGETS[@]}"
) &
wait
If one or more rulesets fail, continue with the findings from the rulesets that did succeed. Do not abort the full scan. In the final report, include a "Scan errors" section that lists each failed ruleset and its error message so the user knows the scan was partial.
If a scan command fails, apply the Runtime note before marking that ruleset as failed.
Read all JSON files in $OUTPUT_DIR/raw/ directly. Deduplicate by
(check_id, path, start.line) — if the same finding appears in more than one
ruleset output, count it once.
For every unique finding:
reference.mdUse these buckets:
candidate_kedro_vulnerabilityproject_developer_responsibilitydeployment_or_environment_issuefalse_positive_or_informationalneeds_manual_reviewAfter triaging Semgrep output, run the Manual review checks from
reference.md against the scan target.
For each check:
candidate_kedro_vulnerability or needs_manual_reviewWhen all checks are clean, report them as a single line in the final report rather than enumerating each one. Only expand a check when it actually flagged something.
This step exists because Semgrep only catches known patterns. These checks catch the class of issues that static analysis misses.
Do not stream intermediate findings to the user.
Accumulate findings during triage, then produce exactly one final report using the format below.
If post mode was requested, write a single review JSON payload and post it via:
bash .agents/scripts/post_github_review.sh <review_json_file>
Delete the temporary review JSON file after posting.
Keep the report short and decisive. The classification summary already carries the counts — do not repeat non-actionable findings as prose.
Always include:
Only itemise actionable findings in the Findings section:
candidate_kedro_vulnerability, needs_manual_reviewproject_developer_responsibility
(this is the primary actionable bucket for the project owner — include file,
line, rule id, and suggested fix for each finding)Do not itemise findings in these buckets — they are reflected in the classification summary counts and that is sufficient:
false_positive_or_informationaldeployment_or_environment_issueproject_developer_responsibility when scope is Kedro frameworkIf the Findings section has nothing actionable, replace it with a single line that names the non-actionable counts (e.g. "None actionable. 2 false positives on pre-existing lines.").
For each actionable finding, include:
reference.md for that bucket; for candidate_kedro_vulnerability, pick the ERROR or WARNING recommendation based on Semgrep severity)If no findings are plausible Kedro vulnerabilities, say so explicitly.
Return one final report in this shape:
## Kedro Security Scan
> Generated with `kedro-security-review`.
### Overview
- **Mode:** <full codebase | PR>
- **Scope:** <Kedro framework | Kedro project>
- **Target:** <repo root | PR #123>
- **Findings reviewed:** <count>
- **Highest Semgrep severities:** <list or "none">
### Classification summary
- **candidate_kedro_vulnerability:** <count>
- **needs_manual_review:** <count>
- **project_developer_responsibility:** <count>
- **deployment_or_environment_issue:** <count>
- **false_positive_or_informational:** <count>
### Findings
<For each actionable finding (candidate_kedro_vulnerability, needs_manual_review):>
- `path/to/file.py:L42` — `<classification>` — <rule id> — <reason> — <next step>
<If nothing actionable, replace the list with a single line, e.g.:>
None actionable. <count> false positives on pre-existing lines.
### Manual review checks
<If all clean, one line:>
All clean (config-dict consumers, env-var paths, path construction, security suppression comments, subprocess/eval/exec/pickle/yaml/dynamic import).
<Otherwise, only list the checks that flagged something, with reasoning.>
### Conclusion
- <short conclusion, or "No plausible Kedro vulnerabilities found.">
Write one GitHub review payload:
{
"event": "COMMENT",
"body": "## Kedro Security Scan\n...(final summary report)...",
"comments": [
{
"path": "file.py",
"line": 42,
"side": "RIGHT",
"body": "**candidate_kedro_vulnerability:** <reason>\n\nRule: `<rule id>`\nSeverity: `<severity>`\nNext step: <next step>"
}
]
}
Use inline comments only for actionable findings tied to changed PR lines:
candidate_kedro_vulnerability, needs_manual_reviewproject_developer_responsibilityDo not post inline comments for false_positive_or_informational,
deployment_or_environment_issue, or project_developer_responsibility when
scope is Kedro framework. Put the full summary in body, following the
same conciseness rules as chat mode (counts only for non-actionable buckets;
collapse clean manual review checks to one line).