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
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:
@@ -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.
|
||||
|
||||
14
docs/api/console/samples/console-export-events.ndjson
Normal file
14
docs/api/console/samples/console-export-events.ndjson
Normal 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"}
|
||||
36
docs/api/console/samples/console-export-manifest.json
Normal file
36
docs/api/console/samples/console-export-manifest.json
Normal 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..."
|
||||
}
|
||||
}
|
||||
16
docs/api/console/samples/console-export-request.json
Normal file
16
docs/api/console/samples/console-export-request.json
Normal 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"
|
||||
}
|
||||
24
docs/api/console/samples/console-export-status.json
Normal file
24
docs/api/console/samples/console-export-status.json
Normal 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": []
|
||||
}
|
||||
37
docs/api/console/samples/exception-schema-sample.json
Normal file
37
docs/api/console/samples/exception-schema-sample.json
Normal 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..."
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -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`.
|
||||
|
||||
Reference in New Issue
Block a user