Files
git.stella-ops.org/docs/api/triage-export-api-reference.md
2025-12-24 21:45:46 +02:00

7.7 KiB

Triage Evidence Export API Reference

Version: 1.0
Sprint: SPRINT_9200_0001_0002, SPRINT_9200_0001_0003
Status: Stable

Overview

The Triage Evidence Export API provides endpoints for downloading complete evidence packages as archives. These endpoints support both individual finding exports and batch exports for entire scan runs.

Base URL

/api/v1/triage

Endpoints

Export Finding Evidence Bundle

Downloads a complete evidence bundle for a single finding as a ZIP or TAR.GZ archive.

GET /findings/{findingId}/evidence/export

Path Parameters

Parameter Type Required Description
findingId string Yes Finding identifier

Query Parameters

Parameter Type Default Description
format string zip Archive format: zip, tar.gz, targz, tgz

Response Headers

Header Description
Content-Type application/zip or application/gzip
Content-Disposition attachment; filename="evidence-{findingId}.zip"
X-Archive-Digest SHA-256 digest of the archive: sha256:{digest}

Response Codes

Code Description
200 Success - archive stream returned
400 Invalid format specified
404 Finding not found

Example Request

curl -X GET \
  "https://api.stellaops.example/api/v1/triage/findings/f-abc123/evidence/export?format=zip" \
  -H "Authorization: Bearer <token>" \
  -o evidence-f-abc123.zip

Example Response

Binary stream of the archive file.

Get Unified Evidence

Retrieves the unified evidence package as JSON (not downloadable archive).

GET /findings/{findingId}/evidence

Path Parameters

Parameter Type Required Description
findingId string Yes Finding identifier

Query Parameters

Parameter Type Default Description
includeSbom boolean true Include SBOM evidence
includeReachability boolean true Include reachability evidence
includeVex boolean true Include VEX claims
includeAttestations boolean true Include attestations
includeDeltas boolean true Include delta evidence
includePolicy boolean true Include policy evidence
includeReplayCommand boolean true Include replay command

Response Headers

Header Description
ETag Content-addressed cache key: "{cacheKey}"
Cache-Control private, max-age=300

Response Codes

Code Description
200 Success - evidence returned
304 Not Modified (ETag match)
404 Finding not found

Example Request

curl -X GET \
  "https://api.stellaops.example/api/v1/triage/findings/f-abc123/evidence" \
  -H "Authorization: Bearer <token>" \
  -H "If-None-Match: \"sha256:abc123...\""

Example Response (200 OK)

{
  "findingId": "f-abc123",
  "cveId": "CVE-2024-1234",
  "componentPurl": "pkg:npm/lodash@4.17.15",
  "sbom": {
    "format": "cyclonedx",
    "version": "1.5",
    "documentUri": "/sboms/sha256:abc123",
    "digest": "sha256:abc123...",
    "component": {
      "purl": "pkg:npm/lodash@4.17.15",
      "name": "lodash",
      "version": "4.17.15",
      "ecosystem": "npm"
    }
  },
  "reachability": {
    "subgraphId": "sg-xyz789",
    "status": "reachable",
    "confidence": 0.95,
    "method": "static",
    "entryPoints": [...]
  },
  "vexClaims": [...],
  "attestations": [...],
  "deltas": {...},
  "policy": {...},
  "manifests": {
    "artifactDigest": "sha256:a1b2c3...",
    "manifestHash": "sha256:def456...",
    "feedSnapshotHash": "sha256:feed789...",
    "policyHash": "sha256:policy321..."
  },
  "verification": {
    "status": "verified",
    "hashesVerified": true,
    "attestationsVerified": true,
    "evidenceComplete": true
  },
  "replayCommand": "stella scan replay --artifact sha256:a1b2c3... --manifest sha256:def456... --feeds sha256:feed789... --policy sha256:policy321...",
  "shortReplayCommand": "stella replay snapshot --verdict V-12345",
  "evidenceBundleUrl": "/v1/triage/findings/f-abc123/evidence/export",
  "generatedAt": "2025-01-15T10:30:00Z",
  "cacheKey": "sha256:unique123..."
}

Get Replay Command

Retrieves the replay command for a finding.

GET /findings/{findingId}/replay-command

Path Parameters

Parameter Type Required Description
findingId string Yes Finding identifier

Query Parameters

Parameter Type Default Description
shells string[] ["bash"] Target shells: bash, powershell, cmd
includeOffline boolean false Include offline replay variant
generateBundle boolean false Generate evidence bundle

Response Codes

Code Description
200 Success - replay command returned
404 Finding not found

Example Response

{
  "findingId": "f-abc123",
  "commands": {
    "bash": "stella scan replay --artifact sha256:a1b2c3... --manifest sha256:def456... --feeds sha256:feed789... --policy sha256:policy321...",
    "powershell": "stella scan replay --artifact sha256:a1b2c3... --manifest sha256:def456... --feeds sha256:feed789... --policy sha256:policy321..."
  },
  "shortCommand": "stella replay snapshot --verdict V-12345",
  "inputHashes": {
    "artifactDigest": "sha256:a1b2c3...",
    "manifestHash": "sha256:def456...",
    "feedSnapshotHash": "sha256:feed789...",
    "policyHash": "sha256:policy321..."
  },
  "bundleUrl": "/v1/triage/findings/f-abc123/evidence/export",
  "generatedAt": "2025-01-15T10:30:00Z"
}

Get Scan Replay Command

Retrieves the replay command for an entire scan.

GET /scans/{scanId}/replay-command

Path Parameters

Parameter Type Required Description
scanId string Yes Scan identifier

Query Parameters

Same as finding replay command endpoint.

Response Codes

Code Description
200 Success - replay command returned
404 Scan not found

ETag Caching

The unified evidence endpoint supports HTTP caching via ETag/If-None-Match:

  1. Initial request: Returns evidence with ETag header
  2. Subsequent requests: Include If-None-Match: "{etag}" header
  3. If unchanged: Returns 304 Not Modified (no body)
  4. If changed: Returns 200 OK with new evidence and ETag

Example flow:

# Initial request
curl -i "https://api.stellaops.example/api/v1/triage/findings/f-abc123/evidence"
# Response: 200 OK, ETag: "sha256:abc123..."

# Conditional request
curl -i "https://api.stellaops.example/api/v1/triage/findings/f-abc123/evidence" \
  -H 'If-None-Match: "sha256:abc123..."'
# Response: 304 Not Modified (if unchanged)

Archive Integrity

To verify downloaded archives:

# Get expected digest from header
EXPECTED=$(curl -sI ".../evidence/export" | grep X-Archive-Digest | cut -d: -f2-)

# Download and verify
curl -o evidence.zip ".../evidence/export"
ACTUAL=$(sha256sum evidence.zip | cut -d' ' -f1)

if [ "sha256:$ACTUAL" = "$EXPECTED" ]; then
    echo "Archive verified"
else
    echo "Verification failed!"
    exit 1
fi

See Also