Skip to main content

Set up Contrast AI SmartFix with Contrast LLM

Legal Disclaimer

When you use Contrast AI SmartFix with Contrast LLM, you agree that your code and other data will be submitted to Contrast's managed LLM service. All data processing and AI model usage is governed by your existing Contrast Security service agreement and data processing terms.

Contrast LLM is a packaged and managed large language model (LLM) that Contrast hosts for use with the SmartFix coding agent. It is based on the Anthropic on AWS Bedrock LLM.

Contrast LLM benefits

  • Minimal LLM configuration: Configuration uses your existing Contrast credentials. No other LLM configuration is required.

  • Enterprise-grade security: All AI processing occurs within the Contrast secure infrastructure. The Contrast LLM doesn't use your Contrast data for training purposes.

  • Managed scaling: Automatically handles rate limits, retries, and load balancing

  • Cost transparency: Built-in credit tracking and usage monitoring

  • Seamless integration: The Contrast LLM works with existing SmartFix workflows

Before you begin

  • Find your Contrast credentials: You need the host name of your Contrast installation, the Organization ID, application ID, Authorization Key, and API Key.

    You can find the Organization ID, Authorization Key, and API key in your user settings in the Contrast web interface. To find the application ID, in the Applications page in the Contrast web interface, select an application. The number after applications/ in the URL is the ID.

  • Contrast LLM only works with the SmartFix coding agent. If you are using GitHub Copilot or Claude Code agents, you must continue using these external service integrations.

Steps for new Contrast LLM configuration

  1. In the SmartFix GitHub workflow file (usually .github/workflows/smartfix.yml), set theuse_contrast_llm option to true.

    name: Run Contrast AI SmartFix - Generate Fixes Action
      uses: Contrast-Security-OSS/contrast-ai-smartfix-action@v1
      with:
        # Enable Contrast LLM (replaces all BYOLLM configuration)
        use_contrast_llm: true # <--- Set this value
    
  2. Set these options for the Contrast credentials:

    • contrast_host: The host name of your Contrast instance, including the protocol. For example: https://yourcompany.contrastsecurity.com.

    • contrast_org_id: Contrast organization UUID

    • contrast_app_id: The Contrast application UUID for the specific repository

    • contrast_authorization_key: Recommended: Create a service user and use the authorization key for that user.

    • contrast_api_key: Organization API key

Steps to migrate to Contrast LLM

If you are using your own LLM and want to use the Contrast LLM instead, use this procedure.

  1. Back up your current Github workflow file for SmartFix (usually .github/workflows/smartfix.yml).

  2. In the GitHub workflow file, remove your LLM-specific settings.

    For example, if you were using Anthropic Claude Sonnet, you would remove these settings.

    # REMOVE these lines:
    # agent_model: 'bedrock/us.anthropic.claude-sonnet-4-5-20250929-v1:0'
    # anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
    # aws_bearer_token_bedrock: ${{ secrets.AWS_BEARER_TOKEN_BEDROCK }}
    # aws_region: ${{ vars.AWS_REGION }}
    
    # REMOVE this step entirely:
    # - name: Configure AWS Credentials
    #   uses: aws-actions/configure-aws-credentials@v4
    #   with: ...
  3. Add this setting:

    use_contrast_llm: true
  4. Test with a single vulnerability to verify the configuration is working correctly.

  5. If you need to revert to the original settings:

    1. Set use_contrast_llm: false

    2. Restore your original LLM provider configuration settings.

    3. Restore the original credential configuration steps.

Note

You can use SmartFix with different LLMs for different repositories. For example, in repo1, you could use the Contrast LLM and in repo2, you could use Anthropic Claude Sonnet.

Sample Contrast LLM workflow

name: Contrast AI SmartFix (Contrast LLM)

on:
  pull_request:
    types: [closed]
  schedule:
    - cron: '0 0 * * *' # Daily at midnight UTC
  workflow_dispatch:

permissions:
  contents: write
  pull-requests: write
  issues: write

jobs:
  generate_fixes:
    name: Generate Fixes
    runs-on: ubuntu-latest
    if: github.event_name == 'workflow_dispatch' || github.event_name == 'schedule'
    steps:
      - name: Checkout repository
        uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - name: Run Contrast AI SmartFix - Generate Fixes Action
        uses: Contrast-Security-OSS/contrast-ai-smartfix-action@v1
        with:
          # --- Contrast LLM Configuration ---
          use_contrast_llm: true

          # --- Standard Configuration ---
          max_open_prs: 5
          base_branch: main
          build_command: 'mvn clean test'
          max_qa_attempts: 6
          vulnerability_severities: '["CRITICAL","HIGH","MEDIUM"]'
          formatting_command: 'mvn spotless:apply'

          # --- GitHub Token ---
          github_token: ${{ secrets.GITHUB_TOKEN }}

          # --- Contrast API Credentials ---
          contrast_host: ${{ vars.CONTRAST_HOST }}
          contrast_org_id: ${{ vars.CONTRAST_ORG_ID }}
          contrast_app_id: ${{ vars.CONTRAST_APP_ID }}
          contrast_authorization_key: ${{ secrets.CONTRAST_AUTHORIZATION_KEY }}
          contrast_api_key: ${{ secrets.CONTRAST_API_KEY }}

          # --- Optional Configuration ---
          skip_writing_security_test: false
          debug_mode: ${{ vars.DEBUG_MODE || 'false' }}

  # PR handling jobs remain unchanged
  handle_pr_merge:
    name: Handle PR Merge
    runs-on: ubuntu-latest
    if: github.event.pull_request.merged == true && contains(join(github.event.pull_request.labels.*.name), 'contrast-vuln-id:VULN-')
    steps:
      - name: Checkout repository
        uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - name: Notify Contrast on PR Merge
        uses: Contrast-Security-OSS/contrast-ai-smartfix-action@v1
        with:
          run_task: merge
          github_token: ${{ secrets.GITHUB_TOKEN }}
          contrast_host: ${{ vars.CONTRAST_HOST }}
          contrast_org_id: ${{ vars.CONTRAST_ORG_ID }}
          contrast_app_id: ${{ vars.CONTRAST_APP_ID }}
          contrast_authorization_key: ${{ secrets.CONTRAST_AUTHORIZATION_KEY }}
          contrast_api_key: ${{ secrets.CONTRAST_API_KEY }}
          skip_comments: ${{ vars.SKIP_COMMENTS || 'false' }}
          debug_mode: ${{ vars.DEBUG_MODE || 'false' }}
        env:
          GITHUB_EVENT_PATH: ${{ github.event_path }}

  handle_pr_closed:
    name: Handle PR Close
    runs-on: ubuntu-latest
    if: github.event.pull_request.merged == false && contains(join(github.event.pull_request.labels.*.name), 'contrast-vuln-id:VULN-')
    steps:
      - name: Checkout repository
        uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - name: Notify Contrast on PR Closed
        uses: Contrast-Security-OSS/contrast-ai-smartfix-action@v1
        with:
          run_task: closed
          github_token: ${{ secrets.GITHUB_TOKEN }}
          contrast_host: ${{ vars.CONTRAST_HOST }}
          contrast_org_id: ${{ vars.CONTRAST_ORG_ID }}
          contrast_app_id: ${{ vars.CONTRAST_APP_ID }}
          contrast_authorization_key: ${{ secrets.CONTRAST_AUTHORIZATION_KEY }}
          contrast_api_key: ${{ secrets.CONTRAST_API_KEY }}
        env:
          GITHUB_EVENT_PATH: ${{ github.event_path }}