up
Some checks failed
AOC Guard CI / aoc-guard (push) Has been cancelled
AOC Guard CI / aoc-verify (push) Has been cancelled
Docs CI / lint-and-preview (push) Has been cancelled
Mirror Thin Bundle Sign & Verify / mirror-sign (push) Has been cancelled
api-governance / spectral-lint (push) Has been cancelled

This commit is contained in:
StellaOps Bot
2025-11-24 07:52:25 +02:00
parent 5970f0d9bd
commit 150b3730ef
215 changed files with 8119 additions and 740 deletions

View File

@@ -0,0 +1,39 @@
# Excititor Locker Manifest (OBS-53-001)
Defines the manifest for evidence snapshots stored in Evidence Locker / sealed-mode bundles.
## Manifest structure
```json
{
"tenant": "default",
"manifestId": "locker:excititor:2025-11-23:0001",
"createdAt": "2025-11-23T23:10:00Z",
"items": [
{
"observationId": "vex:obs:sha256:...",
"providerId": "ubuntu-csaf",
"contentHash": "sha256:...",
"linksetId": "CVE-2024-0001:pkg:maven/org.demo/app@1.2.3",
"dsseEnvelopeHash": "sha256:...",
"provenance": {
"source": "mirror|ingest",
"mirrorGeneration": 12,
"exportCenterManifest": "sha256:..."
}
}
],
"merkleRoot": "sha256:...", // over `items[*].contentHash`
"signature": null, // populated in OBS-54-001 (DSSE)
"metadata": {"sealed": true}
}
```
## Rules
- `items` sorted by `observationId`, then `providerId`.
- `merkleRoot` uses SHA-256 over concatenated item hashes (stable order above).
- `signature` is a DSSE envelope (hash recorded in `dsseEnvelopeHash`) when OBS-54-001 is enabled; otherwise `null`.
- Manifests are immutable; version using `manifestId` suffix.
## Storage and replay
- Store manifests alongside payloads in object storage; key prefix: `locker/excititor/<tenant>/<manifestId>`.
- Replay tools must verify `merkleRoot` before loading payloads; reject if mismatched.

View File

@@ -0,0 +1,43 @@
# Excititor Timeline Events (OBS-52-001)
Defines the event envelope for evidence timelines emitted by Excititor. All fields are aggregation-only; no consensus/merge logic.
## Envelope
```json
{
"type": "excititor.timeline.v1",
"tenant": "default",
"eventId": "urn:uuid:...",
"timestamp": "2025-11-23T23:10:00Z",
"traceId": "beefcafe...",
"spanId": "deadb33f...",
"source": "excititor.web",
"kind": "observation|linkset",
"action": "ingest|update|backfill|replay",
"observationId": "vex:obs:sha256:...",
"linksetId": "CVE-2024-0001:pkg:maven/org.demo/app@1.2.3",
"justifications": ["component_not_present"],
"conflicts": [
{"providerId": "suse-csaf", "status": "fixed", "justification": null}
],
"evidenceHash": "sha256:...", // content-addressed payload hash
"dsseEnvelopeHash": "sha256:...", // if attested (see OBS-54-001)
"metadata": {"connector": "ubuntu-csaf", "mirrorGeneration": 12}
}
```
## Semantics
- `eventId` is stable per write; retries reuse the same ID.
- `timestamp` must be UTC; derive from TimeProvider.
- `traceId`/`spanId` propagate ingestion traces; if tracing is disabled, set both to `null`.
- `kind` + `action` drive downstream storage and alerting.
- `evidenceHash` is the raw document hash; `dsseEnvelopeHash` appears only when OBS-54-001 is enabled.
## Determinism
- Sort `justifications` and `conflicts` ascending by providerId/status before emit.
- Emit at-most-once per storage write; idempotent consumers rely on `(eventId, tenant)`.
## Transport
- Default topic: `excititor.timeline.v1` (NATS/Redis). Subject includes tenant: `excititor.timeline.v1.<tenant>`.
- Payload size should stay <32 KiB; truncate conflict arrays with `truncated=true` flag if needed (keep hash counts deterministic).

View File

@@ -37,6 +37,24 @@ Excititors evidence APIs now emit first-class OpenTelemetry metrics so Lens,
3. **Alerting**: add rules for high guard violation rates, missing signatures, and abnormal chunk bytes/record counts. Tie alerts back to connectors via tenant metadata.
4. **Post-deploy checks**: after each release, verify metrics emit by curling `/v1/vex/observations/...` and `/v1/vex/evidence/chunks`, watching the console exporter (dev) or OTLP (prod).
## SLOs (Sprint 119 OBS-51-001)
The following SLOs apply to Excititor evidence read paths when telemetry is enabled. Record them in the shared SLO registry and alert via the platform alertmanager.
| Surface | SLI | Target | Window | Burn alert | Notes |
| --- | --- | --- | --- | --- | --- |
| `/v1/vex/observations` | p95 latency | ≤ 450ms | 7d | 2% over 1h | Measured on successful responses only; tenant scoped. |
| `/v1/vex/observations` | freshness | ≥ 99% within 5min of upstream ingest | 7d | 5% over 4h | Derived from arrival minus `createdAt`; requires ingest clocks in UTC. |
| `/v1/vex/observations` | signature presence | ≥ 98% statements with signature present | 7d | 3% over 24h | Use `excititor.vex.signature.status{status="missing"}`. |
| `/v1/vex/evidence/chunks` | p95 stream duration | ≤ 600ms | 7d | 2% over 1h | From request start to last NDJSON write; excludes client disconnects. |
| `/v1/vex/evidence/chunks` | truncation rate | ≤ 1% truncated streams | 7d | 1% over 1h | `excititor.vex.chunks.records` with `truncated=true`. |
| AOC guardrail | zero hard violations | 0 | continuous | immediate | Any `excititor.vex.aoc.guard_violations` with severity `error` pages ops. |
Implementation notes:
- Emit latency/freshness SLOs via OTEL views that pre-aggregate by tenant and route to the platform SLO backend; keep bucket boundaries aligned with 50/100/250/450/650/1000ms.
- Freshness SLI derived from ingest timestamps; ensure clocks are synchronized (NTP) and stored in UTC.
- For air-gapped deployments without OTEL sinks, scrape console exporter and push to offline Prometheus; same thresholds apply.
## Related documents
- `docs/modules/excititor/architecture.md` API contract, AOC guardrails, connector responsibilities.

View File

@@ -101,4 +101,29 @@ Response 200:
- Determinism: responses sorted by `vulnerabilityId`, then `productKey`; arrays sorted lexicographically.
## SDK generation
- Use this file plus `vex_observations.md` as the source of truth for SDK examples in EXCITITOR-LNM-21-203.
- Source of truth for EXCITITOR-LNM-21-203 SDK samples (TypeScript/Go/Python) and OpenAPI snippets.
- Suggested generation inputs:
- Schema: this doc + `docs/modules/excititor/vex_observations.md` for field semantics.
- Auth: bearer token + `X-Stella-Tenant` header (required).
- Pagination: `cursor` (opaque) + `limit` (default 200, max 500).
- Minimal client example (TypeScript, fetch):
```ts
const resp = await fetch(
`${baseUrl}/v1/vex/observations?` + new URLSearchParams({
vulnerabilityId: "CVE-2024-0001",
productKey: "pkg:maven/org.demo/app@1.2.3",
limit: "100"
}),
{
headers: {
Authorization: `Bearer ${token}`,
"X-Stella-Tenant": "default"
}
}
);
const body = await resp.json();
```
- Determinism requirements for SDKs:
- Preserve server ordering; do not resort items client-side.
- Treat `cursor` as opaque; echo it back for next page.
- Keep enums case-sensitive as returned by API.