Security Scan Data API
Machine-readable security review results for every indexed plugin — full snapshot, per-plugin JSON, scan state levels, and version binding. All data is static, cached, and free to reuse with attribution.
| URL | Description | Update |
|---|---|---|
/data/security-scan.json | Full snapshot — all plugins' scan results (verdict, counts, categories, hash, version) | daily 01:10 Beijing (17:10 UTC) |
/data/security-scan.schema.json | JSON Schema for the snapshot — machine-readable contract for field validation | append-only updates |
/artifact/<id>.json | Per-plugin JSON — derived scan state + scan record + version info | daily 01:10 Beijing (17:10 UTC) |
JSON endpoints allow cross-origin reads: Access-Control-Allow-Origin: *. No API key or registration is required.
Derived from the scan verdict via deriveBadgeState (src/scripts/badge-state.ts). Evaluation order: outdated → critical → medium → warning → stale → passed.
| Level | Condition | Meaning |
|---|---|---|
critical | verdict = fail | Critical findings in blocking categories (secrets / network / destructive / mining) |
medium | verdict = warn && critical > 0 | Non-blocking critical findings (code-exec / shell / install / obfuscation) — shown as needs-review |
warning | verdict = warn && critical = 0 | Warning-level findings only |
passed | verdict = pass | No critical/warning findings (info allowed) |
outdated | scan.commitSha ≠ plugin.latestCommitSha && scannedAt > 7d ago | Repo has newer commits and the scan is older than 7 days; result no longer describes current code |
stale | passed && scannedAt > 30d ago | Last passing scan is older than 30 days |
unscanned | no scan record | Not yet scanned (new plugin or scan failure) |
/data/security-scan.json is a single JSON object with the snapshot envelope below, not a bare map. Consumers should ignore unknown envelope fields.
| Field | Type | Semantics |
|---|---|---|
generated | string (YYYY-MM-DD) | Snapshot date derived from generatedAt |
generatedAt | string (ISO 8601) | Persisted pipeline snapshot time; never derived from web build time |
source | string | Human registry page this snapshot derives from |
schema | string | Absolute URL of the schema validating each scan record |
update | string | Current pipeline cadence and owner |
license | object | Provenance and reuse terms (attribution required) |
count | integer | Number of plugin ids in scans |
scans | object | Plugin-id to scan-record map; keys match plugins.json ids |
| Field | Type | Semantics |
|---|---|---|
verdict | pass|warn|fail | Scan conclusion (see levels above) |
counts | object | Finding counts by severity: critical / warning / info |
criticalByCategory | object | Critical findings grouped by category (shell, code-exec, secrets, network, destructive, obfuscation, install, mining) |
filesScanned | integer | Source files scanned (capped at 15) |
scannedAt | string (ISO) | When the scan ran |
commitSha | string | null | HEAD commit SHA at scan time — result valid only for this revision |
pkgVersion | string | null | Plugin's own version from package.json (zero-cost extraction) |
pkgDsh | boolean | Whether the repo declares a dsh manifest (package.json dsh field) |
latestCommitSha | string | null | Registry's latest known HEAD (updated by update-plugins; used for outdated detection) |
latestReleaseTag | string | null | Latest GitHub release tag (plugin's published semantic version) |
latestCommitSha and latestReleaseTag are plugin-level metadata from plugins.json, exposed through per-plugin JSON for convenience. They may be null while the pipeline backfills discovery data.
A scan result only describes the code at commitSha (the revision it ran on). New commits within 7 days are tolerated (the rating still counts); if the repository keeps moving and the scan is older than 7 days, the state degrades to outdated until the daily pipeline rescans. This prevents "certified-then-poisoned" scenarios.
Fetch the full snapshot or per-plugin data:
Security scan data is aggregated from public GitHub repositories by the dsh.so pipelines: incremental discovery every 2h at Beijing even hours (02:00-22:00), manual submissions on Beijing odd hours (03:00-23:00), full refresh daily at 00:00 Beijing, and security scan daily at 01:10 Beijing. Fields are append-only: existing fields are never removed or renamed, and new fields are added with a schema update. The snapshot and schema are free to reuse with attribution to dsh.so; check changelog for additions.