Skip to content
Purplemet CI edited this page Apr 28, 2026 · 6 revisions

Purplemet CLI

Command-line tool for running web application security analyses via the Purplemet platform. Designed for CI/CD integration and local use.

🛡️ New to Purplemet? Proactive Web Attack Surface Management — discover real-time security insights with Purplemet's Web ASM platform. Dive into the official documentation to learn more, or explore the API reference.

Table of Contents

Installation

Binary (Linux / macOS / Windows)

curl -sSL https://raw.githubusercontent.com/purplemet/cli/main/scripts/install.sh | sh

The script detects your OS and architecture, downloads the binary, verifies the SHA256 checksum, and installs it to /usr/local/bin.

You can also download a specific version from Releases.

Homebrew (macOS / Linux)

brew tap purplemet/cli https://github.com/Purplemet/cli.git
brew install purplemet-cli

Shell completions for bash, zsh and fish are installed automatically. Open a new terminal (or run exec $SHELL) for them to take effect.

Docker

docker run --rm -e PURPLEMET_API_TOKEN=<token> ppmsupport/purplemet-cli analyze https://your-app.com

Image: ppmsupport/purplemet-cli:latest — Alpine-based, ~15MB. See Docker documentation.

From Source

git clone https://github.com/purplemet/cli.git
cd cli
make build
sudo make install

Requires Go 1.22+.

Quick Start

1. Get an API Token

Create a token at cloud.purplemet.com.

2. Configure Authentication

export PURPLEMET_API_TOKEN=<your-token>

Or use a .env file in your project directory:

PURPLEMET_API_TOKEN=your-token-here

3. Verify Authentication

purplemet-cli auth check

4. Run a Security Analysis

# Analyze by URL (auto-creates the site if it doesn't exist)
purplemet-cli analyze https://your-app.com

# Analyze by site UUID
purplemet-cli analyze a1b2c3d4-e5f6-7890-abcd-ef1234567890

# CI/CD mode: JSON output + severity gate
purplemet-cli analyze https://your-app.com --json --fail-on-severity high

Commands

analyze — Run a Security Analysis

Starts an analysis on a site and polls until completion.

purplemet-cli analyze <siteId|url> [flags]

Arguments:

Argument Description
<siteId|url> Site UUID or URL to analyze. If a URL is given, the CLI resolves it to a site (or creates one automatically).

Flags:

Flag Default Description
--no-create false Do not auto-create a new site if the URL is not found
--format Output format: json, human, sarif, html
--output-file Write output to a file instead of stdout
--poll-interval 10000 Polling interval in ms while waiting for analysis completion (env: PURPLEMET_POLL_INTERVAL)
--wait-timeout 0 (unlimited) Global polling timeout in ms (env: PURPLEMET_WAIT_TIMEOUT)

Security Gates:

Gates allow you to fail a pipeline based on specific security criteria. Multiple gates can be combined — the analysis fails if any gate triggers (exit code 1).

Flag Env Variable Default Description
--fail-on-severity PURPLEMET_FAIL_SEVERITY — (disabled) Fail if issues at or above: critical, high, medium, low, info
--fail-on-rating PURPLEMET_FAIL_RATING Fail if rating is at or worse than: A, B, C, D, E, F
--fail-on-cvss PURPLEMET_FAIL_CVSS 0 (disabled) Fail if any issue has a CVSS score >= threshold (e.g. 9.0)
--fail-on-eol PURPLEMET_FAIL_ON_EOL false Fail if end-of-life components are detected
--fail-on-ssl PURPLEMET_FAIL_ON_SSL false Fail if SSL/TLS protocol issues are found
--fail-on-cert PURPLEMET_FAIL_ON_CERT false Fail if certificate issues are found
--fail-on-headers PURPLEMET_FAIL_ON_HEADERS false Fail if HTTP security header issues (CSP, HSTS, X-Frame-Options) are found
--fail-on-cookies PURPLEMET_FAIL_ON_COOKIES false Fail if insecure cookies (HttpOnly, Secure, SameSite) are found
--fail-on-unsafe PURPLEMET_FAIL_ON_UNSAFE false Fail if unsafe components are detected
--fail-on-kev PURPLEMET_FAIL_ON_KEV false Fail if CISA Known Exploited Vulnerabilities are detected
--fail-on-epss PURPLEMET_FAIL_ON_EPSS 0 (disabled) Fail if any issue has an EPSS score >= threshold (e.g. 0.75)
--fail-on-active-exploits PURPLEMET_FAIL_ON_ACTIVE_EXPLOITS false Fail if actively exploited vulnerabilities are detected
--fail-on-ossf-score PURPLEMET_FAIL_ON_OSSF_SCORE 0 (disabled) Fail if any component has an OpenSSF Scorecard score below threshold (e.g. 5.0)
--fail-on-cert-expiry PURPLEMET_FAIL_ON_CERT_EXPIRY 0 (disabled) Fail if any certificate expires within N days
--fail-on-issue-count PURPLEMET_FAIL_ON_ISSUE_COUNT 0 (disabled) Fail if total issue count >= threshold
--require-waf PURPLEMET_REQUIRE_WAF false Fail if no WAF is detected
--fail-on-sensitive-services PURPLEMET_FAIL_ON_SENSITIVE_SERVICES false Fail if sensitive services are exposed
--exclude-tech PURPLEMET_EXCLUDE_TECH Fail if specified technologies are detected (comma-separated)
--no-create PURPLEMET_NO_CREATE false Do not auto-create site for unknown URLs

Note: Issues explicitly ignored (via purplemet-cli issues ignore) are always excluded from gate evaluation — an acknowledged risk should never re-fail a pipeline.

Examples:

# Basic analysis with human-readable output
purplemet-cli analyze https://your-app.com

# JSON output to file
purplemet-cli analyze https://your-app.com --format json --output-file report.json

# SARIF output (for GitHub Code Scanning)
purplemet-cli analyze https://your-app.com --format sarif --output-file results.sarif

# HTML report
purplemet-cli analyze https://your-app.com --format html --output-file report.html

# Fail pipeline if high or critical issues found
purplemet-cli analyze https://your-app.com --json --fail-on-severity high

# Analyze existing site only (no auto-creation)
purplemet-cli analyze https://your-app.com --no-create

# With timeout (5 minutes)
purplemet-cli analyze https://your-app.com --wait-timeout 300000

analyze stop — Stop a Running Analysis

purplemet-cli analyze stop <siteId> [analysisId]

Stops a specific analysis (if analysisId is given) or all running analyses for the site.

Examples:

# Stop all running analyses for a site
purplemet-cli analyze stop a1b2c3d4-e5f6-7890-abcd-ef1234567890

# Stop a specific analysis
purplemet-cli analyze stop a1b2c3d4-... e9833020-...

auth check — Validate API Token

purplemet-cli auth check

Validates that the configured API token is accepted by the Purplemet API.

$ purplemet-cli auth check
Authenticated successfully.

$ purplemet-cli auth check --json
{"authenticated": true}

sites list — List Web Applications

purplemet-cli sites list [flags]

Shares the standard pagination flags (see Pagination):

Flag Default Description
--limit 100 Page size (1–1000)
--offset 0 Skip the first N items
--page 0 Page number, 1-indexed (alternative to --offset)
--all false Fetch every page automatically (capped by --max)
--max 10000 Hard cap on items fetched when --all is set
$ purplemet-cli sites list --page 2 --limit 20
ID                                      URL
--------------------------------------  ---
…

Showing 21-40 of 142 site(s) — page 2 of 8 (next: --page 3)

# Fetch everything in one shot
$ purplemet-cli sites list --all
…
Showing 142 of 142 site(s) — all pages fetched

# Filter client-side with --query (works on every list command)
$ purplemet-cli sites list --query "url~=staging"
$ purplemet-cli issues list --all --query "severity=high,status=OPEN"

See docs/configuration.md for the full --query syntax (operators =, !=, ~=, !~).

sites get — Get Site Details

purplemet-cli sites get <siteId>

Displays detailed information about a site: URL, rating, score, issue counts, technologies, WAF, schedule.

sites create — Create a New Site

purplemet-cli sites create <url> [flags]
Flag Default Description
--description Optional description
--vhost Virtual Host IP address (IPv4)
--no-notification false Disable notifications
--launch false Launch an analysis immediately after creation
--restore false Restore a previously deleted site
--schedule-frequency Schedule frequency: DAILY or WEEKLY
--schedule-day Day for WEEKLY analyses (e.g. monday)
--schedule-time Time for scheduled analyses (e.g. 10:15)

Examples:

# Create and immediately analyze
purplemet-cli sites create https://your-app.com --launch

# Create with weekly schedule
purplemet-cli sites create https://your-app.com \
  --description "Production" \
  --schedule-frequency WEEKLY \
  --schedule-day monday \
  --schedule-time 02:00

sites delete — Delete a Site

purplemet-cli sites delete <siteId>

sites schedule — Configure Analysis Schedule

purplemet-cli sites schedule <siteId> [flags]
Flag Default Description
--frequency DAILY Analysis frequency: DAILY or WEEKLY
--day Day of week for WEEKLY analyses (e.g. monday)
--time Time of day in UTC, HH:MM format (e.g. 02:00)
--disable false Disable scheduled analyses

Examples:

# Schedule daily analyses at 02:00 UTC
purplemet-cli sites schedule a1b2c3d4-... --frequency DAILY --time 02:00

# Schedule weekly analyses
purplemet-cli sites schedule a1b2c3d4-... --frequency WEEKLY --day monday --time 02:00

# Disable scheduled analyses
purplemet-cli sites schedule a1b2c3d4-... --disable

diff — Compare Two Analyses

purplemet-cli diff <analysisId1> <analysisId2> --site-id <siteId>

Compares two analyses and shows the delta: rating, score, issues, CVEs, technologies.

Flag Required Description
--site-id Yes Site ID the analyses belong to

Example:

$ purplemet-cli diff e983302a-... f094413b-... --site-id a1b2c3d4-...
Purplemet • Diff e983302a vs f094413b
Rating:  B → A
Score:   3 → 1 (-2)
Issues:  12 → 5 (-7)
CVEs:    2 → 0 (-2)
Tech:    8 → 8 (0)

Changes by severity:
  HIGH                 -2
  MEDIUM               -3
  LOW                  -2

tech — Detect Technologies

purplemet-cli tech list <siteId|url>

Lists technologies detected on the site with versions and end-of-life status.

$ purplemet-cli tech list https://your-app.com
NAME            VERSION   EOL
------          -------   ---
Nginx           1.25.3    -
React           18.2.0    -
Node.js         20.11.0   -
PHP             5.6.40    2018-12-31

issues — Manage Issues

purplemet-cli issues list [flags]

Lists issues across all sites.

Subcommands:

Subcommand Description
issues comment create <issueId> --contents "..." Add a comment to an issue
issues comment list <issueId> List comments on an issue
issues comment update <issueId> <commentId> --contents "..." Update a comment
issues comment delete <issueId> <commentId> Delete a comment
issues ignore <issueId> [id...] --reason <reason> Ignore one or more issues (reasons: RISK_ACCEPTED, NOT_APPLICABLE, FIX_IN_PROGRESS, BACKPORTING, FALSE_POSITIVE)
issues activate <issueId> [id...] Re-activate previously ignored issues

domains — Browse Domains

Manage domains tracked in your account (created manually or via discoveries).

# List domains, filter by name, fetch all pages
purplemet-cli domains list
purplemet-cli domains list --query "name~=internal"
purplemet-cli domains list --all

# Inspect / create / delete
purplemet-cli domains get <domainId>
purplemet-cli domains create example.com
purplemet-cli domains delete <domainId>

discoveries — Manage Domain Discoveries

A discovery enumerates web apps under a domain.

purplemet-cli discoveries list --query "status=DONE"
purplemet-cli discoveries get <discoveryId>
purplemet-cli discoveries stop <discoveryId>

certificates (alias cert) — Browse SSL/TLS Certificates

# Certificates expiring soon (relies on the API ordering by validTo asc)
purplemet-cli certificates list --limit 20

# Filter by issuer or by status
purplemet-cli certificates list --query "issuer~=Let's Encrypt"
purplemet-cli certificates list --query "status=EXPIRED"

purplemet-cli certificates get <certId>

ip — Browse IP Addresses

# IPs ordered by threat level / sites count (server-side)
purplemet-cli ip list --all
purplemet-cli ip list --query "threatLevel=HIGH"
purplemet-cli ip list --query "isp~=cloudflare"

purplemet-cli ip get <ipId>

services — Browse Detected Services

Network services exposed on your assets (HTTP, SSH, DB, etc.).

purplemet-cli services list --query "sensitive=true"
purplemet-cli services list --query "port=22"
purplemet-cli services get <serviceId>

changes — Browse Detected Changes

Differences detected between consecutive analyses (new tech, certificate rotation, header changes, etc.).

purplemet-cli changes list --query "priority=HIGH"
purplemet-cli changes list --query "type~=technology"
purplemet-cli changes get <changeId>

tags — Manage Tags

Tags can be attached to sites, users, and tokens for grouping and access control.

purplemet-cli tags list
purplemet-cli tags create "production" --color "#FF0000" --description "Production assets"
purplemet-cli tags get <tagId>
purplemet-cli tags delete <tagId>

reports — Manage Generated Reports

# List, get, download — works for any report type/format
purplemet-cli reports list --query "status=DONE"
purplemet-cli reports get <reportId>
purplemet-cli reports download <reportId> --output-file report.pdf

# Cancel a report still being generated
purplemet-cli reports cancel <reportId>

tokens — Manage API Tokens (admin only)

Requires an ADMIN token. OPERATOR / READER tokens get 403 API_METHOD_NOT_ALLOWED.

purplemet-cli tokens list --query "role=ADMIN"
purplemet-cli tokens get <tokenId>

# Create — the secret is shown ONLY once on creation
purplemet-cli tokens create "ci-pipeline" --role OPERATOR --expires 2026-12-31

purplemet-cli tokens delete <tokenId>

users — Manage User Accounts (admin only)

Requires an ADMIN token.

purplemet-cli users list --query "status=ENABLED"
purplemet-cli users get <userId>

purplemet-cli users create alice@example.com --first-name Alice --last-name Doe --role OPERATOR
purplemet-cli users disable <userId>
purplemet-cli users enable <userId>
purplemet-cli users delete <userId>

sessions — Manage Active Sessions (admin only)

Requires an ADMIN token.

# List active sessions, filter by user or IP
purplemet-cli sessions list --query "active=true"
purplemet-cli sessions list --query "userEmail~=@example.com"

# Revoke (alias: delete, terminate)
purplemet-cli sessions revoke <sessionId>

version — Show Version Information

purplemet-cli version
$ purplemet-cli version
purplemet-cli v1.0.0 (abc1234) built 2025-01-15

$ purplemet-cli version --json
{"commit":"abc1234","date":"2025-01-15","version":"v1.0.0"}

completion — Shell Completions

Bash, zsh and fish completions are installed automatically by Homebrew, install.sh and make install. For any other install path, run purplemet-cli completion <shell> --help for setup instructions.

Global Flags

These flags are available on all commands.

Flag Env Variable Default Description
--token PURPLEMET_API_TOKEN API authentication token
--base-url PURPLEMET_BASE_URL https://api.purplemet.com API base URL
--timeout PURPLEMET_TIMEOUT 30000 Per-request HTTP timeout in ms
--json PURPLEMET_JSON false Machine-readable JSON output
--verbose / -v PURPLEMET_VERBOSE true Verbose logging to stderr
--insecure PURPLEMET_INSECURE false Skip TLS certificate verification

--fail-on-severity, --wait-timeout and --poll-interval are specific to analyze (see above).

Configuration

Configuration is resolved in priority order (first wins):

  1. CLI flags (--token, --json, etc.)
  2. Environment variables (PURPLEMET_API_TOKEN, etc.)
  3. .env file (auto-loaded from current directory)
  4. Project config file (.purplemet.yml — auto-discovered from the current directory up to the project root)
  5. User config file (~/.purplemet/config.yml)
  6. Defaults

See Configuration documentation for full details.

.env File

The CLI automatically loads a .env file from the current directory:

PURPLEMET_API_TOKEN=your-token-here
PURPLEMET_FAIL_SEVERITY=high
PURPLEMET_WAIT_TIMEOUT=300000

Project Config File (.purplemet.yml)

Put a .purplemet.yml at the root of your repository to capture the options used to analyze that project. The CLI auto-discovers it by walking up from the current working directory until it finds either the file or the project boundary (a .git/ directory).

# Default target for `purplemet-cli analyze` (siteId or URL).
# With this set you can simply run `purplemet-cli analyze` — no argument needed.
site: https://example.com

verbose: true

# Security gates for this project
fail_severity: high
fail_rating: C
fail_on_kev: true
fail_on_headers: true
exclude_tech:
  - php
  - java

Lookup order used to locate the file:

  1. --config <path> flag (explicit; errors if missing)
  2. $PURPLEMET_CONFIG env var
  3. .purplemet.yml / .purplemet.yaml in the current directory, then each parent up to the first .git/

Security: a project config is meant to be committed, so it must not contain secrets. If a project file sets token, basic_user or basic_pass, those fields are stripped at load time and a warning is printed. Put secrets in env vars or in ~/.purplemet/config.yml instead.

Typical use cases:

  • Run purplemet-cli analyze without arguments from any subfolder of the repo
  • Share the same gate configuration between local runs and CI/CD (one source of truth)
  • Pin per-project exclusions (exclude_tech) or thresholds (fail_on_epss) next to the code

User Config File (~/.purplemet/config.yml)

Persistent user-level defaults — the right place for your API token and any personal preferences shared across all projects.

token: ppm_xxx
base_url: https://api.purplemet.com
poll_interval_ms: 10000
timeout_ms: 30000
verbose: true
fail_severity: high

Severity Levels

For --fail-on-severity:

Level Blocks on
critical Critical only
high High + Critical
medium Medium + High + Critical
low Low + Medium + High + Critical
info All issues

Output Formats

The analyze command supports 4 output formats via --format or --json:

Format Flag Description
Human (default) Colored text output with summary table
JSON --json or --format json Machine-readable JSON with full analysis data
SARIF --format sarif SARIF 2.1.0 for GitHub Code Scanning and compatible tools
HTML --format html Standalone HTML report with visual styling

Human-readable Output

Purplemet • Analysis e983302a-7c76-4dce-8b29-1c525652469f • DONE
Duration: 01:13
Grade:    B (score: 3)
Issues:   total=3 critical=0 high=0 medium=0 low=3 cve=0 kev=0
Tech:     8 technologies detected
WAF:      CloudFlare
Message:  Task completed in 69s.

JSON Output

{
  "analysis": {
    "id": "e983302a-7c76-4dce-8b29-1c525652469f",
    "status": "DONE",
    "rating": "B",
    "score": 3,
    "issueCnt": 3,
    "issueCnts": { "CRITICAL": 0, "HIGH": 0, "MEDIUM": 0, "LOW": 3 },
    "technologyCnt": 8,
    "waf": "CloudFlare",
    "issues": [
      {
        "severity": "low",
        "name": "Missing Content-Security-Policy header",
        "description": "..."
      }
    ]
  }
}

SARIF Output

SARIF 2.1.0 output is compatible with:

  • GitHub Code Scanning (github/codeql-action/upload-sarif)
  • Azure DevOps Advanced Security
  • Any SARIF-compatible viewer
purplemet-cli analyze https://your-app.com --format sarif --output-file results.sarif

Exit Codes

Code Meaning Recommended CI Action
0 Success — no issues above threshold Pipeline passes
1 Vulnerabilities found above --fail-on-severity threshold Fail or warn — review findings
2 Analysis error on Purplemet platform Fail — check target URL accessibility
3 Timeout (--wait-timeout exceeded) Fail — increase timeout or check manually
4 Network or HTTP API error Fail — check token, network, rate limits
5 Usage error (invalid arguments) Fail — fix command syntax
6 API contract error (unexpected response) Fail — check CLI version, contact support

Handling Exit Codes in Scripts

purplemet-cli analyze https://your-app.com --json --fail-on-severity high
EXIT_CODE=$?

case $EXIT_CODE in
  0) echo "Analysis passed — no issues above threshold" ;;
  1) echo "WARNING: vulnerabilities found above threshold" ;;
  2) echo "Analysis error — check target accessibility" ;;
  3) echo "Timeout — increase --wait-timeout or check manually" ;;
  *) echo "Error (exit code $EXIT_CODE)" ; exit 1 ;;
esac

See Exit codes documentation for full details.

CI/CD Integrations

Ready-to-use integrations for major CI/CD platforms:

Platform Type Documentation
GitHub Actions Composite Action Guide · Action README
GitLab CI/CD Include Template Guide · Template
Bitbucket Pipelines Docker Step Guide · Template
Jenkins Shared Library Guide · Library
Azure DevOps Marketplace Extension Guide · Extension

Minimal CI Example (Any Platform)

# Install
curl -sSL https://raw.githubusercontent.com/purplemet/cli/main/scripts/install.sh | sh

# Analyze
PURPLEMET_API_TOKEN=$TOKEN purplemet-cli analyze https://your-app.com \
  --json --fail-on-severity high --wait-timeout 300000

Or with Docker:

docker run --rm \
  -e PURPLEMET_API_TOKEN=$TOKEN \
  ppmsupport/purplemet-cli analyze https://your-app.com --json --fail-on-severity high

Examples

Local Development

# Quick analysis with verbose output
purplemet-cli analyze https://your-app.com -v

# Check your sites
purplemet-cli sites list

# Get details for a site
purplemet-cli sites get a1b2c3d4-e5f6-7890-abcd-ef1234567890

# Create a site with a weekly schedule
purplemet-cli sites create https://your-app.com \
  --schedule-frequency WEEKLY \
  --schedule-day monday \
  --schedule-time 02:00

# Compare two analyses
purplemet-cli diff <id1> <id2> --site-id <siteId>

CI/CD Pipeline

# Blocking: fail the pipeline on high/critical issues
purplemet-cli analyze https://your-app.com --json --fail-on-severity high

# Non-blocking: always pass, inspect results
purplemet-cli analyze https://your-app.com --json || true

# With timeout for bounded execution
purplemet-cli analyze https://your-app.com --json \
  --fail-on-severity high --wait-timeout 300000

# Generate SARIF for GitHub Code Scanning integration
purplemet-cli analyze https://your-app.com --format sarif --output-file results.sarif

# Advanced gates: block on CVEs, EOL, and require WAF
purplemet-cli analyze https://your-app.com --json \
  --fail-on-severity high \
  --fail-on-cvss 9.0 \
  --fail-on-eol \
  --fail-on-kev \
  --require-waf

# Block on certificate expiring within 30 days
purplemet-cli analyze https://your-app.com --json \
  --fail-on-cert-expiry 30

# Block if specific technologies are detected
purplemet-cli analyze https://your-app.com --json \
  --exclude-tech "php,java"

Documentation

Document Description
Purplemet Platform Official Purplemet product documentation (ratings, analyses, issues, remediation)
Interpreting Results How to read reports, prioritize remediation, configure gates
Issues Management Ignore, activate, and comment on issues
Technology Detection List and monitor detected technologies
Configuration Environment variables, config file, .env file, severity levels
Exit Codes Detailed exit code reference with CI/CD recommendations
Docker Docker image usage and CI/CD examples
FAQ & Troubleshooting Common errors and solutions
Releases Release history and binaries
API Reference Official Purplemet REST API documentation (OpenAPI/Swagger)
Integrations
GitHub Actions Complete GitHub Actions guide
GitLab CI/CD GitLab CI/CD integration guide
Bitbucket Pipelines Bitbucket Pipelines guide
Jenkins Jenkins integration guide
Azure DevOps Azure DevOps integration guide

Development

make help          # Show all targets
make build         # Build for current platform
make test          # Run tests with race detector
make lint          # Run staticcheck
make lint-full     # Run golangci-lint
make vet           # Run go vet
make build-all     # Cross-compile all platforms

Releasing

The release workflow is fully automated and reproducible. Run these from a clean main branch:

make verify-build VERSION=v1.0.X  # Verify local build matches CI build
make release VERSION=v1.0.X       # Build, regenerate Formula, commit, tag (no push)
git push origin main && git push origin v1.0.X

make verify-build is the recommended pre-release check. It runs make build-all locally, then runs the CI build:linux-amd64 job in docker via gitlab-ci-local, and compares the SHA256 of the resulting binaries. If they match, the local build is reproducible against CI and verify:formula-sha will pass.

Requires Docker running and gitlab-ci-local installed.

License

Proprietary — Purplemet SAS

Clone this wiki locally