Add unit tests for PackRunAttestation and SealedInstallEnforcer
Some checks failed
Docs CI / lint-and-preview (push) Has been cancelled
AOC Guard CI / aoc-guard (push) Has been cancelled
AOC Guard CI / aoc-verify (push) Has been cancelled
Concelier Attestation Tests / attestation-tests (push) Has been cancelled
Policy Lint & Smoke / policy-lint (push) Has been cancelled
release-manifest-verify / verify (push) Has been cancelled

- Implement comprehensive tests for PackRunAttestationService, covering attestation generation, verification, and event emission.
- Add tests for SealedInstallEnforcer to validate sealed install requirements and enforcement logic.
- Introduce a MonacoLoaderService stub for testing purposes to prevent Monaco workers/styles from loading during Karma runs.
This commit is contained in:
StellaOps Bot
2025-12-06 22:25:30 +02:00
parent dd0067ea0b
commit 4042fc2184
110 changed files with 20084 additions and 639 deletions

View File

@@ -12,5 +12,9 @@
- Notification hook contract (`exception.*` events) and rate-limit policy.
- Sample payloads for each state and error cases.
## Draft sample (placeholder)
- See `docs/api/console/samples/exception-schema-sample.json` for a skeleton payload covering `pending_review` state.
- Replace with authoritative samples once schema is published.
## TODO
- Replace with ratified schema + samples; log hash/date; link from Web I/II sprint logs.

View File

@@ -0,0 +1,14 @@
event: started
data: {"exportId":"console-export::tenant-default::2025-12-06::0007","status":"running","percent":0}
event: progress
data: {"exportId":"console-export::tenant-default::2025-12-06::0007","percent":25,"itemsCompleted":125,"itemsTotal":500}
event: asset_ready
data: {"exportId":"console-export::tenant-default::2025-12-06::0007","type":"advisory","id":"CVE-2024-12345","url":"https://exports.local/...","sha256":"cafe0001..."}
event: progress
data: {"exportId":"console-export::tenant-default::2025-12-06::0007","percent":75,"itemsCompleted":375,"itemsTotal":500}
event: completed
data: {"exportId":"console-export::tenant-default::2025-12-06::0007","status":"succeeded","manifestUrl":"https://exports.local/.../manifest.json"}

View File

@@ -0,0 +1,36 @@
{
"version": "2025-12-06",
"exportId": "console-export::tenant-default::2025-12-06::0007",
"tenantId": "tenant-default",
"generatedAt": "2025-12-06T12:11:05Z",
"items": [
{
"type": "advisory",
"id": "CVE-2024-12345",
"url": "https://exports.local/tenant-default/0007/CVE-2024-12345.json?sig=...",
"sha256": "cafe0001..."
},
{
"type": "vex",
"id": "vex:tenant-default:jwt-auth:5d1a",
"url": "https://exports.local/tenant-default/0007/vex-jwt-auth.ndjson?sig=...",
"sha256": "cafe0002..."
},
{
"type": "policy",
"id": "policy://tenant-default/runtime-hardening",
"url": "https://exports.local/tenant-default/0007/policy-runtime-hardening.json?sig=...",
"sha256": "cafe0003..."
},
{
"type": "scan",
"id": "scan::tenant-default::auth-api::2025-11-07",
"url": "https://exports.local/tenant-default/0007/scan-auth-api.ndjson?sig=...",
"sha256": "cafe0004..."
}
],
"checksums": {
"manifest": "c0ffee...",
"bundle": "deadbeef..."
}
}

View File

@@ -0,0 +1,16 @@
{
"scope": {
"tenantId": "tenant-default",
"projectId": "sre-prod"
},
"sources": [
{ "type": "advisory", "ids": ["CVE-2024-12345", "CVE-2024-23456"] },
{ "type": "vex", "ids": ["vex:tenant-default:jwt-auth:5d1a"] },
{ "type": "policy", "ids": ["policy://tenant-default/runtime-hardening"] },
{ "type": "scan", "ids": ["scan::tenant-default::auth-api::2025-11-07"] }
],
"formats": ["json", "ndjson", "csv"],
"attestations": { "include": true, "sigstoreBundle": true },
"notify": { "webhooks": ["https://hooks.local/export"], "email": ["secops@example.com"] },
"priority": "normal"
}

View File

@@ -0,0 +1,24 @@
{
"exportId": "console-export::tenant-default::2025-12-06::0007",
"status": "running",
"estimateSeconds": 420,
"retryAfter": 15,
"createdAt": "2025-12-06T12:10:00Z",
"updatedAt": "2025-12-06T12:11:05Z",
"outputs": [
{
"type": "manifest",
"format": "json",
"url": "https://exports.local/tenant-default/0007/manifest.json?sig=...",
"sha256": "c0ffee...",
"expiresAt": "2025-12-06T13:10:00Z"
}
],
"progress": {
"percent": 42,
"itemsCompleted": 210,
"itemsTotal": 500,
"assetsReady": 12
},
"errors": []
}

View File

@@ -0,0 +1,37 @@
{
"exceptionId": "exc::tenant-default::2025-12-06::00012",
"tenantId": "tenant-default",
"title": "Risk accepted for log4j on batch nodes",
"state": "pending_review",
"type": "advisory",
"scope": {
"level": "asset",
"assetIds": ["batch-node-17", "batch-node-18"],
"advisoryIds": ["CVE-2021-44228"],
"components": ["pkg:maven/org.apache.logging.log4j/log4j-core@2.14.0"]
},
"justification": {
"template": "compensating_control",
"details": "Ingress disabled; nodes isolated; patch planned 2025-12-20"
},
"timebox": {
"start": "2025-12-06T00:00:00Z",
"end": "2025-12-31T00:00:00Z",
"maxRenewals": 1
},
"audit": {
"createdBy": "alice@example.com",
"createdAt": "2025-12-06T11:12:13Z",
"modifiedAt": "2025-12-06T11:12:13Z"
},
"links": {
"history": "/console/exceptions/exc::tenant-default::2025-12-06::00012/history",
"attachments": [
{
"name": "risk-assessment.pdf",
"url": "https://console.local/files/risk-assessment.pdf?sig=...",
"sha256": "cafe..."
}
]
}
}

View File

@@ -309,3 +309,43 @@ data: {
- `docs/api/console/samples/vex-statement-sse.ndjson` contains 5 chronological SSE events for screenshot reproduction.
> Until backend implementations ship, use the examples above to unblock DOCS-AIAI-31-004; replace them with live captures once the gateway endpoints are available in staging.
## Exports (draft contract)
Routes
- `POST /console/exports` — start an evidence bundle export job.
- `GET /console/exports/{exportId}` — fetch job status and download locations.
- `GET /console/exports/{exportId}/events` — SSE stream of job progress (optional).
Headers
- `Authorization: Bearer <token>`
- `X-StellaOps-Tenant: <tenantId>`
- `Idempotency-Key: <uuid>` (recommended for POST)
- `Accept: application/json` (status) or `text/event-stream` (events)
Request body (POST /console/exports)
- `scope`: `{ tenantId, projectId? }`
- `sources`: array of `{ type: "advisory"|"vex"|"policy"|"scan", ids: string[] }`
- `formats`: array of `"json"|"csv"|"ndjson"|"pdf"`
- `attestations`: `{ include: boolean, sigstoreBundle?: boolean }`
- `notify`: `{ webhooks?: string[], email?: string[] }`
- `priority`: `"low"|"normal"|"high"`
Responses
- `202 Accepted` with `exportId`, `status: queued|running|succeeded|failed|expired`, `estimateSeconds`, `retryAfter`.
- Status payload includes presigned download URLs, checksum manifest, and error list when failed.
- SSE events emit `started`, `progress` (percent, item counts), `asset_ready` (uri, sha256), `completed`, `failed` (code, message).
Proposed limits
- Max request body 256 KiB; max sources 50; max outputs 1000 assets/export.
- Default job timeout 30 minutes; idle SSE timeout 60s; backoff header `Retry-After`.
Samples (draft)
- Request: `docs/api/console/samples/console-export-request.json`
- Status: `docs/api/console/samples/console-export-status.json`
- Manifest: `docs/api/console/samples/console-export-manifest.json`
- Events: `docs/api/console/samples/console-export-events.ndjson`
Open items (needs owner sign-off)
- Final schema (fields, limits, error codes), checksum manifest format, attestation options.
- Caching/tie-break rules for downstream `/console/search` and `/console/downloads`.