Agent Skills › turbot/steampipe › soc2-remediation

soc2-remediation

GitHub

自动化SOC2漏洞修复流程,同步Vanta快照与Dependabot告警,分类并处理可合并、需手动修复或无法修复的漏洞,生成修复计划。

.claude/skills/soc2-remediation/SKILL.md turbot/steampipe

Trigger Scenarios

提及Vanta CVE修复 Dependabot安全告警 漏洞SLA 每周SOC2运行

Install

npx skills add turbot/steampipe --skill soc2-remediation -g -y
More Options

Non-standard path

npx skills add https://github.com/turbot/steampipe/tree/develop/.claude/skills/soc2-remediation -g -y

Use without installing

npx skills use turbot/steampipe@soc2-remediation

指定 Agent (Claude Code)

npx skills add turbot/steampipe --skill soc2-remediation -a claude-code -g -y

安装 repo 全部 skill

npx skills add turbot/steampipe --all -g -y

预览 repo 内 skill

npx skills add turbot/steampipe --list

SKILL.md

Frontmatter
{
    "name": "soc2-remediation",
    "description": "Weekly SOC2 vulnerability remediation for one or more pipeling repos (default: the current repo). Pulls the Vanta findings snapshot from turbot\/soc2, reconciles it with Dependabot, classifies each finding as mergeable \/ manual fix \/ no-fix, remediates what has a fix, and prepares snoozes for what does not. Use whenever the operator mentions Vanta, CVE remediation, Dependabot security alerts, vulnerability SLAs, or the weekly SOC2 run."
}

SOC2 vulnerability remediation

Read-only toward Vanta. Present the plan (see Output) and let the operator choose what to fix before any merge or bump; confirm each merge. The operator runs the snooze batch.

Snapshot

gh api -H "Accept: application/vnd.github.raw" \
  repos/turbot/soc2/contents/monitoring/state/vulnerability-state.json > /tmp/vuln-state.json

Top level: lastUpdated, vulnerabilities[] and nowFixableSnoozedItems[] (snoozed findings that now have a fix — treat them as open). Each row has id (Vanta's id), externalId (CVE/GHSA), severity, status (OVERDUE / DUE_SOON / OK / NO_SLA), remediateByDate (null when no SLA), packageName (ecosystem prefix + vulnerable range, e.g. `go-go.opentelemetry.io/otel/sdk

= 1.5.0, <= 1.44.0— strip the ecosystem prefix to match Dependabot),isFixable, repo, integration. One CVE can have several rows (one per affected package or path). The snapshot is weekly and lags Dependabot — state its lastUpdated` date.

Default scope is the current repo (gh repo view --json name -q .name); accept a list of repos as an argument instead. Filter and sort by SLA:

jq -r --arg repo steampipe '
  (.vulnerabilities + .nowFixableSnoozedItems) | map(select(.repo == $repo))
  | sort_by(.remediateByDate // "9999") | .[]
  | "\(.status)\t\((.remediateByDate // "none")[:10])\t\(.severity)\t\(.externalId)\t\(.packageName)"
' /tmp/vuln-state.json

Reconcile

Always union with the live Dependabot alerts:

gh api repos/turbot/<repo>/dependabot/alerts --paginate \
  --jq '.[]|select(.state=="open")|"\(.security_advisory.severity) \(.dependency.package.name) \(.security_vulnerability.vulnerable_version_range) fix=\(.security_vulnerability.first_patched_version.identifier // "none")"' | sort -u
gh pr list --repo turbot/<repo> --author app/dependabot --state open --limit 60 \
  --json number,title,baseRefName -q '.[] | "#\(.number) \(.baseRefName) \(.title)"'

Anything GitHub shows that the snapshot doesn't still needs fixing; it just can't be snoozed until Vanta's next scan creates a row for it. Map each finding to its PR by package name and the fix version implied by the range.

Classify

  • A — has a PR. An open Dependabot PR fixes it.
  • B — no PR, but a fix exists. Typically a nested transitive dependency. Not a snooze.
  • C — no fix. No installable fixed version exists for the module in use. A row with isFixable: true, or an alert with a fix= version, is never C.

Before calling C, check two traps: a renamed module (the fix may live under a different import path the same project publishes), and a range with no lower bound (e.g. <= 5.0.7 includes every older major, so a same-major pin can't clear it).

Remediate

Use --repo turbot/<r> on every gh pr command; the PR number alone resolves against the current checkout.

Bucket A: gh pr comment <n> --repo turbot/<r> --body "@dependabot rebase", then once CI is green (gh pr checks <n> --repo turbot/<r>): gh pr review <n> --repo turbot/<r> --approve and gh pr merge <n> --repo turbot/<r> --squash --delete-branch.

Bucket B: manual bump on a branch off develop — Dependabot and Vanta read the default branch, so only a fix on develop clears the finding. Go: go get <module>@<version> then go mod tidy. npm: bump the parent, or pin via resolutions/overrides within the current major, then yarn install and yarn why <pkg>. Ask the operator before any major-version bump. PR title names package, version and advisory, e.g. Bump github.com/jackc/pgx/v5 to v5.9.2 (CVE-2026-41889).

If the fix must also ship in a release (gh release list --repo turbot/<r> --limit 1, release branch = patch replaced by x), open a second PR into that branch titled Backport: <title>. Redo the bump there with go get rather than cherry-picking; go.mod usually differs.

After any bump, build and test before opening the PR: go build ./... and go test ./... (plus yarn build in the UI directory when the repo has one). Report failures before proceeding. Manual PRs go under the operator's own gh auth and need a teammate's approval.

Verify

A merged bump is not proof the finding cleared.

npm, only in a repo with a yarn.lock (not every repo has a ui/): the lockfile must hold exactly one resolved version — grep -A1 '"<pkg>@npm' yarn.lock | grep version | sort -u. Two lines means a peer dependency or unused package still pins the old copy.

For every finding: re-run the Dependabot alert query and confirm the open count dropped. For integration: github rows, merging to develop clears the finding with no release. Findings against a published image (e.g. the Pipes workspace image) clear only once a release carrying the bump ships.

Snooze

For bucket C, write a short paste-ready justification: why no fix exists, and why it's safe to wait (not reachable / EOL). Snoozes are per snapshot row, so cover every id for the CVE. For 3 or more rows, write a batch file of {id, reason, until, autoReopen} — id is Vanta's id, not the CVE; until is ISO 8601. Dry-run it from turbot/soc2/monitoring:

npm run auto-snooze -- --dry-run --batch <path>.json

The dry run accepts unknown ids, so check each against the snapshot. The operator runs the real write (SNOOZE_INVOKED_BY=<their name> npm run auto-snooze -- --batch <path>.json; single row: --id <id> --reason <text> --until <ISO>) with VANTA_CLIENT_ID / VANTA_CLIENT_SECRET, which only they hold; this skill never runs it. Recommend a reactivation date ~90 days out with auto-reopen-on-fix enabled; not indefinite, not short.

Output

A plan sorted by SLA due date (nearest first), for the operator to choose from:

  1. Merges — per repo, PR number, what it fixes, who approves.
  2. Manual gaps — package, repo, the fixed version, the bump needed, whether a backport is needed.
  3. Snoozes — the finding, its row ids, the justification, the reactivation date.

Lead with whatever is due within the week; note the rest as having runway.

Version History

  • 103201b Current 2026-10-19 06:53

Same Skill Collection

.claude/skills/release/SKILL.md

Metadata

Files
0
Version
103201b
Hash
8236a8be
Indexed
2026-10-19 06:53

inicio - Wiki
Copyright © 2011-2026 iteam. Current version is 2.155.2. UTC+08:00, 2026-10-24 18:59
浙ICP备14020137号-1