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

290 lines
7.7 KiB
Markdown

# 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
```bash
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
```bash
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)
```json
{
"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
```json
{
"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:
```bash
# 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:
```bash
# 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
- [Evidence Bundle Format Specification](../modules/cli/guides/commands/evidence-bundle-format.md)
- [stella scan replay Command Reference](../modules/cli/guides/commands/scan-replay.md)
- [Unified Evidence Model](./evidence-api-reference.md)