# Score Proofs & Reachability API Reference > **Version**: 1.0.0 > **Sprint**: 3500.0004.0004 > **Status**: Complete This document provides the complete API reference for Score Proofs, Reachability Analysis, and Unknowns management features. It consolidates documentation from multiple source files into a single reference. --- ## Table of Contents 1. [Overview](#1-overview) 2. [Authentication](#2-authentication) 3. [Score Proofs API](#3-score-proofs-api) 4. [Reachability API](#4-reachability-api) 5. [Unknowns API](#5-unknowns-api) 6. [Proof Chain API](#6-proof-chain-api) 7. [Data Models](#7-data-models) 8. [Error Handling](#8-error-handling) 9. [Rate Limiting](#9-rate-limiting) 10. [Examples](#10-examples) --- ## 1. Overview ### Design Principles - **Deterministic**: All outputs use canonical JSON serialization (RFC 8785/JCS) - **Verifiable**: DSSE signatures on all proof artifacts - **Idempotent**: `Content-Digest` headers enable safe retries - **Offline-First**: All bundles downloadable for air-gap verification ### Base URLs | Service | Base URL | Description | |---------|----------|-------------| | Scanner | `/api/v1/scanner` | Scan management, reachability | | Proofs | `/api/v1/proofs` | Proof chain creation/verification | | Unknowns | `/api/v1/unknowns` | Unknowns triage and escalation | ### Supported Content Types | Type | Description | |------|-------------| | `application/json` | Standard JSON (responses are canonical) | | `application/x-ndjson` | Streaming NDJSON for large call graphs | | `application/zip` | Proof bundle archives | --- ## 2. Authentication All endpoints require OAuth 2.0 Bearer token authentication. ### Token Request ```http POST /connect/token Content-Type: application/x-www-form-urlencoded grant_type=client_credentials& client_id=ci-bot& client_secret=REDACTED& scope=scanner.scans scanner.proofs scanner.unknowns ``` ### Response ```json { "access_token": "eyJraWQi...", "token_type": "Bearer", "expires_in": 3600 } ``` ### Required Scopes | Scope | Description | |-------|-------------| | `scanner.scans` | Create/read scans and manifests | | `scanner.proofs` | Access proof bundles | | `scanner.unknowns` | Read/manage unknowns | | `scanner.unknowns:write` | Escalate unknowns | | `proofs.read` | Read proof chains | | `proofs.write` | Create proof spines | | `proofs.verify` | Verify proofs | | `anchors.manage` | Manage trust anchors | --- ## 3. Score Proofs API ### 3.1 Create Scan with Manifest **POST** `/api/v1/scanner/scans` Creates a new scan with deterministic manifest for replay. #### Request ```json { "artifactDigest": "sha256:abc123...", "artifactPurl": "pkg:oci/myapp@sha256:abc123...", "scannerVersion": "1.0.0", "workerVersion": "1.0.0", "concelierSnapshotHash": "sha256:feed123...", "excititorSnapshotHash": "sha256:vex456...", "latticePolicyHash": "sha256:policy789...", "deterministic": true, "seed": "AQIDBA==", "knobs": { "maxDepth": "10", "indirectCallResolution": "conservative" } } ``` #### Response (201 Created) ```json { "scanId": "550e8400-e29b-41d4-a716-446655440000", "manifestHash": "sha256:manifest123...", "createdAt": "2025-12-17T12:00:00Z", "_links": { "self": "/api/v1/scanner/scans/550e8400-e29b-41d4-a716-446655440000", "manifest": "/api/v1/scanner/scans/550e8400-e29b-41d4-a716-446655440000/manifest" } } ``` #### Headers | Header | Description | |--------|-------------| | `Content-Digest` | `sha256=` - Idempotency key | | `Location` | URL of created scan | #### Errors | Code | Type | Description | |------|------|-------------| | 400 | `invalid-manifest` | Manifest validation failed | | 409 | `duplicate-scan` | Scan with same manifest hash exists | | 422 | `snapshot-not-found` | Feed/VEX snapshot not found | --- ### 3.2 Get Scan Manifest **GET** `/api/v1/scanner/scans/{scanId}/manifest` Retrieves canonical JSON manifest with DSSE signature. #### Response (200 OK) ```json { "manifest": { "scanId": "550e8400-e29b-41d4-a716-446655440000", "createdAtUtc": "2025-12-17T12:00:00Z", "artifactDigest": "sha256:abc123...", "artifactPurl": "pkg:oci/myapp@sha256:abc123...", "scannerVersion": "1.0.0", "workerVersion": "1.0.0", "concelierSnapshotHash": "sha256:feed123...", "excititorSnapshotHash": "sha256:vex456...", "latticePolicyHash": "sha256:policy789...", "deterministic": true, "seed": "AQIDBA==", "knobs": {"maxDepth": "10"} }, "manifestHash": "sha256:manifest123...", "dsseEnvelope": { "payloadType": "application/vnd.stellaops.scan-manifest.v1+json", "payload": "eyJzY2FuSWQiOiIuLi4ifQ==", "signatures": [ {"keyid": "ecdsa-p256-key-001", "sig": "MEUCIQDx..."} ] } } ``` --- ### 3.3 Replay Score Computation **POST** `/api/v1/scanner/scans/{scanId}/score/replay` Recomputes score proofs using updated feeds/policies without rescanning. #### Request ```json { "overrides": { "concelierSnapshotHash": "sha256:newfeed...", "excititorSnapshotHash": "sha256:newvex...", "latticePolicyHash": "sha256:newpolicy..." } } ``` #### Response (200 OK) ```json { "scanId": "550e8400-e29b-41d4-a716-446655440000", "replayedAt": "2025-12-17T13:00:00Z", "scoreProof": { "rootHash": "sha256:proof123...", "nodes": [ { "id": "input-1", "kind": "Input", "ruleId": "inputs.v1", "delta": 0.0, "total": 0.0, "nodeHash": "sha256:node1..." }, { "id": "delta-cvss", "kind": "Delta", "ruleId": "score.cvss_base.weighted", "parentIds": ["input-1"], "evidenceRefs": ["cvss:9.1"], "delta": 0.50, "total": 0.50, "nodeHash": "sha256:node2..." } ] }, "proofBundleUri": "/api/v1/scanner/scans/.../proofs/sha256:proof123..." } ``` --- ### 3.4 Fetch Proof Bundle **GET** `/api/v1/scanner/scans/{scanId}/proofs/{rootHash}` Downloads proof bundle ZIP archive for offline verification. #### Response Headers | Header | Value | |--------|-------| | `Content-Type` | `application/zip` | | `Content-Disposition` | `attachment; filename="proof-{scanId}-{rootHash}.zip"` | | `X-Proof-Root-Hash` | Proof root hash | | `X-Manifest-Hash` | Manifest hash | #### Bundle Contents | File | Description | |------|-------------| | `manifest.json` | Canonical scan manifest | | `manifest.dsse.json` | DSSE signature of manifest | | `score_proof.json` | Proof ledger (ProofNode array) | | `proof_root.dsse.json` | DSSE signature of proof root | | `meta.json` | Metadata (timestamps, versions) | --- ## 4. Reachability API ### 4.1 Upload Call Graph **POST** `/api/v1/scanner/scans/{scanId}/callgraphs` Uploads language-specific call graph extracted by workers. #### Request ```json { "schema": "stella.callgraph.v1", "language": "dotnet", "artifacts": [ { "artifactKey": "MyApp.WebApi.dll", "kind": "assembly", "sha256": "sha256:artifact123..." } ], "nodes": [ { "nodeId": "sha256:node1...", "artifactKey": "MyApp.WebApi.dll", "symbolKey": "MyApp.Controllers.OrdersController::Get(System.Guid)", "visibility": "public", "isEntrypointCandidate": true } ], "edges": [ { "from": "sha256:node1...", "to": "sha256:node2...", "kind": "static", "reason": "direct_call", "weight": 1.0 } ], "entrypoints": [ { "nodeId": "sha256:node1...", "kind": "http", "route": "/api/orders/{id}", "framework": "aspnetcore" } ] } ``` #### Response (202 Accepted) ```json { "scanId": "550e8400-e29b-41d4-a716-446655440000", "callGraphDigest": "sha256:cg123...", "nodesCount": 1234, "edgesCount": 5678, "entrypointsCount": 12, "status": "accepted" } ``` --- ### 4.2 Compute Reachability **POST** `/api/v1/scanner/scans/{scanId}/reachability/compute` Triggers reachability analysis for uploaded call graph. #### Response (202 Accepted) ```json { "scanId": "550e8400-e29b-41d4-a716-446655440000", "jobId": "reachability-job-001", "status": "queued", "estimatedDuration": "30s", "_links": { "status": "/api/v1/scanner/jobs/reachability-job-001", "results": "/api/v1/scanner/scans/.../reachability/findings" } } ``` --- ### 4.3 Get Reachability Findings **GET** `/api/v1/scanner/scans/{scanId}/reachability/findings` Retrieves reachability verdicts for all vulnerabilities. #### Query Parameters | Parameter | Type | Description | |-----------|------|-------------| | `status` | string | Filter: `REACHABLE`, `UNREACHABLE`, `POSSIBLY_REACHABLE`, `UNKNOWN` | | `cveId` | string | Filter by CVE ID | #### Response (200 OK) ```json { "scanId": "550e8400-e29b-41d4-a716-446655440000", "computedAt": "2025-12-17T12:30:00Z", "findings": [ { "cveId": "CVE-2024-1234", "purl": "pkg:npm/lodash@4.17.20", "status": "REACHABLE_STATIC", "confidence": 0.70, "path": [ { "nodeId": "sha256:entrypoint...", "symbolKey": "MyApp.Controllers.OrdersController::Get(System.Guid)" }, { "nodeId": "sha256:vuln...", "symbolKey": "Lodash.merge(Object, Object)" } ], "evidence": { "pathLength": 3, "staticEdgesOnly": true, "runtimeConfirmed": false } } ], "summary": { "total": 45, "reachable": 3, "unreachable": 38, "possiblyReachable": 4, "unknown": 0 } } ``` --- ### 4.4 Explain Reachability **GET** `/api/v1/scanner/scans/{scanId}/reachability/explain` Provides detailed explanation for a reachability verdict. #### Query Parameters | Parameter | Required | Description | |-----------|----------|-------------| | `cve` | Yes | CVE ID | | `purl` | Yes | Package URL | #### Response (200 OK) ```json { "cveId": "CVE-2024-1234", "purl": "pkg:npm/lodash@4.17.20", "status": "REACHABLE_STATIC", "confidence": 0.70, "explanation": { "shortestPath": [ { "depth": 0, "nodeId": "sha256:entry...", "symbolKey": "MyApp.Controllers.OrdersController::Get(System.Guid)", "entrypointKind": "http", "route": "/api/orders/{id}" }, { "depth": 1, "nodeId": "sha256:inter...", "symbolKey": "MyApp.Services.OrderService::Process(Order)", "edgeKind": "static", "edgeReason": "direct_call" }, { "depth": 2, "nodeId": "sha256:vuln...", "symbolKey": "Lodash.merge(Object, Object)", "edgeKind": "static", "vulnerableFunction": true } ], "whyReachable": [ "Static call path exists from HTTP entrypoint /api/orders/{id}", "All edges are statically proven (no heuristics)", "Vulnerable function Lodash.merge() is directly invoked" ], "confidenceFactors": { "staticPathExists": 0.50, "noHeuristicEdges": 0.20, "runtimeConfirmed": 0.00 } }, "alternativePaths": 2 } ``` --- ## 5. Unknowns API ### 5.1 List Unknowns **GET** `/api/v1/unknowns` Returns paginated list of unknowns ranked by priority score. #### Query Parameters | Parameter | Type | Default | Description | |-----------|------|---------|-------------| | `sort` | string | `score` | Sort field: `score`, `created_at`, `blast_dependents` | | `order` | string | `desc` | Sort order: `asc`, `desc` | | `page` | int | 1 | Page number (1-indexed) | | `pageSize` | int | 50 | Items per page (max 200) | | `artifact` | string | — | Filter by artifact digest | | `reason` | string | — | Filter by reason code | | `minScore` | float | — | Minimum score threshold (0-1) | | `maxScore` | float | — | Maximum score threshold (0-1) | | `kev` | bool | — | Filter by KEV status | | `seccomp` | string | — | Filter by seccomp: `enforced`, `permissive`, `unknown` | #### Response (200 OK) ```json { "items": [ { "id": "unk-12345678-abcd-1234-5678-abcdef123456", "artifactDigest": "sha256:abc123...", "artifactPurl": "pkg:oci/myapp@sha256:abc123", "reasons": ["missing_vex", "ambiguous_indirect_call"], "blastRadius": { "dependents": 15, "netFacing": true, "privilege": "user" }, "evidenceScarcity": 0.7, "exploitPressure": { "epss": 0.45, "kev": false }, "containment": { "seccomp": "enforced", "fs": "ro" }, "score": 0.62, "proofRef": "proofs/unknowns/unk-12345678/tree.json", "createdAt": "2025-01-15T10:30:00Z", "updatedAt": "2025-01-15T10:30:00Z" } ], "pagination": { "page": 1, "pageSize": 50, "totalItems": 142, "totalPages": 3 } } ``` --- ### 5.2 Get Unknown by ID **GET** `/api/v1/unknowns/{id}` Returns detailed information about a specific unknown. #### Response (200 OK) ```json { "id": "unk-12345678-abcd-1234-5678-abcdef123456", "artifactDigest": "sha256:abc123...", "artifactPurl": "pkg:oci/myapp@sha256:abc123", "reasons": ["missing_vex", "ambiguous_indirect_call"], "reasonDetails": [ { "code": "missing_vex", "message": "No VEX statement found for CVE-2024-1234", "component": "pkg:npm/lodash@4.17.20" }, { "code": "ambiguous_indirect_call", "message": "Indirect call target could not be resolved", "location": "src/utils.js:42" } ], "blastRadius": { "dependents": 15, "netFacing": true, "privilege": "user" }, "score": 0.62, "scoreBreakdown": { "blastComponent": 0.35, "scarcityComponent": 0.21, "pressureComponent": 0.26, "containmentDeduction": -0.20 }, "createdAt": "2025-01-15T10:30:00Z", "updatedAt": "2025-01-15T10:30:00Z" } ``` --- ### 5.3 Get Unknown Proof **GET** `/api/v1/unknowns/{id}/proof` Returns the proof tree explaining the ranking decision. #### Response (200 OK) ```json { "version": "1.0", "unknownId": "unk-12345678-abcd-1234-5678-abcdef123456", "nodes": [ { "kind": "input", "hash": "sha256:abc...", "data": { "reasons": ["missing_vex"], "evidenceScarcity": 0.7 } }, { "kind": "delta", "hash": "sha256:def...", "factor": "blast_radius", "contribution": 0.35 }, { "kind": "delta", "hash": "sha256:ghi...", "factor": "containment_seccomp", "contribution": -0.10 }, { "kind": "score", "hash": "sha256:jkl...", "finalScore": 0.62 } ], "rootHash": "sha256:mno..." } ``` --- ### 5.4 Escalate Unknown **POST** `/api/v1/unknowns/{id}/escalate` Escalates an unknown to trigger immediate rescan/re-analysis. #### Response (202 Accepted) ```json { "unknownId": "unk-001", "escalatedAt": "2025-12-17T12:00:00Z", "rescanJobId": "rescan-job-001", "status": "queued" } ``` #### Errors | Code | Description | |------|-------------| | 404 | Unknown ID not found | | 409 | Unknown already escalated (rescan in progress) | --- ### 5.5 Resolve Unknown **POST** `/api/v1/unknowns/{id}/resolve` Marks an unknown as resolved with resolution details. #### Request ```json { "resolution": "not_affected", "justification": "vulnerable_code_not_present", "notes": "Manual analysis confirmed vulnerable function not used" } ``` #### Response (200 OK) ```json { "unknownId": "unk-001", "resolvedAt": "2025-12-17T12:00:00Z", "resolution": "not_affected", "resolvedBy": "analyst@example.com" } ``` --- ### 5.6 Get Unknowns Summary **GET** `/api/v1/unknowns/summary` Returns aggregate statistics about unknowns. #### Response (200 OK) ```json { "totalCount": 142, "byReason": { "missing_vex": 45, "ambiguous_indirect_call": 32, "incomplete_sbom": 28, "unknown_platform": 15, "other": 22 }, "byScoreBucket": { "critical": 12, "high": 35, "medium": 48, "low": 47 }, "byContainment": { "enforced": 45, "permissive": 32, "unknown": 65 }, "kevCount": 8, "avgScore": 0.52 } ``` --- ## 6. Proof Chain API ### 6.1 Create Proof Spine **POST** `/api/v1/proofs/{entry}/spine` Creates a proof spine for an SBOM entry. #### Path Parameters | Parameter | Format | Example | |-----------|--------|---------| | `entry` | `sha256::pkg:` | `sha256:abc:pkg:npm/lodash@4.17.21` | #### Request ```json { "evidenceIds": ["sha256:e7f8a9b0..."], "reasoningId": "sha256:f0e1d2c3...", "vexVerdictId": "sha256:d4c5b6a7...", "policyVersion": "v1.2.3" } ``` #### Response (201 Created) ```json { "proofBundleId": "sha256:1a2b3c4d...", "receiptUrl": "/proofs/sha256:abc:pkg:npm/lodash@4.17.21/receipt" } ``` --- ### 6.2 Get Proof Spine **GET** `/api/v1/proofs/{entry}/spine` Gets the proof spine for an SBOM entry. #### Response (200 OK) ```json { "sbomEntryId": "sha256:abc123:pkg:npm/lodash@4.17.21", "proofBundleId": "sha256:1a2b3c4d...", "evidenceIds": ["sha256:e7f8a9b0..."], "reasoningId": "sha256:f0e1d2c3...", "vexVerdictId": "sha256:d4c5b6a7...", "policyVersion": "v1.2.3", "createdAt": "2025-12-17T10:00:00Z" } ``` --- ### 6.3 Get Verification Receipt **GET** `/api/v1/proofs/{entry}/receipt` Gets the human-readable verification receipt. #### Response (200 OK) ```json { "graphRevisionId": "grv_sha256:9f8e7d6c...", "findingKey": { "sbomEntryId": "sha256:abc123:pkg:npm/lodash@4.17.21", "vulnerabilityId": "CVE-2025-1234" }, "rule": { "id": "critical-vuln-block", "version": "v1.0.0" }, "decision": { "verdict": "pass", "severity": "none", "reasoning": "Not affected - vulnerable code not present" }, "createdAt": "2025-12-17T10:00:00Z", "verified": true } ``` --- ### 6.4 Verify Proof Bundle **POST** `/api/v1/proofs/verify` Performs full verification of a proof bundle. #### Request ```json { "proofBundleId": "sha256:1a2b3c4d...", "checkRekor": true, "anchorIds": ["anchor-001"] } ``` #### Response (200 OK) ```json { "proofBundleId": "sha256:1a2b3c4d...", "verified": true, "checks": { "signatureValid": true, "idRecomputed": true, "merklePathValid": true, "rekorInclusionValid": true }, "errors": [], "verifiedAt": "2025-12-17T10:00:00Z" } ``` #### Verification Steps 1. **Signature Verification**: Verify DSSE envelope against trust anchors 2. **ID Recomputation**: Recompute content-addressed IDs and compare 3. **Merkle Path**: Verify merkle tree construction 4. **Rekor Inclusion**: Verify transparency log proof (if enabled) --- ## 7. Data Models ### ScanManifest ```typescript interface ScanManifest { scanId: string; createdAtUtc: string; // ISO 8601 artifactDigest: string; // sha256:... artifactPurl: string; // pkg:oci/... scannerVersion: string; workerVersion: string; concelierSnapshotHash: string; excititorSnapshotHash: string; latticePolicyHash: string; deterministic: boolean; seed: string; // base64 knobs: Record; } ``` ### ProofNode ```typescript interface ProofNode { id: string; kind: "Input" | "Transform" | "Delta" | "Score"; ruleId: string; parentIds: string[]; evidenceRefs: string[]; delta: number; total: number; actor: string; tsUtc: string; seed: string; nodeHash: string; } ``` ### DsseEnvelope ```typescript interface DsseEnvelope { payloadType: string; payload: string; // base64 canonical JSON signatures: DsseSignature[]; } interface DsseSignature { keyid: string; sig: string; // base64 } ``` ### ReachabilityStatus ```typescript enum ReachabilityStatus { UNREACHABLE = "UNREACHABLE", POSSIBLY_REACHABLE = "POSSIBLY_REACHABLE", REACHABLE_STATIC = "REACHABLE_STATIC", REACHABLE_PROVEN = "REACHABLE_PROVEN", UNKNOWN = "UNKNOWN" } ``` ### UnknownReasonCode | Code | Description | |------|-------------| | `missing_vex` | No VEX statement for vulnerability | | `ambiguous_indirect_call` | Indirect call target unresolved | | `incomplete_sbom` | SBOM missing component data | | `unknown_platform` | Platform not recognized | | `missing_advisory` | No advisory data for CVE | | `conflicting_evidence` | Multiple conflicting data sources | | `stale_data` | Data exceeds freshness threshold | --- ## 8. Error Handling All errors follow RFC 7807 Problem Details format. ### Error Response ```json { "type": "https://stella-ops.org/errors/scan-not-found", "title": "Scan Not Found", "status": 404, "detail": "Scan ID '550e8400...' does not exist.", "instance": "/api/v1/scanner/scans/550e8400...", "traceId": "trace-001" } ``` ### Error Types | Type | Status | Description | |------|--------|-------------| | `scan-not-found` | 404 | Scan ID not found | | `invalid-manifest` | 400 | Manifest validation failed | | `duplicate-scan` | 409 | Scan with same manifest hash exists | | `snapshot-not-found` | 422 | Feed/VEX snapshot not found | | `callgraph-not-uploaded` | 422 | Call graph required before reachability | | `payload-too-large` | 413 | Request body exceeds size limit | | `proof-not-found` | 404 | Proof root hash not found | | `unknown-not-found` | 404 | Unknown ID not found | | `escalation-conflict` | 409 | Unknown already escalated | | `rate-limit-exceeded` | 429 | Rate limit exceeded | --- ## 9. Rate Limiting ### Limits by Endpoint | Endpoint | Limit | Window | |----------|-------|--------| | `POST /scans` | 100 | 1 hour | | `POST /scans/{id}/score/replay` | 1000 | 1 hour | | `POST /callgraphs` | 100 | 1 hour | | `POST /reachability/compute` | 100 | 1 hour | | `GET` endpoints | 10,000 | 1 hour | | `GET /unknowns` | 100 | 1 minute | | `GET /unknowns/{id}` | 300 | 1 minute | ### Response Headers | Header | Description | |--------|-------------| | `X-RateLimit-Limit` | Maximum requests per window | | `X-RateLimit-Remaining` | Remaining requests | | `X-RateLimit-Reset` | Unix timestamp when limit resets | ### Rate Limit Error (429) ```json { "type": "https://stella-ops.org/errors/rate-limit-exceeded", "title": "Rate Limit Exceeded", "status": 429, "detail": "Exceeded 100 requests/hour for POST /scans.", "retryAfter": 1234567890 } ``` --- ## 10. Examples ### Example 1: Complete Scan Workflow ```bash # 1. Create scan with manifest SCAN_RESP=$(curl -X POST https://scanner.example.com/api/v1/scanner/scans \ -H "Authorization: Bearer $TOKEN" \ -H "Content-Type: application/json" \ -d '{ "artifactDigest": "sha256:abc123...", "artifactPurl": "pkg:oci/myapp@sha256:abc123...", "concelierSnapshotHash": "sha256:feed...", "excititorSnapshotHash": "sha256:vex...", "latticePolicyHash": "sha256:policy...", "deterministic": true }') SCAN_ID=$(echo $SCAN_RESP | jq -r '.scanId') # 2. Upload call graph curl -X POST "https://scanner.example.com/api/v1/scanner/scans/$SCAN_ID/callgraphs" \ -H "Authorization: Bearer $TOKEN" \ -H "Content-Type: application/json" \ -H "Content-Digest: sha256=abc123..." \ -d @callgraph.json # 3. Compute reachability curl -X POST "https://scanner.example.com/api/v1/scanner/scans/$SCAN_ID/reachability/compute" \ -H "Authorization: Bearer $TOKEN" # 4. Get findings curl "https://scanner.example.com/api/v1/scanner/scans/$SCAN_ID/reachability/findings" \ -H "Authorization: Bearer $TOKEN" ``` ### Example 2: Score Replay ```bash # Replay with updated feeds curl -X POST "https://scanner.example.com/api/v1/scanner/scans/$SCAN_ID/score/replay" \ -H "Authorization: Bearer $TOKEN" \ -H "Content-Type: application/json" \ -d '{ "overrides": { "concelierSnapshotHash": "sha256:newfeed..." } }' ``` ### Example 3: Unknowns Management ```bash # List high-priority unknowns curl "https://scanner.example.com/api/v1/unknowns?minScore=0.7&sort=score&order=desc" \ -H "Authorization: Bearer $TOKEN" # Escalate for rescan curl -X POST "https://scanner.example.com/api/v1/unknowns/unk-001/escalate" \ -H "Authorization: Bearer $TOKEN" ``` ### Example 4: Proof Verification ```bash # Download proof bundle curl -o proof.zip \ "https://scanner.example.com/api/v1/scanner/scans/$SCAN_ID/proofs/sha256:proof123..." # Verify bundle curl -X POST "https://scanner.example.com/api/v1/proofs/verify" \ -H "Authorization: Bearer $TOKEN" \ -H "Content-Type: application/json" \ -d '{ "proofBundleId": "sha256:1a2b3c4d...", "checkRekor": true }' ``` --- ## Related Documentation - [Scanner Architecture](../modules/scanner/architecture.md) - [Attestor Architecture](../modules/attestor/architecture.md) - [Policy Engine](../modules/policy/architecture.md) - [CLI Reference](./cli-reference.md) - [OpenAPI Specification](../src/Api/StellaOps.Api.OpenApi/scanner/openapi.yaml) --- **Last Updated**: 2025-12-20 **API Version**: 1.0.0 **Sprint**: 3500.0004.0004