Security Certification Data API
Machine-readable security review results per plugin — verdict, counts, concrete findings, scan state levels, and version binding. All data is static, cached, and free to reuse with attribution.
| URL | Description | Update |
|---|---|---|
/data/security-scan.schema.json | JSON Schema for the scan-record format — machine-readable contract for field validation (also validates the internal data file) | append-only updates |
/artifact/@author/plugin.json | Per-plugin JSON — derived scan state + full scan record (verdict / counts / categories / findings) + version info | daily 01:10 Beijing (17:10 UTC) |
/plugins-index.json | Registry summary — every plugin's status / risk level / counts (no findings detail). Docs: /data/plugins-index/ | daily 01:10 Beijing (17:10 UTC) |
JSON endpoints allow cross-origin reads: Access-Control-Allow-Origin: *. No API key or registration is required. Plugins without a scan record return 404.
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) |
| 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) |
findings | array | Concrete findings — ruleId / severity / category / file / line / snippet, capped at 12 per plugin |
filesScanned | integer | Source files scanned (capped at 15) |
scannerVersion | string | null | Ruleset content fingerprint (e.g. dsh-static:xxxxxxxx) — identifies which rule set this scan ran under; same fingerprint = same rules, so consumers can align or reproduce the result. May be null for records scanned before this field was persisted (backfilled by the daily full rescan) |
rulesChecked | integer | null | Rules from the set that actually ran against at least one file (doc-only repos skip skipInDocs rules, so this may be below the full set size). Together with scannerVersion it makes coverage perceivable. May be null for legacy records |
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.
Boundary: findings rows (rule id / file / line / snippet) are per-plugin evidence so authors can see what triggered and contest it — they describe this plugin's code, not how the scanner's rules are implemented. Rule implementations stay private; only the rule-set fingerprint (scannerVersion) is published.
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.
Scan verdicts come from deterministic static rules and can misfire — false positive, wrong basis, or a stale revision. Plugin authors can contest a result through the feedback page (filed as a tracked issue, no GitHub account needed). Include the plugin id, the scan's commitSha, the offending ruleId and a short reason; maintainers review and schedule a re-scan.
Query one plugin (or open /artifact/@dsh-so/dsh-code-security.json in a browser):
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. Per-plugin JSON and the schema are free to reuse with attribution to dsh.so. Check changelog for additions.