feat(docs): Add comprehensive documentation for Vexer, Vulnerability Explorer, and Zastava modules
- Introduced AGENTS.md, README.md, TASKS.md, and implementation_plan.md for Vexer, detailing mission, responsibilities, key components, and operational notes. - Established similar documentation structure for Vulnerability Explorer and Zastava modules, including their respective workflows, integrations, and observability notes. - Created risk scoring profiles documentation outlining the core workflow, factor model, governance, and deliverables. - Ensured all modules adhere to the Aggregation-Only Contract and maintain determinism and provenance in outputs.
This commit is contained in:
		
							
								
								
									
										22
									
								
								docs/modules/attestor/AGENTS.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								docs/modules/attestor/AGENTS.md
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,22 @@ | ||||
| # Attestor agent guide | ||||
|  | ||||
| ## Mission | ||||
| Attestor moves signed evidence through the trust chain by accepting DSSE bundles from Signer, registering them with Rekor v2, and serving deterministic verification payloads to other services. | ||||
|  | ||||
| ## Key docs | ||||
| - [Module README](./README.md) | ||||
| - [Architecture](./architecture.md) | ||||
| - [Implementation plan](./implementation_plan.md) | ||||
| - [Task board](./TASKS.md) | ||||
|  | ||||
| ## How to get started | ||||
| 1. Open ../../implplan/SPRINTS.md and locate the stories referencing this module. | ||||
| 2. Review ./TASKS.md for local follow-ups and confirm status transitions (TODO → DOING → DONE/BLOCKED). | ||||
| 3. Read the architecture and README for domain context before editing code or docs. | ||||
| 4. Coordinate cross-module changes in the main /AGENTS.md description and through the sprint plan. | ||||
|  | ||||
| ## Guardrails | ||||
| - Honour the Aggregation-Only Contract where applicable (see ../../ingestion/aggregation-only-contract.md). | ||||
| - Preserve determinism: sort outputs, normalise timestamps (UTC ISO-8601), and avoid machine-specific artefacts. | ||||
| - Keep Offline Kit parity in mind—document air-gapped workflows for any new feature. | ||||
| - Update runbooks/observability assets when operational characteristics change. | ||||
							
								
								
									
										54
									
								
								docs/modules/attestor/README.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										54
									
								
								docs/modules/attestor/README.md
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,54 @@ | ||||
| # StellaOps Attestor | ||||
|  | ||||
| Attestor converts signed DSSE evidence from the Signer into transparency-log proofs and verifiable reports for every downstream surface (Policy Engine, Export Center, CLI, Console, Scheduler). It is the trust backbone that proves SBOM, scan, VEX, and policy artefacts were signed, witnessed, and preserved without tampering. | ||||
|  | ||||
| ## Why it exists | ||||
| - **Evidence first:** organisations need portable, verifiable attestations that prove build provenance, SBOM availability, policy verdicts, and VEX statements. | ||||
| - **Policy enforcement:** verification policies ensure only approved issuers, key types, witnesses, and freshness windows are accepted. | ||||
| - **Sovereign/offline-ready:** Attestor archives envelopes, signatures, and proofs so air-gapped deployments can replay verification without contacting external services. | ||||
|  | ||||
| ## Roles & surfaces | ||||
| - **Subjects:** immutable digests for container images, SBOMs, reports, and policy bundles. | ||||
| - **Issuers:** builders, scanners, policy engines, or operators signing DSSE envelopes using keyless (Fulcio), KMS/HSM, or FIDO2 keys. | ||||
| - **Consumers:** CLI/SDK, Console, Export Center, Scanner, Policy Engine, and Notify retrieving verification bundles or triggering policy checks. | ||||
| - **Scopes:** Authority issues `attestor.write`, `attestor.verify`, `attestor.read`, and administrative scopes for issuer/key management; every call is bound with mTLS + DPoP. | ||||
|  | ||||
| ## Supported payloads | ||||
| - `StellaOps.BuildProvenance@1`, `StellaOps.SBOMAttestation@1` | ||||
| - `StellaOps.ScanResults@1`, `StellaOps.VEXAttestation@1` | ||||
| - `StellaOps.PolicyEvaluation@1`, `StellaOps.RiskProfileEvidence@1` | ||||
| All predicates capture subjects, issuer metadata, policy context, materials, optional witnesses, and versioned schemas. Unsupported predicates return `422 predicate_unsupported`. | ||||
|  | ||||
| ## Trust & envelope model | ||||
| - DSSE envelopes are canonicalised, hashed, and stored alongside the Rekor UUID, index, and proof. | ||||
| - Signature modes span keyless (Fulcio), keyful (KMS/HSM), and hardware-backed (FIDO2). Multiple signatures are supported per envelope. | ||||
| - Proofs include Merkle inclusion path, checkpoint metadata, optional witness endorsements, and cached verification verdicts. | ||||
| - CAS/object storage retains envelopes + provenance for later replay; Rekor backends may be primary plus mirrors. | ||||
|  | ||||
| ## UI, CLI, and SDK workflows | ||||
| - **Console:** Evidence browser, verification reports, chain-of-custody graph, issuer/key management, attestation workbench, and bulk verification flows. | ||||
| - **CLI / SDK:** `stella attest sign|verify|list|fetch|key` commands plus language SDKs to integrate build pipelines and offline verification scripts. | ||||
| - **Policy Studio:** Verification policies author required predicate types, issuers, witness requirements, and freshness windows; simulations show enforcement impact. | ||||
|  | ||||
| ## Storage, offline & air-gap posture | ||||
| - MongoDB stores entry metadata, dedupe keys, and audit events; object storage optionally archives DSSE bundles. | ||||
| - Export Center packages attestation bundles (`stella export attestation-bundle`) for Offline Kit delivery. | ||||
| - Transparency logs can be mirrored; offline mode records gaps and provides compensating controls. | ||||
|  | ||||
| ## Observability & performance | ||||
| - Metrics: `attestor_submission_total`, `attestor_verify_seconds`, `attestor_cache_hit_ratio`, `attestor_rekor_latency_seconds`. | ||||
| - Logs capture tenant, issuer, subject digests, Rekor UUID, proof status, and policy verdict. | ||||
| - Performance target: ≥1 000 envelopes/minute per worker with cached verification, batched operations, and concurrency controls. | ||||
|  | ||||
| ## Key integrations | ||||
| - Signer (DSSE source), Authority (scopes & tenancy), Export Center (attestation bundles), Policy Engine (verification policies), Scanner/Excititor (subject evidence), Notify (key rotation & verification alerts), Observability stack (dashboards/alerts). | ||||
|  | ||||
| ## Backlog references | ||||
| - DOCS-ATTEST-73-001 … DOCS-ATTEST-75-002 (Attestor console, key management, air-gap bundles) in ../../TASKS.md. | ||||
| - EXPORT-ATTEST-75-002 (Export Center attestation packaging) in ../export-center/TASKS.md. | ||||
|  | ||||
| ## Epic alignment | ||||
| - **Epic 19 – Attestor Console:** console experience, verification APIs, issuer/key governance, transparency integration, and offline bundles. | ||||
| - **Epic 10 – Export Center:** provenance alignment so exports carry signed manifests and attestation bundles. | ||||
|  | ||||
| > **Imposed rule:** Work of this type or tasks of this type on this component must also be applied everywhere else it should be applied. | ||||
							
								
								
									
										9
									
								
								docs/modules/attestor/TASKS.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								docs/modules/attestor/TASKS.md
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,9 @@ | ||||
| # Task board — Attestor | ||||
|  | ||||
| > Local tasks should link back to ./AGENTS.md and mirror status updates into ../../TASKS.md when applicable. | ||||
|  | ||||
| | ID | Status | Owner(s) | Description | Notes | | ||||
| |----|--------|----------|-------------|-------| | ||||
| | ATTESTOR-DOCS-0001 | DOING (2025-10-29) | Docs Guild | Validate that ./README.md aligns with the latest release notes. | See ./AGENTS.md | | ||||
| | ATTESTOR-OPS-0001 | TODO | Ops Guild | Review runbooks/observability assets after next sprint demo. | Sync outcomes back to ../../TASKS.md | | ||||
| | ATTESTOR-ENG-0001 | TODO | Module Team | Cross-check implementation plan milestones against ../../implplan/SPRINTS.md. | Update status via ./AGENTS.md workflow | | ||||
							
								
								
									
										432
									
								
								docs/modules/attestor/architecture.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										432
									
								
								docs/modules/attestor/architecture.md
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,432 @@ | ||||
| # component_architecture_attestor.md — **Stella Ops Attestor** (2025Q4) | ||||
|  | ||||
| > Derived from Epic 19 – Attestor Console with provenance hooks aligned to the Export Center bundle workflows scoped in Epic 10. | ||||
|  | ||||
| > **Scope.** Implementation‑ready architecture for the **Attestor**: the service that **submits** DSSE envelopes to **Rekor v2**, retrieves/validates inclusion proofs, caches results, and exposes verification APIs. It accepts DSSE **only** from the **Signer** over mTLS, enforces chain‑of‑trust to Stella Ops roots, and returns `{uuid, index, proof, logURL}` to calling services (Scanner.WebService for SBOMs; backend for final reports; Excititor exports when configured). | ||||
|  | ||||
| --- | ||||
|  | ||||
| ## 0) Mission & boundaries | ||||
|  | ||||
| **Mission.** Turn a signed DSSE envelope from the Signer into a **transparency‑logged, verifiable fact** with a durable, replayable proof (Merkle inclusion + (optional) checkpoint anchoring). Provide **fast verification** for downstream consumers and a stable retrieval interface for UI/CLI. | ||||
|  | ||||
| **Boundaries.** | ||||
|  | ||||
| * Attestor **does not sign**; it **must not** accept unsigned or third‑party‑signed bundles. | ||||
| * Attestor **does not decide PASS/FAIL**; it logs attestations for SBOMs, reports, and export artifacts. | ||||
| * Rekor v2 backends may be **local** (self‑hosted) or **remote**; Attestor handles both with retries, backoff, and idempotency. | ||||
|  | ||||
| --- | ||||
|  | ||||
| ## 1) Topology & dependencies | ||||
|  | ||||
| **Process shape:** single stateless service `stellaops/attestor` behind mTLS. | ||||
|  | ||||
| **Dependencies:** | ||||
|  | ||||
| * **Signer** (caller) — authenticated via **mTLS** and **Authority** OpToks. | ||||
| * **Rekor v2** — tile‑backed transparency log endpoint(s). | ||||
| * **MinIO (S3)** — optional archive store for DSSE envelopes & verification bundles. | ||||
| * **MongoDB** — local cache of `{uuid, index, proof, artifactSha256, bundleSha256}`; job state; audit. | ||||
| * **Redis** — dedupe/idempotency keys and short‑lived rate‑limit buckets. | ||||
| * **Licensing Service (optional)** — “endorse” call for cross‑log publishing when customer opts‑in. | ||||
|  | ||||
| Trust boundary: **Only the Signer** is allowed to call submission endpoints; enforced by **mTLS peer cert allowlist** + `aud=attestor` OpTok. | ||||
|  | ||||
| --- | ||||
|  | ||||
| ### Roles, identities & scopes | ||||
| - **Subjects** — immutable digests for artifacts (container images, SBOMs, reports) referenced in DSSE envelopes. | ||||
| - **Issuers** — authenticated builders/scanners/policy engines signing evidence; tracked with mode (`keyless`, `kms`, `hsm`, `fido2`) and tenant scope. | ||||
| - **Consumers** — Scanner, Export Center, CLI, Console, Policy Engine that verify proofs using Attestor APIs. | ||||
| - **Authority scopes** — `attestor.write`, `attestor.verify`, `attestor.read`, and administrative scopes for key management; all calls mTLS/DPoP-bound. | ||||
|  | ||||
| ### Supported predicate types | ||||
| - `StellaOps.BuildProvenance@1` | ||||
| - `StellaOps.SBOMAttestation@1` | ||||
| - `StellaOps.ScanResults@1` | ||||
| - `StellaOps.PolicyEvaluation@1` | ||||
| - `StellaOps.VEXAttestation@1` | ||||
| - `StellaOps.RiskProfileEvidence@1` | ||||
|  | ||||
| Each predicate embeds subject digests, issuer metadata, policy context, materials, and optional transparency hints. Unsupported predicates return `422 predicate_unsupported`. | ||||
|  | ||||
| ### Envelope & signature model | ||||
| - DSSE envelopes canonicalised (stable JSON ordering) prior to hashing. | ||||
| - Signature modes: keyless (Fulcio cert chain), keyful (KMS/HSM), hardware (FIDO2/WebAuthn). Multiple signatures allowed. | ||||
| - Rekor entry stores bundle hash, certificate chain, and optional witness endorsements. | ||||
| - Archive CAS retains original envelope plus metadata for offline verification. | ||||
|  | ||||
| ### Verification pipeline overview | ||||
| 1. Fetch envelope (from request, cache, or storage) and validate DSSE structure. | ||||
| 2. Verify signature(s) against configured trust roots; evaluate issuer policy. | ||||
| 3. Retrieve or acquire inclusion proof from Rekor (primary + optional mirror). | ||||
| 4. Validate Merkle proof against checkpoint; optionally verify witness endorsement. | ||||
| 5. Return cached verification bundle including policy verdict and timestamps. | ||||
|  | ||||
| ### UI & CLI touchpoints | ||||
| - Console: Evidence browser, verification report, chain-of-custody graph, issuer/key management, attestation workbench, bulk verification views. | ||||
| - CLI: `stella attest sign|verify|list|fetch|key` with offline verification and export bundle support. | ||||
| - SDKs expose sign/verify primitives for build pipelines. | ||||
|  | ||||
| ### Performance & observability targets | ||||
| - Throughput goal: ≥1 000 envelopes/minute per worker with cached verification. | ||||
| - Metrics: `attestor_submission_total`, `attestor_verify_seconds`, `attestor_rekor_latency_seconds`, `attestor_cache_hit_ratio`. | ||||
| - Logs include `tenant`, `issuer`, `subjectDigest`, `rekorUuid`, `proofStatus`; traces cover submission → Rekor → cache → response path. | ||||
|  | ||||
| --- | ||||
|  | ||||
| ## 2) Data model (Mongo) | ||||
|  | ||||
| Database: `attestor` | ||||
|  | ||||
| **Collections & schemas** | ||||
|  | ||||
| * `entries` | ||||
|  | ||||
|   ``` | ||||
|   { _id: "<rekor-uuid>", | ||||
|     artifact: { sha256: "<sha256>", kind: "sbom|report|vex-export", imageDigest?, subjectUri? }, | ||||
|     bundleSha256: "<sha256>",                           // canonicalized DSSE | ||||
|     index: <int>,                                       // log index/sequence if provided by backend | ||||
|     proof: {                                            // inclusion proof | ||||
|       checkpoint: { origin, size, rootHash, timestamp }, | ||||
|       inclusion: { leafHash, path[] }                   // Merkle path (tiles) | ||||
|     }, | ||||
|     log: { url, logId? }, | ||||
|     createdAt, status: "included|pending|failed", | ||||
|     signerIdentity: { mode: "keyless|kms", issuer, san?, kid? } | ||||
|   } | ||||
|   ``` | ||||
|  | ||||
| * `dedupe` | ||||
|  | ||||
|   ``` | ||||
|   { key: "bundle:<sha256>", rekorUuid, createdAt, ttlAt }     // idempotency key | ||||
|   ``` | ||||
|  | ||||
| * `audit` | ||||
|  | ||||
|   ``` | ||||
|   { _id, ts, caller: { cn, mTLSThumbprint, sub, aud },        // from mTLS + OpTok | ||||
|     action: "submit|verify|fetch", | ||||
|     artifactSha256, bundleSha256, rekorUuid?, index?, result, latencyMs, backend } | ||||
|   ``` | ||||
|  | ||||
| Indexes: | ||||
|  | ||||
| * `entries` on `artifact.sha256`, `bundleSha256`, `createdAt`, and `{status:1, createdAt:-1}`. | ||||
| * `dedupe.key` unique (TTL 24–48h). | ||||
| * `audit.ts` for time‑range queries. | ||||
|  | ||||
| --- | ||||
|  | ||||
| ## 3) Input contract (from Signer) | ||||
|  | ||||
| **Attestor accepts only** DSSE envelopes that satisfy all of: | ||||
|  | ||||
| 1. **mTLS** peer certificate maps to `signer` service (CA‑pinned). | ||||
| 2. **Authority** OpTok with `aud=attestor`, `scope=attestor.write`, DPoP or mTLS bound. | ||||
| 3. DSSE envelope is **signed by the Signer’s key** (or includes a **Fulcio‑issued** cert chain) and **chains to configured roots** (Fulcio/KMS). | ||||
| 4. **Predicate type** is one of Stella Ops types (sbom/report/vex‑export) with valid schema. | ||||
| 5. `subject[*].digest.sha256` is present and canonicalized. | ||||
|  | ||||
| **Wire shape (JSON):** | ||||
|  | ||||
| ```json | ||||
| { | ||||
|   "bundle": { "dsse": { "payloadType": "application/vnd.in-toto+json", "payload": "<b64>", "signatures": [ ... ] }, | ||||
|               "certificateChain": [ "-----BEGIN CERTIFICATE-----..." ], | ||||
|               "mode": "keyless" }, | ||||
|   "meta": { | ||||
|     "artifact": { "sha256": "<subject sha256>", "kind": "sbom|report|vex-export", "imageDigest": "sha256:..." }, | ||||
|     "bundleSha256": "<sha256 of canonical dsse>", | ||||
|     "logPreference": "primary",               // "primary" | "mirror" | "both" | ||||
|     "archive": true                           // whether Attestor should archive bundle to S3 | ||||
|   } | ||||
| } | ||||
| ``` | ||||
|  | ||||
| --- | ||||
|  | ||||
| ## 4) APIs | ||||
|  | ||||
| ### 4.1 Submission | ||||
|  | ||||
| `POST /api/v1/rekor/entries`  *(mTLS + OpTok required)* | ||||
|  | ||||
| * **Body**: as above. | ||||
| * **Behavior**: | ||||
|  | ||||
|   * Verify caller (mTLS + OpTok). | ||||
|   * Validate DSSE bundle (signature, cert chain to Fulcio/KMS; DSSE structure; payloadType allowed). | ||||
|   * Idempotency: compute `bundleSha256`; check `dedupe`. If present, return existing `rekorUuid`. | ||||
|   * Submit canonicalized bundle to Rekor v2 (primary or mirror according to `logPreference`). | ||||
|   * Retrieve **inclusion proof** (blocking until inclusion or up to `proofTimeoutMs`); if backend returns promise only, return `status=pending` and retry asynchronously. | ||||
|   * Persist `entries` record; archive DSSE to S3 if `archive=true`. | ||||
| * **Response 200**: | ||||
|  | ||||
|   ```json | ||||
|   { | ||||
|     "uuid": "…", | ||||
|     "index": 123456, | ||||
|     "proof": { | ||||
|       "checkpoint": { "origin": "rekor@site", "size": 987654, "rootHash": "…", "timestamp": "…" }, | ||||
|       "inclusion": { "leafHash": "…", "path": ["…","…"] } | ||||
|     }, | ||||
|     "logURL": "https://rekor…/api/v2/log/…/entries/…", | ||||
|     "status": "included" | ||||
|   } | ||||
|   ``` | ||||
| * **Errors**: `401 invalid_token`, `403 not_signer|chain_untrusted`, `409 duplicate_bundle` (with existing `uuid`), `502 rekor_unavailable`, `504 proof_timeout`. | ||||
|  | ||||
| ### 4.2 Proof retrieval | ||||
|  | ||||
| `GET /api/v1/rekor/entries/{uuid}` | ||||
|  | ||||
| * Returns `entries` row (refreshes proof from Rekor if stale/missing). | ||||
| * Accepts `?refresh=true` to force backend query. | ||||
|  | ||||
| ### 4.3 Verification (third‑party or internal) | ||||
|  | ||||
| `POST /api/v1/rekor/verify` | ||||
|  | ||||
| * **Body** (one of): | ||||
|  | ||||
|   * `{ "uuid": "…" }` | ||||
|   * `{ "bundle": { …DSSE… } }` | ||||
|   * `{ "artifactSha256": "…" }`  *(looks up most recent entry)* | ||||
|  | ||||
| * **Checks**: | ||||
|  | ||||
|   1. **Bundle signature** → cert chain to Fulcio/KMS roots configured. | ||||
|   2. **Inclusion proof** → recompute leaf hash; verify Merkle path against checkpoint root. | ||||
|   3. Optionally verify **checkpoint** against local trust anchors (if Rekor signs checkpoints). | ||||
|   4. Confirm **subject.digest** matches caller‑provided hash (when given). | ||||
|  | ||||
| * **Response**: | ||||
|  | ||||
|   ```json | ||||
|   { "ok": true, "uuid": "…", "index": 123, "logURL": "…", "checkedAt": "…" } | ||||
|   ``` | ||||
|  | ||||
| ### 4.4 Batch submission (optional) | ||||
|  | ||||
| `POST /api/v1/rekor/batch` accepts an array of submission objects; processes with per‑item results. | ||||
|  | ||||
| --- | ||||
|  | ||||
| ## 5) Rekor v2 driver (backend) | ||||
|  | ||||
| * **Canonicalization**: DSSE envelopes are **normalized** (stable JSON ordering, no insignificant whitespace) before hashing and submission. | ||||
| * **Transport**: HTTP/2 with retries (exponential backoff, jitter), budgeted timeouts. | ||||
| * **Idempotency**: if backend returns “already exists,” map to existing `uuid`. | ||||
| * **Proof acquisition**: | ||||
|  | ||||
|   * In synchronous mode, poll the log for inclusion up to `proofTimeoutMs`. | ||||
|   * In asynchronous mode, return `pending` and schedule a **proof fetcher** job (Mongo job doc + backoff). | ||||
| * **Mirrors/dual logs**: | ||||
|  | ||||
|   * When `logPreference="both"`, submit to primary and mirror; store **both** UUIDs (primary canonical). | ||||
|   * Optional **cloud endorsement**: POST to the Stella Ops cloud `/attest/endorse` with `{uuid, artifactSha256}`; store returned endorsement id. | ||||
|  | ||||
| --- | ||||
|  | ||||
| ## 6) Security model | ||||
|  | ||||
| * **mTLS required** for submission from **Signer** (CA‑pinned). | ||||
| * **Authority token** with `aud=attestor` and DPoP/mTLS binding must be presented; Attestor verifies both. | ||||
| * **Bundle acceptance policy**: | ||||
|  | ||||
|   * DSSE signature must chain to the configured **Fulcio** (keyless) or **KMS/HSM** roots. | ||||
|   * SAN (Subject Alternative Name) must match **Signer identity** policy (e.g., `urn:stellaops:signer` or pinned OIDC issuer). | ||||
|   * Predicate `predicateType` must be on allowlist (sbom/report/vex-export). | ||||
|   * `subject.digest.sha256` values must be present and well‑formed (hex). | ||||
| * **No public submission** path. **Never** accept bundles from untrusted clients. | ||||
| * **Client certificate allowlists**: optional `security.mtls.allowedSubjects` / `allowedThumbprints` tighten peer identity checks beyond CA pinning. | ||||
| * **Rate limits**: token-bucket per caller derived from `quotas.perCaller` (QPS/burst) returns `429` + `Retry-After` when exceeded. | ||||
| * **Redaction**: Attestor never logs secret material; DSSE payloads **should** be public by design (SBOMs/reports). If customers require redaction, enforce policy at Signer (predicate minimization) **before** Attestor. | ||||
|  | ||||
| --- | ||||
|  | ||||
| ## 7) Storage & archival | ||||
|  | ||||
| * **Entries** in Mongo provide a local ledger keyed by `rekorUuid` and **artifact sha256** for quick reverse lookups. | ||||
| * **S3 archival** (if enabled): | ||||
|  | ||||
|   ``` | ||||
|   s3://stellaops/attest/ | ||||
|     dsse/<bundleSha256>.json | ||||
|     proof/<rekorUuid>.json | ||||
|     bundle/<artifactSha256>.zip               # optional verification bundle | ||||
|   ``` | ||||
| * **Verification bundles** (zip): | ||||
|  | ||||
|   * DSSE (`*.dsse.json`), proof (`*.proof.json`), `chain.pem` (certs), `README.txt` with verification steps & hashes. | ||||
|  | ||||
| --- | ||||
|  | ||||
| ## 8) Observability & audit | ||||
|  | ||||
| **Metrics** (Prometheus): | ||||
|  | ||||
| * `attestor.submit_total{result,backend}` | ||||
| * `attestor.submit_latency_seconds{backend}` | ||||
| * `attestor.proof_fetch_total{result}` | ||||
| * `attestor.verify_total{result}` | ||||
| * `attestor.dedupe_hits_total` | ||||
| * `attestor.errors_total{type}` | ||||
|  | ||||
| **Correlation**: | ||||
|  | ||||
| * HTTP callers may supply `X-Correlation-Id`; Attestor will echo the header and push `CorrelationId` into the log scope for cross-service tracing. | ||||
|  | ||||
| **Tracing**: | ||||
|  | ||||
| * Spans: `validate`, `rekor.submit`, `rekor.poll`, `persist`, `archive`, `verify`. | ||||
|  | ||||
| **Audit**: | ||||
|  | ||||
| * Immutable `audit` rows (ts, caller, action, hashes, uuid, index, backend, result, latency). | ||||
|  | ||||
| --- | ||||
|  | ||||
| ## 9) Configuration (YAML) | ||||
|  | ||||
| ```yaml | ||||
| attestor: | ||||
|   listen: "https://0.0.0.0:8444" | ||||
|   security: | ||||
|     mtls: | ||||
|       caBundle: /etc/ssl/signer-ca.pem | ||||
|       requireClientCert: true | ||||
|     authority: | ||||
|       issuer: "https://authority.internal" | ||||
|       jwksUrl: "https://authority.internal/jwks" | ||||
|       requireSenderConstraint: "dpop"   # or "mtls" | ||||
|     signerIdentity: | ||||
|       mode: ["keyless","kms"] | ||||
|       fulcioRoots: ["/etc/fulcio/root.pem"] | ||||
|       allowedSANs: ["urn:stellaops:signer"] | ||||
|       kmsKeys: ["kms://cluster-kms/stellaops-signer"] | ||||
|   rekor: | ||||
|     primary: | ||||
|       url: "https://rekor-v2.internal" | ||||
|       proofTimeoutMs: 15000 | ||||
|       pollIntervalMs: 250 | ||||
|       maxAttempts: 60 | ||||
|     mirror: | ||||
|       enabled: false | ||||
|       url: "https://rekor-v2.mirror" | ||||
|   mongo: | ||||
|     uri: "mongodb://mongo/attestor" | ||||
|   s3: | ||||
|     enabled: true | ||||
|     endpoint: "http://minio:9000" | ||||
|     bucket: "stellaops" | ||||
|     prefix: "attest/" | ||||
|     objectLock: "governance" | ||||
|   redis: | ||||
|     url: "redis://redis:6379/2" | ||||
|   quotas: | ||||
|     perCaller: | ||||
|       qps: 50 | ||||
|       burst: 100 | ||||
| ``` | ||||
|  | ||||
| --- | ||||
|  | ||||
| ## 10) End‑to‑end sequences | ||||
|  | ||||
| **A) Submit & include (happy path)** | ||||
|  | ||||
| ```mermaid | ||||
| sequenceDiagram | ||||
|   autonumber | ||||
|   participant SW as Scanner.WebService | ||||
|   participant SG as Signer | ||||
|   participant AT as Attestor | ||||
|   participant RK as Rekor v2 | ||||
|  | ||||
|   SW->>SG: POST /sign/dsse (OpTok+PoE) | ||||
|   SG-->>SW: DSSE bundle (+certs) | ||||
|   SW->>AT: POST /rekor/entries (mTLS + OpTok) | ||||
|   AT->>AT: Validate DSSE (chain to Fulcio/KMS; signer identity) | ||||
|   AT->>RK: submit(bundle) | ||||
|   RK-->>AT: {uuid, index?} | ||||
|   AT->>RK: poll inclusion until proof or timeout | ||||
|   RK-->>AT: inclusion proof (checkpoint + path) | ||||
|   AT-->>SW: {uuid, index, proof, logURL} | ||||
| ``` | ||||
|  | ||||
| **B) Verify by artifact digest (CLI)** | ||||
|  | ||||
| ```mermaid | ||||
| sequenceDiagram | ||||
|   autonumber | ||||
|   participant CLI as stellaops verify | ||||
|   participant SW as Scanner.WebService | ||||
|   participant AT as Attestor | ||||
|  | ||||
|   CLI->>SW: GET /catalog/artifacts/{id} | ||||
|   SW-->>CLI: {artifactSha256, rekor: {uuid}} | ||||
|   CLI->>AT: POST /rekor/verify { uuid } | ||||
|   AT-->>CLI: { ok: true, index, logURL } | ||||
| ``` | ||||
|  | ||||
| --- | ||||
|  | ||||
| ## 11) Failure modes & responses | ||||
|  | ||||
| | Condition                             | Return                  | Details                                                   |          |              | | ||||
| | ------------------------------------- | ----------------------- | --------------------------------------------------------- | -------- | ------------ | | ||||
| | mTLS/OpTok invalid                    | `401 invalid_token`     | Include `WWW-Authenticate` DPoP challenge when applicable |          |              | | ||||
| | Bundle not signed by trusted identity | `403 chain_untrusted`   | DSSE accepted only from Signer identities                 |          |              | | ||||
| | Duplicate bundle                      | `409 duplicate_bundle`  | Return existing `uuid` (idempotent)                       |          |              | | ||||
| | Rekor unreachable/timeout             | `502 rekor_unavailable` | Retry with backoff; surface `Retry-After`                 |          |              | | ||||
| | Inclusion proof timeout               | `202 accepted`          | `status=pending`, background job continues to fetch proof |          |              | | ||||
| | Archive failure                       | `207 multi-status`      | Entry recorded; archive will retry asynchronously         |          |              | | ||||
| | Verification mismatch                 | `400 verify_failed`     | Include reason: chain                                     | leafHash | rootMismatch | | ||||
|  | ||||
| --- | ||||
|  | ||||
| ## 12) Performance & scale | ||||
|  | ||||
| * Stateless; scale horizontally. | ||||
| * **Targets**: | ||||
|  | ||||
|   * Submit+proof P95 ≤ **300 ms** (warm log; local Rekor). | ||||
|   * Verify P95 ≤ **30 ms** from cache; ≤ **120 ms** with live proof fetch. | ||||
|   * 1k submissions/minute per replica sustained. | ||||
| * **Hot caches**: `dedupe` (bundle hash → uuid), recent `entries` by artifact sha256. | ||||
|  | ||||
| --- | ||||
|  | ||||
| ## 13) Testing matrix | ||||
|  | ||||
| * **Happy path**: valid DSSE, inclusion within timeout. | ||||
| * **Idempotency**: resubmit same `bundleSha256` → same `uuid`. | ||||
| * **Security**: reject non‑Signer mTLS, wrong `aud`, DPoP replay, untrusted cert chain, forbidden predicateType. | ||||
| * **Rekor variants**: promise‑then‑proof, proof delayed, mirror dual‑submit, mirror failure. | ||||
| * **Verification**: corrupt leaf path, wrong root, tampered bundle. | ||||
| * **Throughput**: soak test with 10k submissions; latency SLOs, zero drops. | ||||
|  | ||||
| --- | ||||
|  | ||||
| ## 14) Implementation notes | ||||
|  | ||||
| * Language: **.NET 10** minimal API; `HttpClient` with **sockets handler** tuned for HTTP/2. | ||||
| * JSON: **canonical writer** for DSSE payload hashing. | ||||
| * Crypto: use **BouncyCastle**/**System.Security.Cryptography**; PEM parsing for cert chains. | ||||
| * Rekor client: pluggable driver; treat backend errors as retryable/non‑retryable with granular mapping. | ||||
| * Safety: size caps on bundles; decompress bombs guarded; strict UTF‑8. | ||||
| * CLI integration: `stellaops verify attestation <uuid|bundle|artifact>` calls `/rekor/verify`. | ||||
|  | ||||
| --- | ||||
|  | ||||
| ## 15) Optional features | ||||
|  | ||||
| * **Dual‑log** write (primary + mirror) and **cross‑log proof** packaging. | ||||
| * **Cloud endorsement**: send `{uuid, artifactSha256}` to Stella Ops cloud; store returned endorsement id for marketing/chain‑of‑custody. | ||||
| * **Checkpoint pinning**: periodically pin latest Rekor checkpoints to an external audit store for independent monitoring. | ||||
|  | ||||
							
								
								
									
										74
									
								
								docs/modules/attestor/implementation_plan.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										74
									
								
								docs/modules/attestor/implementation_plan.md
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,74 @@ | ||||
| # Implementation plan — Attestor | ||||
|  | ||||
| ## Delivery phases | ||||
| - **Phase 1 – Foundations**   | ||||
|   Build the Attestor service skeleton, DSSE bundle ingestion, mTLS/OpTok enforcement, Rekor v2 client, and cache the `{uuid,index,proof}` tuple. Publish base API (`POST /rekor/entries`, `GET /entries/{uuid}`) and Mongo schemas. | ||||
| - **Phase 2 – Policies & UI**   | ||||
|   Deliver verification policy authoring (Policy Studio integration), console views (evidence browser, verification reports, issuer management), and CLI verbs (`stella attest sign|verify|list|fetch`). | ||||
| - **Phase 3 – Scan & VEX support**   | ||||
|   Accept SBOM, ScanResults, VEX, and PolicyEvaluation predicates; integrate with Scanner, Export Center, Excititor, and Policy Engine pipelines. Ensure AOC invariants on ingestion. | ||||
| - **Phase 4 – Transparency & keys**   | ||||
|   Add multi-log submission (primary + mirror), witness endorsements, KMS/HSM/FIDO2 drivers, key rotation/revocation workflows, and audit trails. | ||||
| - **Phase 5 – Bulk & air gap**   | ||||
|   Implement batch submission/verification, DSSE archival to CAS/object storage, export/import bundles for Offline Kit, and mirror transparency log snapshots. | ||||
| - **Phase 6 – Performance & hardening**   | ||||
|   Optimise cache usage, parallel verification (target ≥1 k envelopes/minute per worker), extend observability (metrics/logs/traces), fuzz parsers, and finalise incident playbooks. | ||||
|  | ||||
| ## Work breakdown | ||||
| - **Attestor service & libraries** | ||||
|   - DSSE validation pipeline (payload whitelist, signature verification, trust roots). | ||||
|   - Rekor client with inclusion-proof acquisition, retry/backoff, mirroring controls. | ||||
|   - Mongo repositories for entries, dedupe, audit; CAS storage for DSSE envelopes. | ||||
|   - Batch submission/verification APIs, verification cache, deterministic serialization. | ||||
|   - Observability hooks: metrics (`attestor_submission_total`, `attestor_verify_seconds`), structured logs, OpenTelemetry traces. | ||||
| - **Signer & Authority integration** | ||||
|   - Enforce mTLS peer validation, Authority scope mapping (`attestor.write`, `attestor.verify`), and DPoP binding. | ||||
|   - Provide signer identity attestation metadata consumed by Attestor. | ||||
| - **Policy & Console** | ||||
|   - Extend Policy Studio with `VerificationPolicy` authoring, approvals, and simulated results. | ||||
|   - Console workflows: Evidence browser, verification reports, chain-of-custody graph, key management UI, bulk verification screens. | ||||
| - **CLI & SDK** | ||||
|   - `stella attest` command group (sign/verify/list/fetch/key management) with DSSE canonicalisation and cosign interoperability. | ||||
|   - SDK helpers for DSSE envelope creation, verification, and proof inspection. | ||||
| - **Export Center & Offline Kit** | ||||
|   - Export Center adapters for attestation bundles; CLI/Console flows to export & import evidence in air-gapped environments. | ||||
|   - Offline Kit scripts for replaying verification, mirroring transparency logs, and reporting gaps. | ||||
| - **Security & key management** | ||||
|   - KMS/HSM/FIDO2 driver abstraction, key rotation and revocation runbooks, witness endorsements, and revocation telemetry. | ||||
| - **Docs & training** | ||||
|   - Update module dossier (overview, architecture, implementation plan), key management guides, transparency reference, CLI/Console documentation, and air-gap runbooks. | ||||
|  | ||||
| ## Cross-module dependencies | ||||
| - **Policy Studio / Policy Engine:** verification policy artefacts, explain integration, remediation hints. | ||||
| - **Export Center:** attestation bundle export/import, provenance linking. | ||||
| - **Authority & Tenancy:** scopes, identity attestations, tenant-aware issuer catalogues. | ||||
| - **Notifications:** attestation success/failure events, key rotation alerts. | ||||
| - **Observability:** dashboards and alerting for signing/verification pipelines. | ||||
|  | ||||
| ## Acceptance criteria | ||||
| - Service ingests DSSE envelopes for all supported predicate types, logs them to configured transparency logs, and returns proofs with deterministic hashes. | ||||
| - Verification APIs/CLI/UI validate signatures, inclusion proofs, and policy compliance; cached verification accelerates repeated checks. | ||||
| - Verification policies gate attestation usage, enforcing issuer, freshness, signature count, and witness requirements. | ||||
| - Export Center and Offline Kit workflows bundle attestations and replay verification offline. | ||||
| - Observability coverage includes metrics, traces, logs, audit events, and alert triggers for key compromise, log outages, and verification failure spikes. | ||||
| - Performance target met (≥1 k envelopes/minute per worker) with horizontal scaling. | ||||
|  | ||||
| ## Risks & mitigations | ||||
| - **Key compromise or leakage:** enforce hardware-backed keys, rotation procedures, revocation checks, and incident runbooks. | ||||
| - **Parser bugs / malformed DSSE:** fuzz DSSE and predicate schemas, strict schema validation, fail closed. | ||||
| - **Transparency outage:** mirror logs, support witness endorsements, queue submissions for retry with exponential backoff. | ||||
| - **Policy complexity:** ship curated starter policies, provide simulation tooling, and document common scenarios. | ||||
| - **Offline gaps:** archive bundles and proof material, surface gaps to operators, and document compensating controls. | ||||
|  | ||||
| ## Test strategy | ||||
| - **Unit:** DSSE validation, Rekor client, dedupe logic, key drivers, policy enforcement. | ||||
| - **Integration:** submit/verify flows across predicate types, multi-log publishing, batch operations, CLI/UI end-to-end exercises. | ||||
| - **Security:** tenant isolation, scope enforcement, key rotation regression, tamper detection. | ||||
| - **Performance:** throughput benchmarks, cache hit-rate monitoring, large batch verification. | ||||
| - **Chaos:** inject Rekor outages, network failures, corrupt bundles; ensure graceful degradation and auditable alerts. | ||||
|  | ||||
| ## Definition of done | ||||
| - Phased milestones delivered with telemetry, documentation, and runbooks in place. | ||||
| - CLI/Console parity verified; Offline Kit procedures validated in sealed environment. | ||||
| - Cross-module dependencies acknowledged in ./TASKS.md and ../../TASKS.md. | ||||
| - Documentation set refreshed (overview, architecture, key management, transparency, CLI/UI) with imposed rule statement. | ||||
		Reference in New Issue
	
	Block a user