- Implement ProofChainTestFixture for PostgreSQL-backed integration tests. - Create StellaOps.Integration.ProofChain project with necessary dependencies. - Add ReachabilityIntegrationTests to validate call graph extraction and reachability analysis. - Introduce ReachabilityTestFixture for managing corpus and fixture paths. - Establish StellaOps.Integration.Reachability project with required references. - Develop UnknownsWorkflowTests to cover the unknowns lifecycle: detection, ranking, escalation, and resolution. - Create StellaOps.Integration.Unknowns project with dependencies for unknowns workflow.
24 KiB
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
- Overview
- Authentication
- Score Proofs API
- Reachability API
- Unknowns API
- Proof Chain API
- Data Models
- Error Handling
- Rate Limiting
- Examples
1. Overview
Design Principles
- Deterministic: All outputs use canonical JSON serialization (RFC 8785/JCS)
- Verifiable: DSSE signatures on all proof artifacts
- Idempotent:
Content-Digestheaders 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
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
{
"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
{
"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)
{
"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=<base64> - 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)
{
"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
{
"overrides": {
"concelierSnapshotHash": "sha256:newfeed...",
"excititorSnapshotHash": "sha256:newvex...",
"latticePolicyHash": "sha256:newpolicy..."
}
}
Response (200 OK)
{
"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
{
"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)
{
"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)
{
"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)
{
"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)
{
"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)
{
"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)
{
"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)
{
"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)
{
"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
{
"resolution": "not_affected",
"justification": "vulnerable_code_not_present",
"notes": "Manual analysis confirmed vulnerable function not used"
}
Response (200 OK)
{
"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)
{
"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:<hash>:pkg:<purl> |
sha256:abc:pkg:npm/lodash@4.17.21 |
Request
{
"evidenceIds": ["sha256:e7f8a9b0..."],
"reasoningId": "sha256:f0e1d2c3...",
"vexVerdictId": "sha256:d4c5b6a7...",
"policyVersion": "v1.2.3"
}
Response (201 Created)
{
"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)
{
"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)
{
"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
{
"proofBundleId": "sha256:1a2b3c4d...",
"checkRekor": true,
"anchorIds": ["anchor-001"]
}
Response (200 OK)
{
"proofBundleId": "sha256:1a2b3c4d...",
"verified": true,
"checks": {
"signatureValid": true,
"idRecomputed": true,
"merklePathValid": true,
"rekorInclusionValid": true
},
"errors": [],
"verifiedAt": "2025-12-17T10:00:00Z"
}
Verification Steps
- Signature Verification: Verify DSSE envelope against trust anchors
- ID Recomputation: Recompute content-addressed IDs and compare
- Merkle Path: Verify merkle tree construction
- Rekor Inclusion: Verify transparency log proof (if enabled)
7. Data Models
ScanManifest
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<string, string>;
}
ProofNode
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
interface DsseEnvelope {
payloadType: string;
payload: string; // base64 canonical JSON
signatures: DsseSignature[];
}
interface DsseSignature {
keyid: string;
sig: string; // base64
}
ReachabilityStatus
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
{
"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)
{
"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
# 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
# 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
# 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
# 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
Last Updated: 2025-12-20
API Version: 1.0.0
Sprint: 3500.0004.0004