Skip to content

Azure DevOps Pipelines

Binary Approach

Download the binary, run a scan, and publish results as a pipeline summary tab and artifact.

# azure-pipelines.yml
trigger:
  branches:
    include: [main]

pool:
  vmImage: ubuntu-latest

steps:
  - task: Bash@3
    displayName: Download Agent Smith
    inputs:
      targetType: inline
      script: |
        curl -fsSL -o $(Agent.TempDirectory)/agent-smith \
          https://github.com/holgerleichsenring/agent-smith/releases/latest/download/agent-smith-linux-x64
        chmod +x $(Agent.TempDirectory)/agent-smith

  - task: Bash@3
    displayName: Run API Security Scan
    env:
      ANTHROPIC_API_KEY: $(ANTHROPIC_API_KEY)
    inputs:
      targetType: inline
      script: |
        $(Agent.TempDirectory)/agent-smith api-scan \
          --repo $(Build.SourcesDirectory) \
          --output console,summary,sarif \
          --output-dir $(Build.ArtifactStagingDirectory)/security

  - task: Bash@3
    displayName: Publish Summary Tab
    condition: always()
    inputs:
      targetType: inline
      script: |
        SUMMARY=$(Build.ArtifactStagingDirectory)/security/summary.md
        if [ -f "$SUMMARY" ]; then
          echo "##vso[task.uploadsummary]$SUMMARY"
        fi

  - task: PublishBuildArtifacts@1
    displayName: Publish Security Report
    condition: always()
    inputs:
      pathToPublish: $(Build.ArtifactStagingDirectory)/security
      artifactName: security-report

Summary Tab

The ##vso[task.uploadsummary] command attaches a Markdown file as a tab on the pipeline run page. Team members see the findings without digging into logs.

Docker Compose Variant

For teams that prefer Docker or need tool containers (Nuclei, Spectral):

# azure-pipelines.yml
trigger:
  branches:
    include: [main]

pool:
  vmImage: ubuntu-latest

steps:
  - task: Bash@3
    displayName: Run Agent Smith (Docker)
    env:
      ANTHROPIC_API_KEY: $(ANTHROPIC_API_KEY)
    inputs:
      targetType: inline
      script: |
        docker run --rm \
          -e ANTHROPIC_API_KEY=$ANTHROPIC_API_KEY \
          -v $(Build.SourcesDirectory):/app/repo \
          -v /var/run/docker.sock:/var/run/docker.sock \
          -v $(Build.ArtifactStagingDirectory)/security:/app/output \
          holgerleichsenring/agent-smith:latest \
          api-scan --repo /app/repo --output console,summary,sarif --output-dir /app/output

  - task: Bash@3
    displayName: Publish Summary Tab
    condition: always()
    inputs:
      targetType: inline
      script: |
        SUMMARY=$(Build.ArtifactStagingDirectory)/security/summary.md
        if [ -f "$SUMMARY" ]; then
          echo "##vso[task.uploadsummary]$SUMMARY"
        fi

  - task: PublishBuildArtifacts@1
    displayName: Publish Security Report
    condition: always()
    inputs:
      pathToPublish: $(Build.ArtifactStagingDirectory)/security
      artifactName: security-report

Security Scan with Gate

Fail the pipeline when critical findings are detected:

  - task: Bash@3
    displayName: Check Findings
    inputs:
      targetType: inline
      script: |
        SARIF=$(Build.ArtifactStagingDirectory)/security/results.sarif
        if [ -f "$SARIF" ]; then
          CRITICAL=$(jq '[.runs[].results[] | select(.level == "error")] | length' "$SARIF")
          if [ "$CRITICAL" -gt 0 ]; then
            echo "##vso[task.logissue type=error]Found $CRITICAL critical security findings"
            exit 1
          fi
        fi

Variables Setup

Add these as pipeline variables (mark as secret):

Variable Required Description
ANTHROPIC_API_KEY Yes Claude API key for analysis
GITHUB_TOKEN No For GitHub source repos
AZURE_DEVOPS_TOKEN No For Azure Repos