io.atcr.hold.scan

did:web:lexicon.atcr.io

{
  "$type": "com.atproto.lexicon.schema",
  "defs": {
    "main": {
      "description": "Vulnerability scan results for a container manifest. Stored in the hold's embedded PDS. Record key is deterministic: the manifest digest hex without the 'sha256:' prefix, so re-scans upsert the existing record.",
      "key": "any",
      "record": {
        "properties": {
          "critical": {
            "description": "Count of critical severity vulnerabilities",
            "minimum": 0,
            "type": "integer"
          },
          "high": {
            "description": "Count of high severity vulnerabilities",
            "minimum": 0,
            "type": "integer"
          },
          "low": {
            "description": "Count of low severity vulnerabilities",
            "minimum": 0,
            "type": "integer"
          },
          "manifest": {
            "description": "AT-URI of the scanned manifest (e.g., at://did:plc:xyz/io.atcr.manifest/abc123...)",
            "format": "at-uri",
            "type": "string"
          },
          "medium": {
            "description": "Count of medium severity vulnerabilities",
            "minimum": 0,
            "type": "integer"
          },
          "reason": {
            "description": "Optional human-readable explanation for non-ok status (e.g. 'unscannable artifact type application/vnd.cncf.helm.config.v1+json').",
            "maxLength": 256,
            "type": "string"
          },
          "repository": {
            "description": "Repository name (e.g., myapp)",
            "maxLength": 256,
            "type": "string"
          },
          "sbomBlob": {
            "accept": [
              "application/spdx+json"
            ],
            "description": "SBOM blob (SPDX JSON format) uploaded to the hold's blob storage",
            "type": "blob"
          },
          "scannedAt": {
            "description": "RFC3339 timestamp of when the scan completed",
            "format": "datetime",
            "type": "string"
          },
          "scannerVersion": {
            "description": "Version of the scanner that produced this result (e.g., atcr-scanner-v1.0.0)",
            "maxLength": 64,
            "type": "string"
          },
          "status": {
            "description": "Outcome of the scan attempt. 'ok' (or omitted, for back-compat) means the scanner produced an SBOM. 'failed' means the scanner ran but errored. 'skipped' means the scanner intentionally bypassed this artifact type (e.g. helm charts).",
            "knownValues": [
              "ok",
              "failed",
              "skipped"
            ],
            "maxLength": 32,
            "type": "string"
          },
          "total": {
            "description": "Total vulnerability count",
            "minimum": 0,
            "type": "integer"
          },
          "userDid": {
            "description": "DID of the image owner",
            "format": "did",
            "type": "string"
          },
          "vulnReportBlob": {
            "accept": [
              "application/vnd.atcr.vulnerabilities+json"
            ],
            "description": "Grype vulnerability report blob (JSON) with full CVE details",
            "type": "blob"
          }
        },
        "required": [
          "manifest",
          "repository",
          "userDid",
          "critical",
          "high",
          "medium",
          "low",
          "total",
          "scannerVersion",
          "scannedAt"
        ],
        "type": "object"
      },
      "type": "record"
    }
  },
  "id": "io.atcr.hold.scan",
  "lexicon": 1
}

Validate Record

Validate a record against io.atcr.hold.scan

Validation Options
Treat any remaining unresolved references as valid

Metadata

DID
did:web:lexicon.atcr.io
CID
bafyreidqtmx2ivfrmj5cfki2zej5fgjqux4svdv3rrkv2evs5f2jdld5yi
Indexed At
2026-09-06 01:26 UTC
AT-URI
at://did:web:lexicon.atcr.io/com.atproto.lexicon.schema/io.atcr.hold.scan

Similar Lexicons

Lexicons whose schemas describe something close to this one. Check them before publishing a new one that overlaps.

  • Subscribe to vulnerability scan jobs via WebSocket. Scanners connect to receive pending scan jobs and send back results. Authenticated via shared secret (query parameter or X-Scanner-Secret header).

Lexicon Garden

@