mirror of
https://github.com/cesanta/mongoose.git
synced 2026-10-21 11:30:01 +00:00
128 lines
3.9 KiB
YAML
128 lines
3.9 KiB
YAML
name: Claude Full Codebase Security Scan
|
|
|
|
on:
|
|
workflow_dispatch:
|
|
inputs:
|
|
prompt_path:
|
|
description: "Path to the repo prompt file Claude should read"
|
|
required: true
|
|
default: "resources/specs/claude-security-scan.md"
|
|
target_ref:
|
|
description: "Branch, tag, or SHA to scan"
|
|
required: false
|
|
default: ""
|
|
#schedule:
|
|
# Weekly scan: Sunday 02:00 UTC
|
|
# - cron: "0 2 * * 0"
|
|
|
|
permissions:
|
|
contents: read
|
|
id-token: write
|
|
|
|
concurrency:
|
|
group: claude-full-codebase-security-scan-${{ github.ref }}
|
|
cancel-in-progress: false
|
|
|
|
jobs:
|
|
scan:
|
|
name: Full codebase security scan
|
|
runs-on: ubuntu-latest
|
|
timeout-minutes: 90
|
|
|
|
env:
|
|
DEFAULT_PROMPT_PATH: "resources/specs/claude-security-scan.md"
|
|
|
|
steps:
|
|
- name: Resolve scan inputs
|
|
id: vars
|
|
shell: bash
|
|
run: |
|
|
if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
|
|
PROMPT_PATH="${{ inputs.prompt_path }}"
|
|
TARGET_REF="${{ inputs.target_ref }}"
|
|
else
|
|
PROMPT_PATH="${DEFAULT_PROMPT_PATH}"
|
|
TARGET_REF=""
|
|
fi
|
|
|
|
if [ -z "$TARGET_REF" ]; then
|
|
TARGET_REF="${{ github.ref }}"
|
|
fi
|
|
|
|
echo "prompt_path=$PROMPT_PATH" >> "$GITHUB_OUTPUT"
|
|
echo "target_ref=$TARGET_REF" >> "$GITHUB_OUTPUT"
|
|
|
|
- name: Checkout repository
|
|
uses: actions/checkout@v6
|
|
with:
|
|
ref: ${{ steps.vars.outputs.target_ref }}
|
|
fetch-depth: 0
|
|
|
|
- name: Verify prompt file exists
|
|
shell: bash
|
|
run: |
|
|
test -f "${{ steps.vars.outputs.prompt_path }}" || {
|
|
echo "Prompt file not found: ${{ steps.vars.outputs.prompt_path }}"
|
|
exit 1
|
|
}
|
|
|
|
- name: Run Claude full codebase security scan
|
|
id: claude_scan
|
|
uses: anthropics/claude-code-action@v1
|
|
with:
|
|
anthropic_api_key: ${{ secrets.CLAUDE_API_KEY }}
|
|
|
|
prompt: |
|
|
REPO: ${{ github.repository }}
|
|
REF: ${{ steps.vars.outputs.target_ref }}
|
|
PROMPT_FILE: ${{ steps.vars.outputs.prompt_path }}
|
|
|
|
You are running a full-codebase security scan in GitHub Actions.
|
|
|
|
First, read the prompt file at:
|
|
${{ steps.vars.outputs.prompt_path }}
|
|
|
|
Treat that file as the authoritative security-review instruction set.
|
|
|
|
Scan the checked-out repository as a whole codebase.
|
|
Do not modify files.
|
|
Do not create commits.
|
|
Do not open pull requests.
|
|
Do not post GitHub comments.
|
|
Do not create GitHub issues.
|
|
|
|
claude_args: |
|
|
--max-turns 20
|
|
--allowedTools "Read,Glob,Grep,Bash(git:*),Bash(find:*),Bash(grep:*),Bash(sed:*),Bash(cat:*)"
|
|
--model claude-opus-4-8
|
|
|
|
- name: Upload Claude scan execution output
|
|
if: always() && steps.claude_scan.outputs.execution_file != ''
|
|
uses: actions/upload-artifact@v4
|
|
with:
|
|
name: claude-full-codebase-security-scan-${{ github.run_id }}
|
|
path: ${{ steps.claude_scan.outputs.execution_file }}
|
|
if-no-files-found: warn
|
|
retention-days: 30
|
|
|
|
- name: Extract JSON findings from Claude output
|
|
if: always() && steps.claude_scan.outputs.execution_file != ''
|
|
shell: bash
|
|
run: |
|
|
jq -r '
|
|
.[]
|
|
| select(.type == "result")
|
|
| .result
|
|
| sub("^[^{]*"; "")
|
|
' "${{ steps.claude_scan.outputs.execution_file }}" | jq . > security-findings.json
|
|
|
|
jq -e '.findings and .analysis_summary' security-findings.json > /dev/null
|
|
|
|
- name: Upload extracted JSON findings
|
|
if: always() && hashFiles('security-findings.json') != ''
|
|
uses: actions/upload-artifact@v4
|
|
with:
|
|
name: security-findings-${{ github.run_id }}
|
|
path: security-findings.json
|
|
if-no-files-found: error
|
|
retention-days: 30 |