Skip to content

Commit 2cb6637

Browse files
Merge pull request #54 from Contrast-Security-OSS/AIML-122-add-claude-code-external-agent-config
AIML-122: add claude code external agent config
2 parents a05ea16 + 2d3213a commit 2cb6637

File tree

6 files changed

+53
-3
lines changed

6 files changed

+53
-3
lines changed

README.md

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,48 @@ This is an example variation of the workflow file for use with the GitHub Copilo
222222
# The Closed and Merge Handler jobs remain the same as the previous example as well.
223223
```
224224

225+
### Installation and Configuration for Claude Code Coding Agent
226+
- NOTE: The Claude GitHub app is required to be installed in your GitHub organization or repository.
227+
- Please see: https://docs.anthropic.com/en/docs/claude-code/github-actions
228+
This is an example variation of the workflow file for use with the Claude Code Coding Agent:
229+
```
230+
# The beginning of the workflow file is the same as the previous example.
231+
232+
# Use a variation of this 'generate_fixes' job in order to run with the Claude Code Coding Agent
233+
generate_fixes:
234+
name: Generate Fixes
235+
runs-on: ubuntu-latest
236+
if: github.event_name == 'workflow_dispatch' || github.event_name == 'schedule'
237+
steps:
238+
# When using Claude Code, it is unnecessary to authenticate with an LLM API from this step.
239+
240+
- name: Checkout repository
241+
uses: actions/checkout@v4
242+
with:
243+
fetch-depth: 0
244+
245+
- name: Run Contrast AI SmartFix - Generate Fixes Action
246+
uses: Contrast-Security-OSS/contrast-ai-smartfix-action@v1 # Replace with the latest version
247+
with:
248+
# Contrast Configuration
249+
contrast_host: ${{ vars.CONTRAST_HOST }} # The host name of your Contrast SaaS instance, e.g. 'app.contrastsecurity.com'
250+
contrast_org_id: ${{ vars.CONTRAST_ORG_ID }} # The UUID of your Contrast organization
251+
contrast_app_id: ${{ vars.CONTRAST_APP_ID }} # The UUID that is specific to the application in this repository.
252+
contrast_authorization_key: ${{ secrets.CONTRAST_AUTHORIZATION_KEY }}
253+
contrast_api_key: ${{ secrets.CONTRAST_API_KEY }}
254+
255+
# GitHub Configuration
256+
github_token: ${{ secrets.PAT_TOKEN }} # Necessary for creating Issues and mentioning Claude Code (@claude). This token should have read permission for metadata and read-write permission for issues and pulls. A best practice is to have an GitHub Organization service account create the PAT (an Organization admin may need to approve it)
257+
base_branch: '${{ github.event.repository.default_branch }}' # This will default to your repo default branch (other common base branches are 'main', 'master' or 'develop')
258+
coding_agent: 'CLAUDE_CODE' # Specify the use of Claude Code instead of the default SmartFix internal coding agent
259+
260+
# Other Optional Inputs (see action.yml for defaults and more options)
261+
# formatting_command: 'mvn spotless:apply' # Or the command appropriate for your project to correct the formatting of SmartFix's changes. This ensures that SmartFix follows your coding standards.
262+
# max_open_prs: 5 # This is the maximum limit for the number of PRs that SmartFix will have open at single time
263+
264+
# The Closed and Merge Handler jobs remain the same as the previous example as well.
265+
```
266+
225267
### Supported LLMs (Bring Your Own LLM \- BYOLLM) for the SmartFix Coding Agent
226268

227269
SmartFix uses a "Bring Your Own LLM" (BYOLLM) model. You provide the credentials for your preferred LLM provider.

action.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ inputs:
9090
required: false
9191
default: 'true'
9292
coding_agent:
93-
description: 'Specifies the coding agent to use for generating fixes. Allowed values: SMARTFIX, GITHUB_COPILOT.'
93+
description: 'Specifies the coding agent to use for generating fixes. Allowed values: SMARTFIX, GITHUB_COPILOT, CLAUDE_CODE.'
9494
required: false
9595
default: 'SMARTFIX'
9696

src/config.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,7 @@ def _check_contrast_config_values_exist(self):
165165

166166
def _get_coding_agent(self) -> str:
167167
coding_agent = self._get_env_var("CODING_AGENT", required=False, default="SMARTFIX")
168-
valid_agents = ["SMARTFIX", "GITHUB_COPILOT"]
168+
valid_agents = ["SMARTFIX", "GITHUB_COPILOT", "CLAUDE_CODE"]
169169
if coding_agent.upper() not in valid_agents:
170170
_log_config_message(f"Warning: Invalid CODING_AGENT '{coding_agent}'. Must be one of {valid_agents}. Defaulting to 'SMARTFIX'.", is_warning=True)
171171
return "SMARTFIX"

src/external_coding_agent.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,10 @@ def generate_fixes(self, vuln_uuid: str, remediation_id: str, vuln_title: str, i
155155
remediation_label = f"smartfix-id:{remediation_id}"
156156
issue_title = vuln_title
157157

158+
if self.config.CODING_AGENT == "CLAUDE_CODE":
159+
debug_log("CLAUDE_CODE agent detected, tagging @claude in issue title for processing")
160+
issue_title = f"@claude fix: {issue_title}"
161+
158162
# Use the provided issue_body or fall back to default
159163
if issue_body is None:
160164
log(f"Failed to generate issue body for vulnerability id {vuln_uuid}", is_error=True)

src/git_handler.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -540,6 +540,10 @@ def create_issue(title: str, body: str, vuln_label: str, remediation_label: str)
540540
issue_number = int(os.path.basename(issue_url.strip()))
541541
log(f"Issue number extracted: {issue_number}")
542542

543+
if config.CODING_AGENT == "CLAUDE_CODE":
544+
debug_log("CLAUDE_CODE agent detected no need to edit issue for assignment")
545+
return issue_number
546+
543547
# Now try to assign to @copilot separately
544548
assign_command = [
545549
"gh", "issue", "edit",

src/main.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -333,7 +333,7 @@ def main(): # noqa: C901
333333
qa_system_prompt = vulnerability_data['qaSystemPrompt']
334334
qa_user_prompt = vulnerability_data['qaUserPrompt']
335335
else:
336-
# For external coding agents (like GITHUB_COPILOT), get vulnerability details
336+
# For external coding agents (GITHUB_COPILOT/CLAUDE_CODE), get vulnerability details
337337
log("\n::group::--- Fetching next vulnerability details from Contrast API ---")
338338
vulnerability_data = contrast_api.get_vulnerability_details(
339339
config.CONTRAST_HOST, config.CONTRAST_ORG_ID, config.CONTRAST_APP_ID,

0 commit comments

Comments
 (0)