@@ -24,102 +24,92 @@ jobs:
2424 with :
2525 python-version : 3.x
2626
27- - name : Install Semgrep
28- run : pip install semgrep
29-
27+ - name : Install dependencies
28+ run : |
29+ pip install semgrep anthropic python-dotenv
30+
3031 - name : Run Semgrep scan (non-blocking)
3132 run : semgrep ci --config auto || true
32-
33+
3334 - name : Save Semgrep reports
3435 if : always()
3536 run : |
3637 semgrep --config auto --json > semgrep-report.json || echo '{"results":[]}' > semgrep-report.json
3738 semgrep --config auto --text > semgrep-report.txt || echo "No findings" > semgrep-report.txt
38-
39- - name : Install Claude CLI
40- if : always()
41- run : |
42- # Download and install Claude CLI
43- curl -fsSL https://cli.anthropic.com/install.sh | sh
44-
45- # Add to PATH for subsequent steps
46- echo "$HOME/.local/bin" >> $GITHUB_PATH
47-
48- # Verify installation
49- export PATH="$HOME/.local/bin:$PATH"
50- which claude || echo "Claude not found in PATH"
51- claude --version || echo "Claude command failed"
52-
39+
5340 - name : Verify Semgrep findings with Claude
5441 if : always()
5542 env :
5643 ANTHROPIC_API_KEY : ${{ secrets.ANTHROPIC_API_KEY }}
5744 run : |
58- # Ensure claude is in PATH
59- export PATH="$HOME/.local/bin:$PATH"
60-
61- # Create the prompt
62- cat > claude_prompt.txt <<'EOF'
63- You are a security code reviewer. I have a Semgrep scan report that I need you to verify.
64-
65- Your task:
66- 1. Read the semgrep-report.json file in the current directory
67- 2. For EACH finding in the report:
68- - Examine the specific file and line number mentioned
69- - Read the surrounding code context (at least 10 lines before and after)
70- - Analyze if the finding is a TRUE POSITIVE or FALSE POSITIVE
71- - Consider the actual code logic and data flow
72-
73- 3. Create a detailed report file named "claude-verification-report.md" with this structure:
74-
45+ # Create Python script for Claude verification
46+ cat > verify_findings.py <<'EOF'
47+ import os
48+ import json
49+ from anthropic import Anthropic
50+
51+ client = Anthropic(api_key=os.environ["ANTHROPIC_API_KEY"])
52+
53+ # Load Semgrep results
54+ with open("semgrep-report.json", "r") as f:
55+ semgrep_data = json.load(f)
56+
57+ findings = semgrep_data.get("results", [])
58+
59+ # Create prompt
60+ prompt = f"""You are a security code reviewer. I have {len(findings)} Semgrep findings to verify.
61+
62+ Here are the findings:
63+ {json.dumps(findings, indent=2)}
64+
65+ For each finding:
66+ 1. Examine the file and line number
67+ 2. Determine if it's a TRUE POSITIVE or FALSE POSITIVE
68+ 3. Consider code context and data flow
69+
70+ Create a detailed markdown report with:
71+
7572 # Semgrep Findings Verification Report
76-
73+
7774 ## Summary
78- - Total findings: [count]
75+ - Total findings: {len(findings)}
7976 - True positives: [count]
8077 - False positives: [count]
81- - High severity: [count]
82- - Medium severity: [count]
83- - Low severity: [count]
84-
78+
8579 ## Detailed Analysis
86-
87- ### Finding 1: [Rule ID]
88- - **File**: `path/to/file`
89- - **Line**: [line number]
90- - **Severity**: [HIGH/MEDIUM/LOW]
91- - **Semgrep Rule**: [rule name]
92- - **Semgrep Message**: [original message]
93- - **Verdict**: TRUE POSITIVE / FALSE POSITIVE
94-
95- **Code Context:**
96- ```
97- [relevant code snippet with line numbers]
98- ```
99-
100- **Analysis**:
101- [Your detailed explanation of why this is or isn't a real security issue]
102-
103- **Recommended Fix** (if true positive):
104- ```
105- [suggested secure code]
106- ```
107-
108- **Justification** (if false positive):
109- [Explain why this is not actually a security risk]
110-
111- ---
112-
113- [Repeat for each finding]
114-
115- ## Recommendations
116- [Overall security recommendations based on the findings]
117-
118- Please analyze all findings thoroughly by examining the actual repository code.
80+
81+ For each finding, provide:
82+ - File and line number
83+ - Severity
84+ - Verdict (TRUE POSITIVE / FALSE POSITIVE)
85+ - Analysis explaining your reasoning
86+ - Recommended fix (if true positive)
87+
88+ Please analyze thoroughly."""
89+
90+ # Call Claude
91+ message = client.messages.create(
92+ model="claude-sonnet-4-5-20250929",
93+ max_tokens=8000,
94+ messages=[
95+ {
96+ "role": "user",
97+ "content": prompt
98+ }
99+ ]
100+ )
101+
102+ # Save report
103+ report = message.content[0].text
104+ with open("claude-verification-report.md", "w") as f:
105+ f.write(report)
106+
107+ print("✅ Claude verification completed")
108+ print(f"Report saved to claude-verification-report.md")
119109 EOF
120-
121- # Run Claude CLI
122- $HOME/.local/bin/claude "$(cat claude_prompt.txt)"
110+
111+ # Run the verification script
112+ python3 verify_findings.py
123113
124114 - name : Check if Claude report exists
125115 if : always()
@@ -153,7 +143,7 @@ jobs:
153143 semgrep-report.json
154144 semgrep-report.txt
155145 claude-verification-report.md
156- claude_prompt.txt
146+ verify_findings.py
157147
158148 - name : Comment on PR with summary
159149 if : always() && github.event_name == 'pull_request' && steps.check_report.outputs.report_exists == 'true'
0 commit comments