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:
		
							
								
								
									
										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.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user