290 lines
7.7 KiB
Markdown
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)
|