valory-xyz/open-autonomy/triage-security

Claude Code and agent skill by valory-xyz/open-autonomy

Trust tier 2
  • community
LLM review pending
Source check pending

Checking that the SKILL.md file is still in the repository.

Triage open security alerts on the current GitHub repo — both Dependabot (dependency CVEs) and Code Scanning (CodeQL / SnykCode / other tools that emit to GitHub's code-scanning API). For each alert, decide whether the bug's threat model is actually exploitable given this codebase's archetype, calling code, and reachability. Applicable findings get a tracking issue opened; not-applicable findings get dismissed with the appropriate per-source reason (`inaccurate` / `not_used` for Dependabot; `false positive` / `used in tests` for Code Scanning). Repo-agnostic — works across the Valory fleet.

Install

npx vskill@latest install valory-xyz/open-autonomy/triage-security

SKILL.md

Triage security alerts (Dependabot + Code Scanning)

Walk every open security alert on the current repo from both Dependabot (/repos/{r}/dependabot/alerts) and Code Scanning (/repos/{r}/code-scanning/alerts). For each alert, classify by whether it is reachable from production code and then whether the bug's threat model preconditions are satisfied by this codebase's actual usage. Then act in one pass:

SourceClassificationConfidence + extrasAction
DependabotProduction-reachable AND exploit-applicableanyOpen tracking issue, leave Dependabot alert open.
DependabotProduction-reachable but exploit NOT applicable — cli-toolhighDismiss with inaccurate (+ audit issue per §3.1c).
DependabotProduction-reachable but exploit NOT applicable — framework / scaffold + §2.5.6b passeshighDismiss with inaccurate (+ audit issue).
DependabotProduction-reachable but exploit NOT applicable — moderate/low conf OR framework + §2.5.6b fails—Open issue + needs-human-review. Do NOT dismiss.
DependabotTest / dev / CI-only import pathn/aDismiss with not_used (+ audit issue).
Code ScanningRule matches RULE_HUMAN_REVIEW_PATTERNS (cert/TLS bypass, injection in prod, hardcoded secrets non-test, auth/authz, RCE/deserialization, path traversal)anyOpen issue + needs-human-review. Never auto-dismiss this rule class.
Code ScanningApplicable — flagged code is reachable from prod entry point AND §2.5 preconditions holdanyOpen tracking issue, leave code-scanning alert open.
Code ScanningNOT applicable (false positive) — cli-tool + §2.5 ruled preconditions absenthighDismiss with false positive (+ audit issue).
Code ScanningNOT applicable — framework/service archetype OR moderate/low confidence—Open issue + needs-human-review. Do NOT dismiss.
Code ScanningFlagged file is under tests/ / PKG_TEST_DIRSn/aDismiss with used in tests (+ audit issue).
Either sourceUnclassifiablen/aSkip. stderr line for manual review. Never auto-dismiss without evidence.

Conservative defaults: when uncertain, open the issue. A false-positive issue is cheap to close; a false-negative dismissal hides a real vulnerability. `won't fix` (code-scanning) and `tolerable_risk` (Dependabot) are never set by the skill — those are maintainer-only risk-accept calls.

Three paths to autonomous dismissal:

  1. Dependabot: cli-tool + high confidence + preconditions absent → inaccurate
  2. Dependabot: framework/scaffold + high confidence + §2.5.6b structural-impossibility passes → inaccurate
  3. Dependabot: test/dev-only import path (Signal C) → not_used
  4. Code-scanning: file under tests/ → used in tests
  5. Code-scanning: cli-tool + high confidence + §2.5 preconditions absent + rule NOT in RULE_HUMAN_REVIEW_PATTERNS → false positive

Every dismissal produces a closed audit-trail issue (§3.1c) labelled security-audit. The 280-char dismissed_comment carries a one-line summary + audit-issue URL pointer.

This skill runs fully autonomously on invocation — it mutates GitHub state (dismisses alerts, opens issues). Do not invoke from conversational context; require explicit /triage-security.


Phase 0 — Ground truth

bash
# 0. Platform check. The skill targets Linux + macOS bash; runs untested on
# Git Bash / MSYS / Cygwin. Native PowerShell / cmd.exe is not supported
# (the skill uses heredocs, process substitution, array expansion).
case "$(uname -s 2>/dev/null)" in
Linux*|Darwin*) ;; # supported
MINGW*|MSYS*|CYGWIN*)
echo "WARN: running under $(uname -s) — Git Bash / MSYS path is untested. Most operations should work; report any failures." >&2
;;
*)
echo "WARN: unrecognized platform $(uname -s). Skill is bash-only and may fail on this OS." >&2
;;
esac
# Required CLIs — fail fast if anything is missing so the operator gets a clear
# message instead of a cryptic mid-loop error 40 minutes in.
for cmd in gh jq python3 grep find sed tr printf mktemp; do
command -v "$cmd" >/dev/null 2>&1 \
|| { echo "ERROR: required CLI not found on PATH: $cmd"; exit 1; }
done
# 1. Confirm we're in a git repo with a GitHub remote
gh repo view --json owner,name --jq '"\(.owner.login)/\(.name)"' > /tmp/td_repo.txt 2>/dev/null \
|| { echo "ERROR: not in a GitHub repo (gh repo view failed)"; exit 1; }
REPO=$(cat /tmp/td_repo.txt)
echo "operating on $REPO"
# 2. Confirm alert APIs are reachable. Each is OPTIONAL — the skill can run
# against either source, or both. Source selection happens in Phase 1.
# Track availability so Phase 1 can fetch only what's actually enabled.
DEPENDABOT_AVAILABLE="no"
CODESCAN_AVAILABLE="no"
# Differentiate "feature disabled" (404) from "token missing scope" (401/403).
# `> /dev/null 2>&1` collapses both into "unavailable" and silently skips
# every alert when the real cause is a permissions failure. Capture stderr
# and fail loudly on auth errors so the operator gets an actionable message
# instead of a clean Phase 4 "0 alerts processed" that masks a broken run.
_check_alerts_api() {
local label="$1" url="$2" err
if err=$(gh api "$url" --jq 'length' 2>&1 >/dev/null); then
return 0
fi
# Auth/scope failures look like `HTTP 401`, `HTTP 403`, `Bad credentials`,
# or mention `scope` / `requires authentication`. Anything else (most
# commonly `HTTP 404` for a disabled feature) is treated as not-enabled.
if printf '%s' "$err" | grep -qiE 'HTTP 40[13]|Bad credentials|requires authentication|missing.*scope|needs the .*scope'; then
echo "ERROR: gh token lacks required scope for $label alerts on $REPO." >&2
echo " Run: gh auth refresh -h github.com -s security_events" >&2
echo " Underlying error: $err" >&2
exit 1
fi
echo "WARN: $label alerts API unreachable on $REPO (feature likely not enabled) — $label path will be skipped" >&2
return 1
}
_check_alerts_api "Dependabot" "repos/$REPO/dependabot/alerts?per_page=1" && DEPENDABOT_AVAILABLE="yes"
_check_alerts_api "code-scanning" "repos/$REPO/code-scanning/alerts?per_page=1" && CODESCAN_AVAILABLE="yes"
[[ "$DEPENDABOT_AVAILABLE" == "no" && "$CODESCAN_AVAILABLE" == "no" ]] \
&& { echo "ERROR: neither Dependabot nor code-scanning is enabled on $REPO. Nothing to triage."; exit 1; }
# 3. Confirm a Python project layout exists (this skill currently keys off Python ecosystems)
test -f pyproject.toml \
|| { echo "ERROR: no pyproject.toml — skill only supports Python repos right now"; exit 1; }
# 4. Pin the skill version into audit issue bodies. This is a hardcoded date
# string, NOT a runtime git-rev-parse: Claude Code executes the skill via
# per-call `bash -c` invocations, so `BASH_SOURCE[0]` is empty, `$0` is
# `bash`, and any `realpath`+`git -C` chain resolves against the AUDITED
# repo's cwd — yielding the audited repo's HEAD, not the skill's. That's
# worse than `unknown` (looks authoritative, points at the wrong tree).
# Bump this string when the skill itself is updated.
SKILL_VERSION="2026-05-14"
export SKILL_VERSION
0.2 RULE_HUMAN_REVIEW_PATTERNS — code-scanning rule classes that NEVER auto-dismiss

For code-scanning alerts (Phase 2-cs), some bug classes carry asymmetric risk: a false-positive dismissal of a real vulnerability is catastrophic, while a false-positive issue is cheap to close. For these classes the skill bypasses §2.5 and routes directly to a needs-human-review issue — regardless of how clean the confidence-tier analysis looks.

Pattern-match each alert's rule.id (and rule.tags for CWE-based matching) against this list. Match → force needs-human-review.

bash
# Glob patterns matched case-insensitively against alert.rule.id.
# Add patterns here based on observed false-positive cost vs the
# blast radius of a real miss. Tested against actual SnykCode + CodeQL
# rule IDs seen on the Valory fleet.
RULE_HUMAN_REVIEW_PATTERNS=(
# Cert / TLS verification bypass — bypass of HTTPS trust path
"*disabled-certificate-check*"
"*SSLVerificationBypass*"
"*TooPermissiveTrustManager*"
"*MissingCertVerification*"
"*InsecureProtocol*"
# Injection — SQL, XSS, command, XML — when fired on prod code
"*SQLInjection*"
"*XSS*"
"*CommandInjection*"
"*ShellInjection*"
"*InsecureXmlParser*"
"*XmlInjection*"
"*LdapInjection*"
"*TaintedFormatString*"
# Hardcoded secrets in NON-test code. The /test variants of these
# rules are auto-dismissable as `used in tests`; the bare names are not.
"*HardcodedPassword"
"*HardcodedCredential*"
"*HardcodedNonCryptoSecret"
"*HardcodedKey"
"*EmbeddedCredentials*"
# Auth / authz — can't statically prove "middleware X handles this"
"*MissingAuth*"
"*WeakAuthorization*"
"*BrokenAccessControl*"
"*authentication*"
"*authorization*"
# Deserialization / RCE — highest blast radius
"*UnsafeDeserialization*"
"*UnsafePickle*"
"*PickleLoad*"
"*UnsafeYaml*"
"*CodeInjection*"
"*EvalUsage*"
"*UnsafeReflection*"
# Path traversal — too easy to misjudge input-sourcing
"*PathTraversal*"
"*TaintedPath*"
"*ZipSlip*"
)
# Helper: does the alert's rule.id match any pattern? (Phase 2-cs uses this.)
matches_human_review_pattern() {
local rule_id="$1"
local rid_lower pat_lower
# Lower-case both sides for case-insensitive match. `${var,,}` would be
# shorter but is bash 4+ only; macOS ships `/bin/bash` 3.2 (this file
# is explicitly bash-3.2-compat — see §2.1 `while read` note and the
# reference loop's `mapfile` callout). Using `tr` keeps the safety
# guard active on the default macOS shell instead of silently
# disabling it (otherwise the function errors → forced-review never
# fires for high-stakes rule classes like SQLi / RCE / path-traversal).
rid_lower=$(printf '%s' "$rule_id" | tr '[:upper:]' '[:lower:]')
for pat in "${RULE_HUMAN_REVIEW_PATTERNS[@]}"; do
pat_lower=$(printf '%s' "$pat" | tr '[:upper:]' '[:lower:]')
# Bash glob match; `*foo*` matches "foo" anywhere in rule_id
# shellcheck disable=SC2053
[[ "$rid_lower" == $pat_lower ]] && return 0
done
return 1
}

The list is deliberately conservative on injection / RCE / auth — false-positive issues on *PathTraversal* are cheap; false-negative dismissals of a real one are expensive. Refine over time based on the actual false-positive rate observed in dismissed audit issues.

The skill does NOT match rule IDs with a /test suffix (e.g. python/NoHardcodedPasswords/test) against these patterns — those are tool-vendor-tagged test variants and are handled by the file-path-in-tests/ check in Phase 2-cs. Pattern matching applies to the bare (non-/test) rule IDs.

Capture into working memory:

FieldSource
REPO<owner>/<name> from gh repo view
PROD_PATHSDefault: autonomy/ packages/ agent/ — adjust to repo. See Phase 2.1 for repo-specific overrides.
TEST_PATHSDefault: tests/ scripts/ .github/ plus every **/tests/ subdir under packages/.
LIMITOptional --limit N arg; otherwise process all open alerts.
ARCHETYPERepo archetype (see §0.1). Drives the exploit-surface threshold in Phase 2.5.
0.1 Repo archetype

Different archetypes have radically different exploit surfaces for the same CVE. A header-leak CVE in urllib3 matters for an internet-facing web service handling user auth tokens; it doesn't matter for a CLI link checker that holds no auth state. The skill needs this distinction baked into Phase 2.5's reasoning, not bolted on after the fact.

Classify the current repo into one of:

This is the start of the file. Read the full SKILL.md on GitHub.

Security

  • Security scanPassed, 100 of 100Pattern checks on the skill's files.
  • Model reviewNot runA model review is scheduled for the next rescan.

Quality evaluation

  • Task evaluationNot runNo evaluation yet. Run one in Skill Studio.

Source

Popularity

Repository stars
122
Repository forks
47
7-day trend score
24

Stars and forks are for the whole GitHub repository, not this skill alone. Not refreshed yet.

Works with

Any agent vskill installs to: 56 targets in all. These 39 have a page on this site.

  • Claude Code
  • Cursor
  • GitHub Copilot
  • Windsurf
  • Codex
  • Gemini CLI
  • Cline
  • Amp
  • Roo Code
  • Goose
  • Continue
  • Kilo Code
  • Junie
  • Trae
  • OpenHands
  • Qwen Code
  • AI Agent
  • Tabnine Chat
  • Sourcegraph Cody
  • Amazon Q
  • Firebase Genkit
  • Sweep
  • Devin
  • Phind
  • Mentat
  • Claude Desktop
  • Aider
  • GPT Pilot
  • Plandex
  • bolt.new
  • v0
  • Replit Agent
  • Anse
  • TypingMind
  • BetterChatGPT
  • LibreChat
  • Warp AI
  • Pieces
  • Fig AI
Embed badge
vskill VERIFIED badge
[![vskill VERIFIED](https://verified-skill.com/api/v1/skills/valory-xyz/open-autonomy/triage-security/badge)](https://verified-skill.com/skills/valory-xyz/open-autonomy/triage-security)

Something wrong with this skill or its page? Tell us.