name: Process Community Advisory on: issues: types: [labeled] permissions: read-all concurrency: group: community-advisory cancel-in-progress: false env: FEED_PATH: advisories/feed.json FEED_SIG_PATH: advisories/feed.json.sig SKILL_FEED_PATH: skills/clawsec-feed/advisories/feed.json SKILL_FEED_SIG_PATH: skills/clawsec-feed/advisories/feed.json.sig jobs: process-advisory: if: github.event.label.name == 'advisory-approved' runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: fetch-depth: 1 - name: Parse issue and create advisory id: parse env: ISSUE_BODY: ${{ github.event.issue.body }} ISSUE_NUMBER: ${{ github.event.issue.number }} ISSUE_URL: ${{ github.event.issue.html_url }} ISSUE_TITLE: ${{ github.event.issue.title }} ISSUE_CREATED_AT: ${{ github.event.issue.created_at }} run: | # Generate advisory ID: CLAW-YYYY-{issue_number padded to 4 digits} # Use issue creation year, not current year, to ensure consistency YEAR=$(echo "$ISSUE_CREATED_AT" | cut -c1-4) PADDED_NUM=$(printf "%04d" "$ISSUE_NUMBER") ADVISORY_ID="CLAW-${YEAR}-${PADDED_NUM}" echo "advisory_id=$ADVISORY_ID" >> $GITHUB_OUTPUT echo "Generated advisory ID: $ADVISORY_ID" # Check if advisory already exists by issue URL (dedupe by issue, not by ID) # This prevents duplicates when the same issue is labeled in different years if jq -e --arg url "$ISSUE_URL" '.advisories[] | select(.github_issue_url == $url)' "$FEED_PATH" > /dev/null 2>&1; then echo "Advisory for issue $ISSUE_URL already exists in feed" echo "already_exists=true" >> $GITHUB_OUTPUT exit 0 fi echo "already_exists=false" >> $GITHUB_OUTPUT # Parse opener type (human vs agent) if echo "$ISSUE_BODY" | grep -q '\[x\] Agent'; then OPENER_TYPE="agent" else OPENER_TYPE="human" fi echo "Opener type: $OPENER_TYPE" # Parse report type if echo "$ISSUE_BODY" | grep -q '\[x\] Malicious Prompt'; then REPORT_TYPE="prompt_injection" elif echo "$ISSUE_BODY" | grep -q '\[x\] Vulnerable Skill'; then REPORT_TYPE="vulnerable_skill" elif echo "$ISSUE_BODY" | grep -q '\[x\] Tampering Attempt'; then REPORT_TYPE="tampering_attempt" else REPORT_TYPE="unknown" fi echo "Report type: $REPORT_TYPE" # Parse severity if echo "$ISSUE_BODY" | grep -q '\[x\] Critical'; then SEVERITY="critical" elif echo "$ISSUE_BODY" | grep -q '\[x\] High'; then SEVERITY="high" elif echo "$ISSUE_BODY" | grep -q '\[x\] Medium'; then SEVERITY="medium" elif echo "$ISSUE_BODY" | grep -q '\[x\] Low'; then SEVERITY="low" else SEVERITY="medium" fi echo "Severity: $SEVERITY" # Parse title (between ## Title and ## Description) TITLE=$(echo "$ISSUE_BODY" | sed -n '/^## Title/,/^## Description/p' | grep -v '^## ' | grep -v '^