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/signer/AGENTS.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								docs/modules/signer/AGENTS.md
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,22 @@ | ||||
| # Signer agent guide | ||||
|  | ||||
| ## Mission | ||||
| Signer validates callers, enforces Proof-of-Entitlement, and produces signed DSSE bundles for SBOMs, reports, and exports. | ||||
|  | ||||
| ## 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. | ||||
							
								
								
									
										30
									
								
								docs/modules/signer/README.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								docs/modules/signer/README.md
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,30 @@ | ||||
| # StellaOps Signer | ||||
|  | ||||
| Signer validates callers, enforces Proof-of-Entitlement, and produces signed DSSE bundles for SBOMs, reports, and exports. | ||||
|  | ||||
| ## Responsibilities | ||||
| - Enforce plan quotas and PoE before signing artifacts. | ||||
| - Support keyless and keyful signing backends. | ||||
| - Emit DSSE payloads consumed by Attestor and downstream bundles. | ||||
| - Maintain audit trails for all signing operations. | ||||
|  | ||||
| ## Key components | ||||
| - `StellaOps.Signer` service host. | ||||
| - Crypto providers under `StellaOps.Cryptography.*`. | ||||
|  | ||||
| ## Integrations & dependencies | ||||
| - Authority for OpTok validation. | ||||
| - Attestor for transparency logging. | ||||
| - Export Center and CLI for artifact signing flows. | ||||
|  | ||||
| ## Operational notes | ||||
| - Key management via Authority/DevOps runbooks. | ||||
| - Metrics for signing latency/throttle states. | ||||
| - Offline kit integration for signature verification. | ||||
|  | ||||
| ## Backlog references | ||||
| - SIG docs/tasks in ../../TASKS.md (e.g., DOCS-SIG-26-006). | ||||
|  | ||||
| ## Epic alignment | ||||
| - **Epic 10 – Export Center:** provide signing pipelines, cosign interoperability, and provenance manifests for bundle promotion. | ||||
| - **Epic 19 – Attestor Console:** supply DSSE payloads and Proof-of-Entitlement enforcement feeding attestation workflows described in `docs/modules/attestor/`. | ||||
							
								
								
									
										9
									
								
								docs/modules/signer/TASKS.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								docs/modules/signer/TASKS.md
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,9 @@ | ||||
| # Task board — Signer | ||||
|  | ||||
| > Local tasks should link back to ./AGENTS.md and mirror status updates into ../../TASKS.md when applicable. | ||||
|  | ||||
| | ID | Status | Owner(s) | Description | Notes | | ||||
| |----|--------|----------|-------------|-------| | ||||
| | SIGNER-DOCS-0001 | DOING (2025-10-29) | Docs Guild | Validate that ./README.md aligns with the latest release notes. | See ./AGENTS.md | | ||||
| | SIGNER-OPS-0001 | TODO | Ops Guild | Review runbooks/observability assets after next sprint demo. | Sync outcomes back to ../../TASKS.md | | ||||
| | SIGNER-ENG-0001 | TODO | Module Team | Cross-check implementation plan milestones against ../../implplan/SPRINTS.md. | Update status via ./AGENTS.md workflow | | ||||
							
								
								
									
										420
									
								
								docs/modules/signer/architecture.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										420
									
								
								docs/modules/signer/architecture.md
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,420 @@ | ||||
| # component_architecture_signer.md — **Stella Ops Signer** (2025Q4) | ||||
|  | ||||
| > Supports deliverables from Epic 10 – Export Center and Epic 19 – Attestor Console. | ||||
|  | ||||
| > **Scope.** Implementation‑ready architecture for the **Signer**: the *only* service allowed to produce **Stella Ops‑verified** signatures over SBOMs and reports. It enforces **entitlement** (PoE), **release integrity** (scanner provenance), **sender‑constrained auth** (DPoP/mTLS), and emits **in‑toto/DSSE** bundles suitable for **Rekor v2** logging by the Attestor. Includes APIs, data flow, storage, quotas, security, and test matrices. | ||||
|  | ||||
| --- | ||||
|  | ||||
| ## 0) Mission & boundaries | ||||
|  | ||||
| **Mission.** Convert authenticated signing requests from trusted Stella Ops services into **verifiable** DSSE bundles while enforcing **license policy** and **supply‑chain integrity**. | ||||
|  | ||||
| **Boundaries.** | ||||
|  | ||||
| * **Signer does not push to Rekor** — it returns DSSE to the caller; **Attestor** logs to **Rekor v2**. | ||||
| * **Signer does not compute PASS/FAIL** — it signs SBOMs/reports produced by Scanner/WebService after backend evaluation. | ||||
| * **Signer is stateless for hot path** — long‑term storage is limited to audit events; all secrets/keys live in KMS/HSM or are ephemeral (keyless). | ||||
|  | ||||
| --- | ||||
|  | ||||
| ## 1) Responsibilities (contract) | ||||
|  | ||||
| 1. **Authenticate** caller with **OpTok** (Authority OIDC, DPoP or mTLS‑bound). | ||||
| 2. **Authorize** scopes (`signer.sign`) + audience (`aud=signer`) + tenant/installation. | ||||
| 3. **Validate entitlement** via **PoE** (Proof‑of‑Entitlement) against Cloud Licensing `/license/introspect`. | ||||
| 4. **Verify release integrity** of the **scanner** image digest presented in the request: must be **cosign‑signed** by Stella Ops release key, discoverable via **OCI Referrers API**. | ||||
| 5. **Enforce plan & quotas** (concurrency/QPS/artifact size/rate caps). | ||||
| 6. **Mint signing identity**: | ||||
|  | ||||
|    * **Keyless** (default): get a short‑lived X.509 cert from **Fulcio** using the Signer’s OIDC identity and sign the DSSE. | ||||
|    * **Keyful** (optional): sign with an HSM/KMS key. | ||||
| 7. **Return DSSE bundle** (subject digests + predicate + cert chain or KMS key id). | ||||
| 8. **Audit** every decision; expose metrics. | ||||
|  | ||||
| --- | ||||
|  | ||||
| ## 2) External dependencies | ||||
|  | ||||
| * **Authority** (on‑prem OIDC): validates OpToks (JWKS/introspection) and DPoP/mTLS. | ||||
| * **Licensing Service (cloud)**: `/license/introspect` to verify PoE (active, claims, expiry, revocation). | ||||
| * **Fulcio** (Sigstore) *or* **KMS/HSM**: to obtain certs or perform signatures. | ||||
| * **OCI Registry (Referrers API)**: to verify **scanner** image release signature. | ||||
| * **Attestor**: downstream service that writes DSSE bundles to **Rekor v2**. | ||||
| * **Config/state stores**: Redis (caches, rate buckets), Mongo/Postgres (audit log). | ||||
|  | ||||
| --- | ||||
|  | ||||
| ## 3) API surface (mTLS; DPoP supported) | ||||
|  | ||||
| Base path: `/api/v1/signer`. **All endpoints require**: | ||||
|  | ||||
| * Access token (JWT) from **Authority** with `aud=signer`, `scope=signer.sign`. | ||||
| * **Sender constraint**: DPoP proof per request or mTLS client cert. | ||||
| * **PoE** presented as either: | ||||
|  | ||||
|   * **Client TLS cert** (if PoE is mTLS‑style) chained to Licensing CA, *or* | ||||
|   * **PoE JWT** (DPoP/mTLS‑bound) in `X-PoE` header or request body. | ||||
|  | ||||
| ### 3.1 `POST /sign/dsse` | ||||
|  | ||||
| Request (JSON): | ||||
|  | ||||
| ```json | ||||
| { | ||||
|   "subject": [ | ||||
|     { "name": "s3://stellaops/images/sha256:.../inventory.cdx.pb", | ||||
|       "digest": { "sha256": "..." } } | ||||
|   ], | ||||
|   "predicateType": "https://stella-ops.org/attestations/sbom/1", | ||||
|   "predicate": { | ||||
|     "image_digest": "sha256:...", | ||||
|     "stellaops_version": "2.3.1 (2027.04)", | ||||
|     "license_id": "LIC-9F2A...", | ||||
|     "customer_id": "CUST-ACME", | ||||
|     "plan": "pro", | ||||
|     "policy_digest": "sha256:...",        // optional for final reports | ||||
|     "views": ["inventory", "usage"], | ||||
|     "created": "2025-10-17T12:34:56Z" | ||||
|   }, | ||||
|   "scannerImageDigest": "sha256:sc-web-or-worker-digest", | ||||
|   "poe": { | ||||
|     "format": "jwt",                      // or "mtls" | ||||
|     "value": "eyJhbGciOi..."              // PoE JWT when not using mTLS PoE | ||||
|   }, | ||||
|   "options": { | ||||
|     "signingMode": "keyless",             // "keyless" | "kms" | ||||
|     "expirySeconds": 600,                 // cert lifetime hint (keyless) | ||||
|     "returnBundle": "dsse+cert"           // dsse (default) | dsse+cert | ||||
|   } | ||||
| } | ||||
| ``` | ||||
|  | ||||
| Response 200: | ||||
|  | ||||
| ```json | ||||
| { | ||||
|   "bundle": { | ||||
|     "dsse": { "payloadType": "application/vnd.in-toto+json", "payload": "<base64>", "signatures": [ ... ] }, | ||||
|     "certificateChain": [ "-----BEGIN CERTIFICATE-----...", "... root ..." ], | ||||
|     "mode": "keyless", | ||||
|     "signingIdentity": { "issuer": "https://fulcio.internal", "san": "urn:stellaops:signer", "certExpiry": "2025-10-17T12:44:56Z" } | ||||
|   }, | ||||
|   "policy": { "plan": "pro", "maxArtifactBytes": 104857600, "qpsRemaining": 97 }, | ||||
|   "auditId": "a7c9e3f2-1b7a-4e87-8c3a-90d7d2c3ad12" | ||||
| } | ||||
| ``` | ||||
|  | ||||
| Errors (RFC 7807): | ||||
|  | ||||
| * `401 invalid_token` (JWT/DPoP/mTLS failure) | ||||
| * `403 entitlement_denied` (PoE invalid/revoked/expired; release year mismatch) | ||||
| * `403 release_untrusted` (scanner image not Stella‑signed) | ||||
| * `429 plan_throttled` (license plan caps) | ||||
| * `413 artifact_too_large` (size cap) | ||||
| * `400 invalid_request` (schema/predicate/type invalid) | ||||
| * `500 signing_unavailable` (Fulcio/KMS outage) | ||||
|  | ||||
| ### 3.2 `GET /verify/referrers?imageDigest=<sha256>` | ||||
|  | ||||
| Checks whether the **image** at digest is signed by **Stella Ops release key**. | ||||
|  | ||||
| Response: | ||||
|  | ||||
| ```json | ||||
| { "trusted": true, "signatures": [ { "type": "cosign", "digest": "sha256:...", "signedBy": "StellaOps Release 2027 Q2" } ] } | ||||
| ``` | ||||
|  | ||||
| > **Note:** This endpoint is also used internally by Signer before issuing signatures. | ||||
|  | ||||
| --- | ||||
|  | ||||
| ## 4) Validation pipeline (hot path) | ||||
|  | ||||
| ```mermaid | ||||
| sequenceDiagram | ||||
|   autonumber | ||||
|   participant Client as Scanner.WebService | ||||
|   participant Auth as Authority (OIDC) | ||||
|   participant Sign as Signer | ||||
|   participant Lic as Licensing Service (cloud) | ||||
|   participant Reg as OCI Registry (Referrers) | ||||
|   participant Ful as Fulcio/KMS | ||||
|  | ||||
|   Client->>Sign: POST /sign/dsse (OpTok + DPoP/mTLS, PoE, request) | ||||
|   Note over Sign: 1) Validate OpTok, audience, scope, DPoP/mTLS binding | ||||
|   Sign->>Lic: /license/introspect(PoE) | ||||
|   Lic-->>Sign: { active, claims: {license_id, plan, valid_release_year, max_version}, exp } | ||||
|   Note over Sign: 2) Enforce plan/version window and revocation | ||||
|  | ||||
|   Sign->>Reg: Verify scannerImageDigest signed (Referrers + cosign) | ||||
|   Reg-->>Sign: OK with signer identity | ||||
|   Note over Sign: 3) Enforce release integrity | ||||
|  | ||||
|   Note over Sign: 4) Enforce quotas (QPS/concurrency/size) | ||||
|   Sign->>Ful: Mint cert (keyless) or sign via KMS | ||||
|   Ful-->>Sign: Cert or signature | ||||
|  | ||||
|   Sign-->>Client: DSSE bundle (+cert chain), policy counters, auditId | ||||
| ``` | ||||
|  | ||||
| **DPoP nonce dance (when enabled for high‑value ops):** | ||||
|  | ||||
| * If DPoP proof lacks a valid nonce, Signer replies `401` with `WWW-Authenticate: DPoP error="use_dpop_nonce", dpop_nonce="<nonce>"`. | ||||
| * Client retries with new proof including the nonce; Signer validates nonce and `jti` uniqueness (Redis TTL cache). | ||||
|  | ||||
| --- | ||||
|  | ||||
| ## 5) Entitlement enforcement (PoE) | ||||
|  | ||||
| * **Accepted forms**: | ||||
|  | ||||
|   * **mTLS PoE**: client presents a **PoE client cert** at TLS handshake; Signer validates chain to **Licensing CA** (CA bundle configured) and calls `/license/introspect` with cert thumbprint + serial. | ||||
|   * **JWT PoE**: `X-PoE` bearer token (DPoP/mTLS‑bound) is validated (sig + `cnf`) locally (Licensing JWKS) and then **introspected** for status and claims. | ||||
|  | ||||
| * **Claims required**: | ||||
|  | ||||
|   * `license_id`, `plan` (free|pro|enterprise|gov), `valid_release_year`, `max_version`, `exp`. | ||||
|   * Optional: `tenant_id`, `customer_id`, `entitlements[]`. | ||||
|  | ||||
| * **Enforcements**: | ||||
|  | ||||
|   * Reject if **revoked**, **expired**, **plan mismatch** or **release outside window** (`stellaops_version` in predicate exceeds `max_version` or release date beyond `valid_release_year`). | ||||
|   * Apply plan **throttles** (QPS/concurrency/artifact bytes) via token‑bucket in Redis keyed by `license_id`. | ||||
|  | ||||
| --- | ||||
|  | ||||
| ## 6) Release integrity (scanner provenance) | ||||
|  | ||||
| * **Input**: `scannerImageDigest` representing the actual Scanner component that produced the artifact. | ||||
|  | ||||
| * **Check**: | ||||
|  | ||||
|   1. Use **OCI Referrers API** to enumerate signatures of that digest. | ||||
|   2. Verify **cosign** signatures against the configured **Stella Ops Release** keyring (keyless Fulcio roots *or* keyful public keys). | ||||
|   3. Optionally require Rekor inclusion for those signatures. | ||||
|  | ||||
| * **Policy**: | ||||
|  | ||||
|   * If not signed by an authorized **Stella Ops Release** identity → **deny**. | ||||
|   * If signed but **release year** > PoE `valid_release_year` → **deny**. | ||||
|  | ||||
| * **Cache**: LRU of digest → verification result (TTL 10–30 min) to avoid registry thrash. | ||||
|  | ||||
| --- | ||||
|  | ||||
| ## 7) Signing modes | ||||
|  | ||||
| ### 7.1 Keyless (default; Sigstore Fulcio) | ||||
|  | ||||
| * Signer authenticates to **Fulcio** using its on‑prem OIDC identity (client credentials) and requests a **short‑lived cert** (5–10 min). | ||||
| * Generates **ephemeral keypair**, gets cert for the public key, signs DSSE with the **private key**. | ||||
| * DSSE **bundle** includes **certificate chain**; verifiers validate to Fulcio root. | ||||
|  | ||||
| ### 7.2 Keyful (optional; KMS/HSM) | ||||
|  | ||||
| * Signer uses a configured **KMS** key (AWS KMS, GCP KMS, Azure Key Vault, Vault Transit, or HSM). | ||||
| * DSSE bundle includes **key metadata** (kid, cert chain if x509). | ||||
| * Recommended for FIPS/sovereign environments. | ||||
|  | ||||
| --- | ||||
|  | ||||
| ## 8) Predicates & schema | ||||
|  | ||||
| Supported **predicate types** (extensible): | ||||
|  | ||||
| * `https://stella-ops.org/attestations/sbom/1` (SBOM emissions) | ||||
| * `https://stella-ops.org/attestations/report/1` (final PASS/FAIL reports) | ||||
| * `https://stella-ops.org/attestations/vex-export/1` (Excititor exports; optional) | ||||
|  | ||||
| **Validation**: | ||||
|  | ||||
| * JSON‑Schema per predicate type; **canonical property order**. | ||||
| * `subject[*].digest` must include `sha256`. | ||||
| * `predicate.stellaops_version` must parse and match policy windows. | ||||
|  | ||||
| --- | ||||
|  | ||||
| ## 9) Quotas & throttling | ||||
|  | ||||
| Per `license_id` (from PoE): | ||||
|  | ||||
| * **QPS** (token bucket), **concurrency** (semaphore), **artifact bytes** (sliding window). | ||||
| * On exceed → `429 plan_throttled` with `Retry-After`. | ||||
| * Free/community plan may also receive **randomized delay** to disincentivize farmed signing. | ||||
|  | ||||
| --- | ||||
|  | ||||
| ## 10) Storage & caches | ||||
|  | ||||
| * **Redis**: | ||||
|  | ||||
|   * DPoP nonce & `jti` replay cache (TTL ≤ 10 min). | ||||
|   * PoE introspection cache (short TTL, e.g., 60–120 s). | ||||
|   * Release‑verify cache (`scannerImageDigest` → { trusted, ts }). | ||||
|  | ||||
| * **Audit store** (Mongo or Postgres): `signer.audit_events` | ||||
|  | ||||
| ``` | ||||
| { _id, ts, tenantId, installationId, licenseId, customerId, | ||||
|   plan, actor{sub,cnf}, request{predicateType, subjectSha256[], imageDigest}, | ||||
|   poe{type, thumbprint|jwtKid, exp, introspectSnapshot}, | ||||
|   release{digest, signerId, policy}, | ||||
|   mode: "keyless"|"kms", | ||||
|   result: "success"|"deny:<reason>"|"error:<reason>", | ||||
|   bundleSha256? } | ||||
| ``` | ||||
|  | ||||
| * **Config**: Stella Ops release signing keyring, Fulcio roots, Licensing CA bundle. | ||||
|  | ||||
| --- | ||||
|  | ||||
| ## 11) Security & privacy | ||||
|  | ||||
| * **mTLS** on all Signer endpoints. | ||||
| * **No bearer fallbacks** — DPoP/mTLS enforced for `aud=signer`. | ||||
| * **PoE** is never persisted beyond audit snapshots (minimized fields). | ||||
| * **Secrets**: no long‑lived private keys on disk (keyless) or handled via KMS APIs. | ||||
| * **Input hardening**: schema‑validate predicates; cap payload sizes; zstd/gzip decompression bombs guarded. | ||||
| * **Logging**: redact PoE JWTs, access tokens, DPoP proofs; log only hashes and identifiers. | ||||
|  | ||||
| --- | ||||
|  | ||||
| ## 12) Metrics & observability | ||||
|  | ||||
| * `signer.requests_total{result}` | ||||
| * `signer.latency_seconds{stage=auth|introspect|release_verify|sign}` | ||||
| * `signer.poe_failures_total{reason}` | ||||
| * `signer.release_verify_failures_total{reason}` | ||||
| * `signer.plan_throttle_total{license_id}` | ||||
| * `signer.bundle_bytes_total` | ||||
| * `signer.keyless_certs_issued_total` / `signer.kms_sign_total` | ||||
| * OTEL traces across stages; correlation id (`auditId`) returned to client. | ||||
|  | ||||
| --- | ||||
|  | ||||
| ## 13) Configuration (YAML) | ||||
|  | ||||
| ```yaml | ||||
| signer: | ||||
|   listen: "https://0.0.0.0:8443" | ||||
|   authority: | ||||
|     issuer: "https://authority.internal" | ||||
|     jwksUrl: "https://authority.internal/jwks" | ||||
|     require: "dpop"         # "dpop" | "mtls" | ||||
|   poe: | ||||
|     mode: "both"            # "jwt" | "mtls" | "both" | ||||
|     licensing: | ||||
|       introspectUrl: "https://www.stella-ops.org/api/v1/license/introspect" | ||||
|       caBundle: "/etc/ssl/licensing-ca.pem" | ||||
|       cacheTtlSeconds: 90 | ||||
|   release: | ||||
|     referrers: | ||||
|       allowRekorVerified: true | ||||
|       keyrings: | ||||
|         - type: "cosign-keyless" | ||||
|           fulcioRoots: ["/etc/fulcio/root.pem"] | ||||
|           identities: | ||||
|             - san: "mailto:release@stella-ops.org" | ||||
|             - san: "https://sigstore.dev/oidc/stellaops" | ||||
|   signing: | ||||
|     mode: "keyless"         # "keyless" | "kms" | ||||
|     fulcio: | ||||
|       issuer: "https://fulcio.internal" | ||||
|       oidcClientId: "signer" | ||||
|       oidcClientSecretRef: "env:FULCIO_CLIENT_SECRET" | ||||
|       certTtlSeconds: 600 | ||||
|     kms: | ||||
|       provider: "aws-kms" | ||||
|       keyId: "arn:aws:kms:...:key/..." | ||||
|   quotas: | ||||
|     default: | ||||
|       qps: 100 | ||||
|       concurrency: 20 | ||||
|       maxArtifactBytes: 104857600 | ||||
|     free: | ||||
|       qps: 5 | ||||
|       concurrency: 1 | ||||
|       maxArtifactBytes: 1048576 | ||||
| ``` | ||||
|  | ||||
| --- | ||||
|  | ||||
| ## 14) Testing matrix | ||||
|  | ||||
| * **Auth & DPoP**: bad `aud`, wrong `jkt`, replayed `jti`, missing nonce, mTLS mismatch. | ||||
| * **PoE**: expired, revoked, plan mismatch, release year gate, max_version gate. | ||||
| * **Release verify**: unsigned digest, wrong signer, Rekor‑absent (when required), referrers unreachable. | ||||
| * **Signing**: Fulcio outage; KMS timeouts; bundle correctness (verifier harness). | ||||
| * **Quotas**: burst above QPS, artifact over size, concurrency overflow. | ||||
| * **Schema**: invalid predicate types/required fields. | ||||
| * **Determinism**: same request → identical DSSE (aside from cert validity period). | ||||
| * **Perf**: P95 end‑to‑end under 120 ms with caches warm (excluding network to Fulcio). | ||||
|  | ||||
| --- | ||||
|  | ||||
| ## 15) Failure modes & responses | ||||
|  | ||||
| | Failure                 | HTTP | Problem type          | Notes                                        | | ||||
| | ----------------------- | ---- | --------------------- | -------------------------------------------- | | ||||
| | Invalid OpTok / DPoP    | 401  | `invalid_token`       | `WWW-Authenticate` with DPoP nonce if needed | | ||||
| | PoE invalid/revoked     | 403  | `entitlement_denied`  | Include `license_id` (hashed) and reason     | | ||||
| | Scanner image untrusted | 403  | `release_untrusted`   | Include digest and required identity         | | ||||
| | Plan throttle           | 429  | `plan_throttled`      | Include limits and `Retry-After`             | | ||||
| | Artifact too large      | 413  | `artifact_too_large`  | Include cap                                  | | ||||
| | Fulcio/KMS down         | 503  | `signing_unavailable` | Retry‑After with jitter                      | | ||||
|  | ||||
| --- | ||||
|  | ||||
| ## 16) Deployment & HA | ||||
|  | ||||
| * Run ≥ 2 replicas; front with L7 LB; **sticky** not required. | ||||
| * Redis for replay/quota caches (HA). | ||||
| * Audit sink (Mongo/Postgres) in primary region; asynchronous write with local fallback buffer. | ||||
| * Fulcio/KMS clients configured with retries/backoff; circuit breakers. | ||||
|  | ||||
| --- | ||||
|  | ||||
| ## 17) Implementation notes | ||||
|  | ||||
| * **.NET 10** minimal API + Kestrel mTLS; custom DPoP middleware; JWT/JWKS cache. | ||||
| * **Cosign verification** via sigstore libraries; Referrers queries over registry API with retries. | ||||
| * **DSSE** via in‑toto libs; canonical JSON writer for predicates. | ||||
| * **Backpressure** paths: refuse at auth/quota stages before any expensive network calls. | ||||
|  | ||||
| --- | ||||
|  | ||||
| ## 18) Examples (wire) | ||||
|  | ||||
| **Request (free plan; expect throttle if burst):** | ||||
|  | ||||
| ```http | ||||
| POST /api/v1/signer/sign/dsse HTTP/1.1 | ||||
| Authorization: DPoP <JWT> | ||||
| DPoP: <proof> | ||||
| Content-Type: application/json | ||||
|  | ||||
| ``` | ||||
|  | ||||
| **Error (release untrusted):** | ||||
|  | ||||
| ```json | ||||
| { | ||||
|   "type": "https://stella-ops.org/problems/release_untrusted", | ||||
|   "title": "Scanner image not signed by StellaOps", | ||||
|   "status": 403, | ||||
|   "detail": "sha256:abcd... not in trusted keyring", | ||||
|   "instance": "urn:audit:a7c9e3f2-..." | ||||
| } | ||||
| ``` | ||||
|  | ||||
| --- | ||||
|  | ||||
| ## 19) Roadmap | ||||
|  | ||||
| * **Key Transparency**: optional publication of Signer’s *own* certs to a KT log. | ||||
| * **Attested Build**: SLSA‑style provenance for Signer container itself, checked at startup. | ||||
| * **FIPS mode**: enforce `ES256` + KMS/HSM only; disallow Ed25519. | ||||
| * **Dual attestation**: optional immediate push to **Attestor** (sync mode) with timeout budget, returning Rekor UUID inline. | ||||
|  | ||||
| 
 | ||||
							
								
								
									
										61
									
								
								docs/modules/signer/implementation_plan.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										61
									
								
								docs/modules/signer/implementation_plan.md
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,61 @@ | ||||
| # Implementation plan — Signer | ||||
|  | ||||
| ## Delivery phases | ||||
| - **Phase 1 – Core service & PoE**   | ||||
|   Harden OpTok validation, Proof-of-Entitlement (PoE) checks, quota enforcement, scanner release verification, and DSSE signing pipeline (keyless + keyful). | ||||
| - **Phase 2 – Export Center integration**   | ||||
|   Produce signing bundles with provenance manifests for Export Center, deliver cosign-compatible outputs, and document verification workflows for offline exports. | ||||
| - **Phase 3 – Attestor alignment**   | ||||
|   Emit DSSE envelopes, metadata, and signer identity information required by Attestor (key metadata, certificate chains, bundle hashes); expose audit APIs. | ||||
| - **Phase 4 – Observability & resilience**   | ||||
|   Complete telemetry, throttling dashboards, audit trails, fallback key rotation, and offline kit packaging. | ||||
|  | ||||
| ## Work breakdown | ||||
| - **Authentication & entitlement** | ||||
|   - Enforce Authority-issued DPoP/mTLS tokens with `signer.sign` scope and tenant checks. | ||||
|   - Integrate PoE introspection (cloud licensing) and plan quotas. | ||||
|   - Validate scanner release signature via OCI referrers before signing reports/SBOMs. | ||||
| - **Signing pipeline** | ||||
|   - Implement DSSE canonicalisation, keyless (Fulcio) and keyful (KMS/HSM/FIDO2) signing. | ||||
|   - Support multi-signature output, certificate chain embedding, and deterministic bundle hashing. | ||||
|   - Provide policy metadata (policy digest, view set) for report predicates. | ||||
| - **Integrations** | ||||
|   - Coordinate with Attestor on bundle schema, signer identity payload, and error codes. | ||||
|   - Expose Export Center-ready signing API (`/sign/export`) that returns manifest + signature tuple. | ||||
|   - Surface CLI flows (`stella sign sbom/report`, offline verification helpers). | ||||
| - **Security & key management** | ||||
|   - Key rotation and revocation runbooks; separation of signing keys per tenancy/plan. | ||||
|   - Hardware-backed key support (HSM/FIDO2) with audit logging and attested builds. | ||||
| - **Observability** | ||||
|   - Metrics: signing latency, PoE failures, quota hits, key usage distribution. | ||||
|   - Structured logs with trace/context IDs, subject digests, issuer mode, decision outcome. | ||||
|   - Alerts for PoE outages, key exhaustion, quota breach, signing failure spikes. | ||||
| - **Documentation & runbooks** | ||||
|   - Update README/architecture/implementation plan, operator runbooks, offline verification guidance, and CLI reference. | ||||
|  | ||||
| ## Acceptance criteria | ||||
| - Signer only signs requests that satisfy OpTok, PoE, quota, and scanner provenance checks. | ||||
| - DSSE outputs (keyless + keyful) verify with standard cosign tooling; Attestor logs them without additional transformation. | ||||
| - Export Center receives signed bundles, provenance manifests, and signature metadata to package exports deterministically. | ||||
| - Audit logs capture every signing request with tenant, issuer, subject digest, PoE state, and key source. | ||||
| - Observability dashboards/alerts reflect latency, failure rate, PoE status, and quota usage. | ||||
| - CLI/Offline workflows verify signatures using Offline Kit trust roots. | ||||
|  | ||||
| ## Risks & mitigations | ||||
| - **PoE/entitlement outages:** cache last-known entitlement within TTL, provide emergency bypass toggles with audit trail. | ||||
| - **Key compromise:** enforce hardware-backed keys, rotation cadence, immediate revocation workflow, incident runbook. | ||||
| - **Release verification failures:** maintain allowlist for trusted scanner digests, fallback to manual approval with audit. | ||||
| - **Determinism drift:** canonicalise JSON, lock timestamp sources, regression tests for DSSE hashing. | ||||
|  | ||||
| ## Test strategy | ||||
| - **Unit:** OpTok/PoE validation, quota enforcement, scanner signature verification, DSSE canonicalisation, multi-sig bundling. | ||||
| - **Integration:** end-to-end signing for SBOM, report, export artifacts; Attestor ingestion; Export Center bundle signing. | ||||
| - **Security:** fuzz signing inputs, simulate PoE tampering, ensure unauthorized actors are rejected. | ||||
| - **Performance:** signing throughput benchmarks (keyless vs keyful), quota pressure, concurrency checks. | ||||
| - **Offline:** verify signatures using Offline Kit trust roots and cosign CLI without network access. | ||||
|  | ||||
| ## Definition of done | ||||
| - Signing pipeline deployed with observability and incident runbooks. | ||||
| - Export Center + Attestor dependencies validated; CLI parity confirmed. | ||||
| - Documentation updated (README, architecture, runbooks, CLI guides) with imposed rule compliance. | ||||
| - ./TASKS.md and ../../TASKS.md reflect the latest status transitions. | ||||
		Reference in New Issue
	
	Block a user