Files
git.stella-ops.org/docs/api/gateway/findings-ledger-proxy.md
StellaOps Bot 44171930ff
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
Policy Lint & Smoke / policy-lint (push) Has been cancelled
devportal-offline / build-offline (push) Has been cancelled
feat: Add UI benchmark driver and scenarios for graph interactions
- Introduced `ui_bench_driver.mjs` to read scenarios and fixture manifest, generating a deterministic run plan.
- Created `ui_bench_plan.md` outlining the purpose, scope, and next steps for the benchmark.
- Added `ui_bench_scenarios.json` containing various scenarios for graph UI interactions.
- Implemented tests for CLI commands, ensuring bundle verification and telemetry defaults.
- Developed schemas for orchestrator components, including replay manifests and event envelopes.
- Added mock API for risk management, including listing and statistics functionalities.
- Implemented models for risk profiles and query options to support the new API.
2025-12-02 01:28:17 +02:00

74 lines
3.4 KiB
Markdown

# Findings Ledger Proxy Contract (Web V)
## Status
- Final v1.0 (2025-12-01); validated with Findings Ledger Guild for Sprint 0216.
## Scope
- Gateway → Findings Ledger forwarding for vuln workflow actions (`open`, `ack`, `close`, `reopen`, `export`).
- Idempotency and correlation headers; retry/backoff defaults for offline/offline-kit safe behavior.
## Required Headers
| Name | Requirement | Notes |
| --- | --- | --- |
| `Authorization: Bearer <jwt>` | Required | RS256/ES256 service token, `aud=stellaops-ledger`, scopes `ledger:write ledger:read`. |
| `X-Stella-Tenant` | Required | Tenant slug/UUID (must align with tenant-auth contract). |
| `X-Stella-Project` | Conditional | Required for project-scoped findings. |
| `X-Idempotency-Key` | Required on POST/PUT | Deterministic `BLAKE3-256(base64url(tenant + route + canonical_body))`; 44 chars. TTL: 24h. |
| `X-Correlation-Id` | Required | UUID/ULID stable across gateway → ledger → notifier; echoed by responses. |
| `Content-Type` | Required | `application/json`. |
| `If-Match` | Optional | When present, ledger enforces optimistic concurrency using the last `ETag` value. |
## Behavior
- Delivery semantics: gateway is at-least-once; Findings Ledger guarantees exactly-once per `X-Idempotency-Key` within 24h TTL.
- Retry/backoff (gateway): base delay 500 ms, factor 2, jitter ±20%, max 3 attempts, cap total wait 10 s. Offline kits persist NDJSON (headers+body) and replay on next sync window.
- Timeout: 5 s per attempt; timeout → `ERR_LEDGER_TIMEOUT`.
- Concurrency: ledger returns `ETag` for each workflow record; gateway includes `If-Match` on retries when available. Mismatch → 409 + `ERR_LEDGER_CONFLICT`.
- Error mapping (deterministic envelope with `trace_id` + echoed `X-Correlation-Id`):
- 400 → `ERR_LEDGER_BAD_REQUEST` (propagate `details`).
- 404 → `ERR_LEDGER_NOT_FOUND`.
- 409 → `ERR_LEDGER_CONFLICT`.
- 429/503 → `ERR_LEDGER_RETRY`.
- 500+ → `ERR_LEDGER_UPSTREAM`.
## Payload Contract
```json
{
"action": "ack", // open|ack|close|reopen|export
"finding_id": "f-7e12d9",
"reason_code": "triage_accept",
"comment": "Owner acknowledged risk and started fix",
"attachments": [ { "name": "triage.pdf", "digest": "sha256-..." } ],
"actor": { "subject": "svc-console", "type": "service" },
"metadata": { "policy_version": "2025.11.0", "vex_statement_id": "vex-123" }
}
```
- Body must be canonical JSON (sorted keys) before hashing for `X-Idempotency-Key`.
- Maximum size: 64 KiB; larger bodies rejected with 413.
## Example Request
```bash
curl -X POST https://gateway.stellaops.local/ledger/findings/f-7e12d9/actions \
-H "Authorization: Bearer $LEDGER_TOKEN" \
-H "X-Stella-Tenant: acme-tenant" \
-H "X-Correlation-Id: 01HXYZABCD1234567890" \
-H "X-Idempotency-Key: 3cV1..." \
-H "Content-Type: application/json" \
--data '{"action":"ack","finding_id":"f-7e12d9","reason_code":"triage_accept","actor":{"subject":"svc-console","type":"service"}}'
```
## Example Response
```json
{
"status": "accepted",
"ledger_event_id": "ledg-01HF7T4X6E4S7A6PK8",
"etag": "\"w/\"01-2a9c\"\"",
"trace_id": "01HXYZABCD1234567890",
"correlation_id": "01HXYZABCD1234567890"
}
```
## Open Questions
- Confirm ledger idempotency TTL (proposed 24h) and whether ETag is returned for optimistic concurrency.
- Confirm expected payload schemas for each workflow action (open/ack/close/export).
- Confirm whether ledger enforces ordering per `tenant_id`.