Purplemet Azure DevOps Extension
Purplemet: Proactive Web Attack Surface Management. Discover real-time security insights with Purplemet's Web ASM platform.
Run Purplemet security analyses directly in your Azure DevOps pipelines.

Quick Start
trigger:
- main
pool:
vmImage: 'ubuntu-latest'
steps:
- task: PurplemetAnalyze@1
inputs:
apiToken: $(PURPLEMET_API_TOKEN)
targetUrl: 'https://your-app.example.com'
failSeverity: 'high'
Prerequisites
- Create a Purplemet API token at cloud.purplemet.com
- Install the extension from the Azure DevOps Marketplace
- Add
PURPLEMET_API_TOKEN as a secret pipeline variable:
- Edit pipeline → Variables → New variable
- Check Keep this value secret
Usage
YAML Pipeline
steps:
- task: PurplemetAnalyze@1
inputs:
apiToken: $(PURPLEMET_API_TOKEN)
targetUrl: 'https://your-app.example.com'
failSeverity: 'high'
Classic Pipeline
- Add the Purplemet Security Analysis task
- Configure the API token (use a secret variable)
- Set the target URL and severity threshold
With Docker (Without Extension)
The ppmsupport/purplemet-cli Docker image includes the shared analyze.sh script which reads all PURPLEMET_* variables automatically:
steps:
- script: |
docker run --rm \
-e PURPLEMET_API_TOKEN=$(PURPLEMET_API_TOKEN) \
-e PURPLEMET_TARGET_URL=https://your-app.com \
-e PURPLEMET_FAIL_SEVERITY=high \
--entrypoint /usr/local/share/purplemet/analyze.sh \
ppmsupport/purplemet-cli
displayName: 'Purplemet Security Analysis'
With Binary Installation
Uses the shared install.sh and analyze.sh scripts for consistent behavior across all platforms:
steps:
- script: |
curl -sSLf https://github.com/purplemet/cli/releases/latest/download/install.sh -o /tmp/install.sh
curl -sSLf https://github.com/purplemet/cli/releases/latest/download/analyze.sh -o /tmp/analyze.sh
chmod +x /tmp/install.sh /tmp/analyze.sh
source /tmp/install.sh && purplemet_install
/tmp/analyze.sh
displayName: 'Purplemet Security Analysis'
env:
PURPLEMET_API_TOKEN: $(PURPLEMET_API_TOKEN)
PURPLEMET_TARGET_URL: 'https://your-app.com'
PURPLEMET_FAIL_SEVERITY: 'high'
All PURPLEMET_* variables from the configuration reference are supported.
Required
| Input |
Default |
Description |
apiToken |
— |
API token (use secret variable) |
targetUrl |
— |
URL of the web application to analyze |
General
| Input |
Default |
Description |
failSeverity |
high |
Severity threshold: critical, high, medium, low, info |
timeout |
1800000 |
Polling timeout in milliseconds (30 min) |
version |
latest |
CLI version to use |
format |
json |
Output format: json, human, sarif, html |
baseUrl |
— |
API base URL (override) |
noCreate |
false |
Do not auto-create site if URL not found |
Security Gates
| Input |
Default |
Description |
failRating |
— |
Fail if rating is at or below this grade (A–F) |
failCvss |
0 |
Fail if any CVE has CVSS score ≥ this value (e.g. 9.0) |
failOnEol |
false |
Fail if end-of-life components are detected |
failOnSsl |
false |
Fail if SSL/TLS protocol issues are detected |
failOnCert |
false |
Fail if certificate issues are detected |
failOnHeaders |
false |
Fail if HTTP security header issues are detected (CSP, HSTS, X-Frame-Options) |
failOnCookies |
false |
Fail if insecure cookie issues are detected (HttpOnly, Secure, SameSite) |
failOnUnsafe |
false |
Fail if unsafe component issues are detected |
failOnKev |
false |
Fail if CISA Known Exploited Vulnerabilities are detected |
failOnEpss |
0 |
Fail if any issue has EPSS score ≥ this value (0.0–1.0) |
failOnActiveExploits |
false |
Fail if actively exploited vulnerabilities are detected |
failOnOssfScore |
0 |
Fail if any technology has OpenSSF Scorecard score below this value (0–10) |
failOnCertExpiry |
0 |
Fail if certificate expires within N days |
failOnIssueCount |
0 |
Fail if total issue count ≥ this value |
requireWaf |
false |
Fail if no WAF is detected |
failOnSensitiveServices |
false |
Fail if sensitive services are exposed on the site IP |
excludeTech |
— |
Fail if specified technologies are detected (comma-separated) |
When using the Docker or binary methods (without the extension), all of the above are exposed as PURPLEMET_* environment variables (e.g. PURPLEMET_FAIL_ON_KEV, PURPLEMET_FAIL_CVSS).
Output Variables
Access in subsequent steps:
| Variable |
Description |
Example |
PurplemetExitCode |
Exit code of the analysis |
0 |
PurplemetRating |
Security rating |
B |
PurplemetIssues |
Total number of issues |
12 |
- task: PurplemetAnalyze@1
name: analysis
inputs:
apiToken: $(PURPLEMET_API_TOKEN)
targetUrl: 'https://your-app.com'
- script: |
echo "Rating: $(analysis.PurplemetRating)"
echo "Issues: $(analysis.PurplemetIssues)"
displayName: 'Check Results'
Viewing the Report
The task automatically uploads the analysis output as a build artifact named purplemet-report. No extra step required.
After the run completes:
- Open the pipeline run → Summary tab
- Scroll to Published (or Related in newer UIs)
- Download the
purplemet-report artifact
With format: html, the CLI writes purplemet-report.html to the pipeline workspace (not stdout). Add a PublishPipelineArtifact step to surface it:
- task: PurplemetAnalyze@1
inputs:
apiToken: $(PURPLEMET_API_TOKEN)
targetUrl: 'https://your-app.example.com'
format: 'html'
failSeverity: 'high'
- task: PublishPipelineArtifact@1
condition: always() # publish even if the gate fails
inputs:
targetPath: '$(System.DefaultWorkingDirectory)/purplemet-report.html'
artifact: 'purplemet-report-html'
publishLocation: 'pipeline'
Download from Summary → Published, then open the file locally in a browser. Azure DevOps does not render HTML inline — use the HTML Report Publisher extension if you want a dedicated tab inside the run.
Exit Codes
| Code |
Meaning |
Task Result |
| 0 |
No issues above threshold |
Succeeded |
| 1 |
Issues found above threshold |
Succeeded with issues |
| 2 |
Analysis error |
Failed |
| 3 |
Timeout |
Failed |
| 4 |
Network/API error |
Failed |
| 5 |
Usage error |
Failed |
| 6 |
API contract error |
Failed |
Complete Example
trigger:
- main
pool:
vmImage: 'ubuntu-latest'
stages:
- stage: Build
jobs:
- job: BuildAndTest
steps:
- script: make build && make test
- stage: Security
dependsOn: Build
jobs:
- job: Analyze
steps:
- task: PurplemetAnalyze@1
inputs:
apiToken: $(PURPLEMET_API_TOKEN)
targetUrl: 'https://staging.example.com'
failSeverity: 'high'
timeout: '600000'
- stage: Production
dependsOn: Security
# Deploy only if Security passed AND we are on main
condition: and(succeeded(), eq(variables['Build.SourceBranch'], 'refs/heads/main'))
jobs:
- deployment: Prod
environment: production
strategy:
runOnce:
deploy:
steps:
- script: ./deploy.sh production
Troubleshooting
| Error |
Solution |
Variable PURPLEMET_API_TOKEN not found |
Add as a secret pipeline variable or variable group |
| Token invalid/expired |
Create a new token at cloud.purplemet.com |
| Timeout (exit code 3) |
Increase timeout input (e.g. 600000 for 10 min) |
| Network error (exit code 4) |
Ensure agent can reach api.purplemet.com on port 443 |
Documentation
See the full Azure DevOps integration guide for advanced examples, security gates, and detailed troubleshooting.