Skip to content

[CRITICAL] fix(security): scope legacy-key cleanup to authenticated user's own keys #8

[CRITICAL] fix(security): scope legacy-key cleanup to authenticated user's own keys

[CRITICAL] fix(security): scope legacy-key cleanup to authenticated user's own keys #8

Workflow file for this run

# Managed by sh1pt Actions Fleet
# pack: vu1nz-scan@1.0.0
# install: sh1pt-actions-store
# hash: sha256:a5f27998f1a6ddd9e2ff263724a5d4eb5887a306210d9c00591d9a918a7136ad
name: vu1nz security scan
on:
pull_request:
permissions:
contents: read
pull-requests: write
jobs:
review:
name: Review PR for security vulnerabilities
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: "3.12"
- name: Install vu1nz
run: pip install --quiet git+https://github.com/profullstack/vu1nz-gh-actions.git
- name: Load env file
env:
ENV_FILE: ${{ secrets.ENV_FILE }}
run: |
echo "$ENV_FILE" > "$RUNNER_TEMP/.env"
echo "Keys in ENV_FILE:"
grep -oP '^[A-Z_]+(?==)' "$RUNNER_TEMP/.env" || echo "(no keys found or different format)"
ANTHROPIC_API_KEY=$(grep -E '^ANTHROPIC_API_KEY=' "$RUNNER_TEMP/.env" | head -1 | sed 's/^ANTHROPIC_API_KEY=//')
if [ -n "$ANTHROPIC_API_KEY" ]; then
echo "::add-mask::$ANTHROPIC_API_KEY"
echo "ANTHROPIC_API_KEY=$ANTHROPIC_API_KEY" >> "$GITHUB_ENV"
echo "ANTHROPIC_API_KEY found and exported"
else
echo "::warning::ANTHROPIC_API_KEY not found in ENV_FILE"
fi
- name: Review PR
id: review
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
NO_COLOR: "1"
TERM: dumb
run: |
vu1nz review-pr main \
${{ github.repository }} \
${{ github.event.pull_request.number }} \
--token "$GITHUB_TOKEN" \
--json \
| tee "$RUNNER_TEMP/vu1nz-review-raw.txt" || true
python3 -c "
import json, re, sys
raw = open('$RUNNER_TEMP/vu1nz-review-raw.txt').read()
raw = re.sub(r'\x1b\[[0-9;]*m', '', raw)
start = raw.find('{')
if start >= 0:
obj, _ = json.JSONDecoder(strict=False).raw_decode(raw, start)
json.dump(obj, sys.stdout)
else:
print('{}')
" > "$RUNNER_TEMP/vu1nz-review.json"
- name: Build PR comment
id: comment
run: |
python3 << 'PYEOF'
import json, os, sys
review_file = os.environ.get("RUNNER_TEMP", "") + "/vu1nz-review.json"
comment_file = os.environ.get("RUNNER_TEMP", "") + "/vu1nz-comment.md"
try:
with open(review_file) as f:
data = json.loads(f.read(), strict=False)
except Exception as e:
print(f"::warning::Could not parse review results: {e}")
with open(comment_file, "w") as f:
f.write("## vu1nz Security Review\n\nCould not parse review results.\n")
sys.exit(0)
findings = data.get("findings", [])
analysis = data.get("analysis", "")
pr = data.get("pr_number", "?")
total = len(findings)
counts = {"critical": 0, "high": 0, "medium": 0, "low": 0}
for finding in findings:
sev = finding.get("severity", "").lower()
if sev in counts:
counts[sev] += 1
has_hc = counts["critical"] > 0 or counts["high"] > 0
lines = ["## vu1nz Security Review", ""]
lines.append(f"**{total}** finding(s) in PR #{pr}")
lines.append("")
badge_parts = []
for sev in ("critical", "high", "medium", "low"):
if counts[sev] > 0:
badge_parts.append(f"**{sev.upper()}**: {counts[sev]}")
if badge_parts:
lines.append(" | ".join(badge_parts))
lines.append("")
if has_hc:
lines.append("> **High or critical findings - review before merging.**")
lines.append("")
if findings:
lines.append("### Findings")
lines.append("")
lines.append("| Severity | File | Issue | Suggestion |")
lines.append("|----------|------|-------|------------|")
for f in findings:
sev = f.get("severity", "?").upper()
file = f.get("file", "N/A")
issue = f.get("issue", "").replace("\n", " ")[:150]
suggestion = f.get("suggestion", "").replace("\n", " ")[:150]
lines.append(f"| {sev} | `{file}` | {issue} | {suggestion} |")
lines.append("")
else:
lines.append("No security issues found.")
lines.append("")
if analysis:
lines.append("<details><summary>Full AI Analysis</summary>")
lines.append("")
lines.append(analysis)
lines.append("")
lines.append("</details>")
body = "\n".join(lines)
with open(comment_file, "w") as f:
f.write(body)
with open(os.environ.get("GITHUB_OUTPUT", ""), "a") as out:
out.write(f"total={total}\n")
out.write(f"has_high_critical={'true' if has_hc else 'false'}\n")
if has_hc:
print(f"::error::vu1nz found high/critical vulnerabilities in PR code")
sys.exit(1)
print(f"::notice::vu1nz review: {total} finding(s), no high/critical issues")
PYEOF
- name: Write report to job summary
if: always()
run: |
if [ -f "$RUNNER_TEMP/vu1nz-comment.md" ]; then
cat "$RUNNER_TEMP/vu1nz-comment.md" >> "$GITHUB_STEP_SUMMARY"
else
echo "## vu1nz Security Review" >> "$GITHUB_STEP_SUMMARY"
echo "" >> "$GITHUB_STEP_SUMMARY"
echo "Scan completed but could not read results." >> "$GITHUB_STEP_SUMMARY"
fi
- name: Comment on PR
if: always() && github.event.pull_request.head.repo.full_name == github.repository
uses: actions/github-script@v7
with:
script: |
const fs = require('fs');
const commentFile = `${process.env.RUNNER_TEMP}/vu1nz-comment.md`;
let body;
try {
body = fs.readFileSync(commentFile, 'utf8');
} catch {
body = '## vu1nz Security Review\n\nScan completed but could not read results.';
}
try {
const { data: comments } = await github.rest.issues.listComments({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
});
const existing = comments.find(c =>
c.user.type === 'Bot' && c.body.includes('vu1nz Security Review')
);
if (existing) {
await github.rest.issues.updateComment({
comment_id: existing.id,
owner: context.repo.owner,
repo: context.repo.repo,
body: body,
});
} else {
await github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: body,
});
}
} catch (err) {
if (err.status === 403) {
core.warning(`Cannot post PR comment (read-only token): ${err.message}. Findings are in the job summary.`);
} else {
throw err;
}
}