Skip to content

interpreting results

Purplemet CI edited this page Jun 2, 2026 · 5 revisions

Interpreting Results

This guide explains how to read Purplemet analysis results, prioritize remediation, and configure security gates for your context.

Security Rating and Severity Levels

Every analysis returns a rating (A, B, C, D, E, F) and classifies issues by severity (CRITICAL, HIGH, MEDIUM, LOW, INFO).

Both are computed and defined by the Purplemet platform — the CLI only consumes these values. Refer to the official Purplemet documentation for authoritative definitions, scoring rules, and examples.

Output Formats

Four output formats are available, each designed for a different audience:

  • Human — developer in a terminal (default)
  • JSON — CI/CD pipelines and automated processing
  • SARIF — security tool integrations (GitHub Code Scanning, Defect Dojo, VS Code)
  • HTML — everyone (stakeholders, managers, auditors, clients)

Human-readable (default)

The terminal output shows a color-coded summary. The format below is illustrative — actual values (rating, severities, CVE counts, technology categories, gate messages) come from the Purplemet API:

Purplemet • https://your-app.com • DONE
────────────────────────────────────────────────────────────
  Analysis:   <uuid>
  Title:      <site title>
  IP:         <origin ip>
  HTTP:       <status code>
  Duration:   <duration>

  Rating:     <A-F> (score: <0-100>)
  Issues:     <total> — broken down by severity
  CVEs:       <count>
  Tech:       <count> technologies (<unsafe> unsafe)
  WAF:        <WAF product or none>

Issues (...)
────────────────────────────────────────────────────────────
  <SEVERITY>   <name or CVE id>
               <type> • CWE-<id> • CVSS <score> • EPSS <pct>
               <description>
  ...

Technologies (...)
────────────────────────────────────────────────────────────
  <name>       <version>    <category>    <CVE count if any>

Certificates
────────────────────────────────────────────────────────────
  <subject>                 expires <date> (<days> left)

Gates (N configured)
────────────────────────────────────────────────────────────
  ✓  <gate>                   passed
  ✗  <gate>                   failed
       <failure message>

  X passed, Y failed / N gates

JSON

The JSON output is designed for CI/CD pipelines and automated processing. JSON goes to stdout; progress updates and gate summaries go to stderr.

During analysis, the CLI emits periodic status updates to stderr so CI logs show progress:

[purplemet] Waiting for analysis...
[purplemet] Scanning — 25% (30s)
[purplemet] Analyzing — 75% (1m15s)
[purplemet] Analysis complete (2m05s)
purplemet-cli analyze https://your-app.com --json

Top-level structure:

Field Type Description
meta.version string CLI version that generated the report
meta.timestamp string ISO 8601 timestamp
analysis object Full analysis data (see below)
gates object Per-gate evaluation results
ignoredCount int Number of IGNORED issues excluded from analysis.issues (always present, 0 when none)
error string Error message (only on failure)

Fields are omitted when empty. The JSON is encoded with omitempty: a field appears only when it holds a non-zero / non-empty value. A trivial site (no CVEs, no end-of-life technology, no exposed services) therefore emits a subset of the fields below — e.g. cveCnt, kevCnt and unsafeCnt are absent when 0, and certificates / services when empty. The tables below list the key fields the CLI emits, not a guaranteed-present set.

analysis object — key fields:

Field Type Description
id string Analysis UUID
site.id string Site UUID
url string Analyzed URL
status string DONE, ERROR, WARNING, ABORTED
rating string Letter grade A–F
score int Numeric score (0–100, lower is better)
issueCnt int Total issue count
issueCnts object {"CRITICAL": 0, "HIGH": 2, "MEDIUM": 3, ...}
cveCnt int Number of CVEs
kevCnt int CISA Known Exploited Vulnerabilities count
technologyCnt int Technologies detected
unsafeCnt int Unsafe components count
waf string WAF product name (empty if none)
duration string ISO 8601 duration
remoteIp string Origin IP address
httpResponseCode int HTTP status code
issues array Detailed issue list
technologies array Technology details
certificates array SSL certificate details
services array Exposed services

issues[] — each issue:

Field Type Description
id string Issue ID
severity string CRITICAL, HIGH, MEDIUM, LOW, INFO
type string Category: SSL_TLS_PROTOCOLS, CERTIFICATES, HTTP_HEADERS, COOKIES, etc.
name string CVE identifier or vulnerability name
description string Detailed description
reference string External reference URL
cweId int CWE number
cweName string CWE name
exploitMaturity string ATTACKED if actively exploited
status string OPEN, FIXED, REJECTED, IGNORED
weight int Internal weight used to compute the score
technology.name string Affected technology
technology.version string Affected version
details.cvss3Score float CVSS v3 score (0–10)
details.cvss3Vector string CVSS v3 vector string
details.epssScore float EPSS score (0–1)
details.epssPercentile string EPSS percentile
details.cisaAdditionDate string Date added to CISA KEV catalog
details.cisaRequiredAction string CISA recommended action

technologies[] — each technology:

Field Type Description
id string Technology UUID
name string Product name
version string Detected version
category string Technology category as defined by the Purplemet platform
cveCnt int Known CVE count
endOfLife int End-of-life date as a unix-ms timestamp (omitted when the component is not end-of-life)
latestVersion string Latest available version
ossfScorecard.score float OpenSSF Scorecard score (0–10)

gates object:

Each gate key (e.g. severity, rating, cvss, eol, waf) maps to:

Field Type Description
name string Gate identifier
passed bool true if gate passed or was skipped
skipped bool true if gate was not enabled
message string Failure reason (empty if passed)

Gate summary on stderr (CI-friendly):

In JSON/SARIF mode, the CLI also prints a human-readable gate summary to stderr so CI logs show which gates failed without parsing JSON:

[purplemet] FAILED  severity: severity gate: 1 critical (threshold: high)
[purplemet] FAILED  eol: EOL gate: 2 end-of-life component(s) (jQuery 2.1.4, PHP 7.4)
[purplemet] 2/4 gate(s) failed

Example — parsing gates in CI:

# Check if any gate failed
FAILED=$(echo "$RESULT" | jq '[.gates[] | select(.skipped == false and .passed == false)] | length')
if [ "$FAILED" -gt 0 ]; then
  echo "Failed gates:"
  echo "$RESULT" | jq -r '.gates[] | select(.passed == false and .skipped == false) | "  \(.name): \(.message)"'
fi

SARIF

SARIF 2.1.0 output is compatible with GitHub Code Scanning, Azure DevOps Advanced Security, and any SARIF viewer.

purplemet-cli analyze https://your-app.com --format sarif --output-file results.sarif

Structure:

  • Each unique issue type becomes a SARIF rule with its severity, CWE, and description
  • Each finding becomes a SARIF result referencing that rule
  • The analyzed URL is used as the artifact location
  • Analysis metadata and gate results are in runs[].properties

Severity mapping to SARIF levels:

Purplemet Severity SARIF Level
Critical, High error
Medium warning
Low, Info note

runs[].properties — analysis metadata:

Field Type Description
rating string Letter grade A–F
score int Numeric score (0–100, lower is better)
url string Analyzed URL
issueCnt int Total issue count
issueCnts object Issues by severity
cveCnt int CVE count
kevCnt int KEV count
gates object Per-gate pass/fail results (only configured gates)

These custom properties follow the SARIF 2.1.0 specification and are accessible by tools like GitHub Code Scanning, Defect Dojo, and any SARIF viewer that supports properties.

HTML

Generates a standalone HTML report suitable for sharing with stakeholders, archiving as audit evidence, or publishing as a CI/CD pipeline artifact.

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

The report is a self-contained .html file (no external dependencies) with a dark theme. It includes:

  • Security rating with color-coded badge (A–F)
  • Issue summary by severity (critical, high, medium, low, info)
  • Issue details table — severity, name, type, technology, CVSS, EPSS, CWE, description
  • Technologies table — name, version, category, flags (EOL, CVE count, latest version)
  • Certificates table — common name, issuer, expiry date, status
  • Sensitive services table — service name, port, protocol, IP address
  • Gates summary — configured gates with pass/fail status and failure messages
  • Overview metrics — total issues, CVE count, technology count, KEV count
  • Analysis details — ID, status, duration, WAF, remote IP, HTTP code, redirect URL, CLI version

Prioritizing Remediation

General security guidance — not Purplemet-specific. Refer to your organization's policies and the official Purplemet documentation for authoritative remediation workflows.

Common industry signals for prioritization:

  • CISA KEV catalog — vulnerabilities listed by CISA as actively exploited
  • EPSS score — probability of exploitation in the next 30 days (maintained by FIRST.org)
  • CVSS score — severity rating of a vulnerability (maintained by FIRST.org)
  • Public exploit availability
  • End-of-life status of affected components

Combine these with your context (internal vs public, data sensitivity, compensating controls) to set remediation priorities.

CVSS and EPSS in a nutshell

  • CVSS measures the severity of a vulnerability (how bad it is if exploited)
  • EPSS measures the probability of exploitation (how likely it will be exploited in the wild)

A high CVSS + high EPSS issue is typically the highest priority. See first.org/cvss and first.org/epss for authoritative definitions.

Recommended Gate Configurations

Staging / Pre-production

Start strict to catch issues before production:

purplemet-cli analyze https://staging.example.com --json \
  --fail-on-severity high \
  --fail-on-eol \
  --fail-on-kev \
  --fail-on-ssl \
  --fail-on-cert

Production Monitoring

Add broader checks for runtime concerns:

purplemet-cli analyze https://app.example.com --json \
  --fail-on-severity high \
  --fail-on-eol \
  --fail-on-kev \
  --fail-on-active-exploits \
  --fail-on-cert-expiry 30 \
  --require-waf \
  --fail-on-sensitive-services

Compliance-oriented

Combine severity with specific policy gates:

purplemet-cli analyze https://app.example.com --json \
  --fail-on-severity medium \
  --fail-on-cvss 7.0 \
  --fail-on-epss 0.5 \
  --fail-on-eol \
  --fail-on-ssl \
  --fail-on-headers \
  --fail-on-cookies \
  --fail-on-ossf-score 5.0 \
  --exclude-tech "php"

Progressive Rollout

Start permissive, tighten over time:

  1. Week 1: --fail-on-severity critical — block only critical issues
  2. Week 2: --fail-on-severity high --fail-on-kev — add high severity + known exploits
  3. Month 2: Add --fail-on-eol --fail-on-ssl --fail-on-cert
  4. Month 3: Add --fail-on-headers --fail-on-cookies --require-waf

This avoids overwhelming teams with hundreds of findings on day one.

Tracking Progress Over Time

Use the diff command to compare two analyses and measure improvement:

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

Output shows the delta for rating, score, issues, CVEs, and technologies:

Rating:  C → B
Score:   45 → 18 (-27)
Issues:  25 → 12 (-13)
CVEs:    5 → 1 (-4)

Use scheduled analyses (sites schedule or CI/CD cron) to monitor security posture continuously.

Clone this wiki locally