save checkpoint
This commit is contained in:
@@ -0,0 +1,95 @@
|
||||
# Evidence-Based Release Gates Contract
|
||||
|
||||
**Status:** Implemented baseline in promotion runtime (2026-02-10)
|
||||
**Related:** `docs/modules/release-orchestrator/workflow/promotion.md`, `docs/modules/attestor/repro-bundle-profile.md`, `docs/modules/evidence-locker/architecture.md`
|
||||
|
||||
## Purpose
|
||||
|
||||
Define a deterministic, policy-driven promotion gate model where release decisions are made from verifiable evidence, not ad hoc logic. This contract translates the evidence-based gate advisory into Stella Ops module boundaries and delivery tasks.
|
||||
|
||||
## Gate Policy Model (Data-Driven)
|
||||
|
||||
Gate policy is treated as versioned data (for example CUE compiled to JSON, or equivalent policy-pack JSON). At minimum, the gate policy profile must declare:
|
||||
|
||||
- `name`, `environment`
|
||||
- `evidence.min_score`, `evidence.required_links`, `evidence.product_digest_alg`
|
||||
- `signatures.k_of_n.k`, `signatures.k_of_n.n`, `signatures.allowed_keys`, `signatures.dsse_algos`
|
||||
- `rekor.required`, `rekor.instance_url`, `rekor.max_fresh_secs`
|
||||
- `retry.backoff_initial_ms`, `retry.backoff_factor`, `retry.max_retries`
|
||||
- `escalation.mode`, `escalation.human_queue`, `escalation.require_signed_human_decision`
|
||||
- `slo.p50_ms`, `slo.p90_ms`, `slo.p99_ms`, `slo.async_hold_sla_hours`, `slo.evidence_ttl_hours`
|
||||
|
||||
## Required Promotion Checks
|
||||
|
||||
Promotion gate evaluation must enforce all enabled checks below:
|
||||
|
||||
1. Evidence score threshold
|
||||
- Require `evidence_score >= policy.evidence.min_score`.
|
||||
|
||||
2. Rekor inclusion and freshness
|
||||
- Require inclusion proof present and verified when `policy.rekor.required=true`.
|
||||
- Require proof freshness within `policy.rekor.max_fresh_secs`.
|
||||
|
||||
3. In-toto build link + digest binding
|
||||
- Require `build` link when configured in `policy.evidence.required_links`.
|
||||
- Require build product digest to exactly match release artifact digest under `policy.evidence.product_digest_alg`.
|
||||
|
||||
4. DSSE signer threshold (k-of-n)
|
||||
- Count only valid signatures whose key IDs and algorithms are in policy allowlists.
|
||||
- Require `valid_unique_signers >= policy.signatures.k_of_n.k`.
|
||||
|
||||
## Decision Workflow Contract
|
||||
|
||||
Promotion flow for evidence gates:
|
||||
|
||||
`collect_evidence -> evaluate_gate_sync -> { approve | hold_async | escalate }`
|
||||
|
||||
Decision semantics:
|
||||
|
||||
- `approve`: all enabled checks pass.
|
||||
- `hold_async`: heavyweight evidence still pending; re-evaluate on evidence arrival or TTL expiry.
|
||||
- `escalate`: retries exhausted or policy requires human disposition; require DSSE-signed human decision when configured.
|
||||
|
||||
Runtime mapping:
|
||||
- `hold_async` is persisted as `DecisionOutcome.HoldAsync` (legacy `PendingGate` remains for compatibility).
|
||||
- `escalate` is persisted as `DecisionOutcome.Escalate`.
|
||||
|
||||
## Lane Defaults
|
||||
|
||||
- Sovereign and air-gap lanes default to `fail_closed`.
|
||||
- Dev lanes may use `fail_open_with_alert` only with mandatory audit record and alert emission.
|
||||
|
||||
## Audit and Replay Requirements
|
||||
|
||||
For each gate decision, persist immutable evidence pointers and gate inputs:
|
||||
|
||||
- policy identifier and version/digest
|
||||
- gate input hashes and evidence bundle references
|
||||
- DSSE envelope references and signer IDs counted toward k-of-n
|
||||
- Rekor UUIDs/log index/inclusion proof references and freshness timestamp
|
||||
- decision outcome, reason codes, retries, escalation routing
|
||||
- wall-clock timing metrics for SLO tracking
|
||||
- human decision DSSE reference when escalation occurs
|
||||
|
||||
## SLO Targets
|
||||
|
||||
Synchronous gate targets:
|
||||
|
||||
- P50 <= 200 ms
|
||||
- P90 <= 2 s
|
||||
- P99 <= 15 s
|
||||
|
||||
Asynchronous hold targets:
|
||||
|
||||
- `async_hold_sla_hours <= 12` (default profile)
|
||||
- `evidence_ttl_hours <= 24` with re-evaluation when stale
|
||||
|
||||
## Implementation Notes (2026-02-10)
|
||||
|
||||
- `SecurityGate` now enforces policy-configured checks for:
|
||||
- `minEvidenceScore` threshold (`SEC_REPRO_EVIDENCE_SCORE_THRESHOLD`)
|
||||
- in-toto build-link presence + digest binding (`SEC_REPRO_BUILD_LINK_MISSING`, `SEC_REPRO_BUILD_DIGEST_MISMATCH`)
|
||||
- DSSE k-of-n signer threshold (`SEC_REPRO_DSSE_THRESHOLD`)
|
||||
- Rekor freshness TTL with retry + escalation mode (`SEC_REPRO_REKOR_FRESHNESS_*`, `SEC_ESCALATION_*`)
|
||||
- Environment gate-specific policy config is now propagated into gate evaluation context by `DecisionEngine`.
|
||||
- Decision recording now captures SLO metadata (`p50/p90/p99`, async hold SLA, evidence TTL) and DSSE human decision reference when present.
|
||||
@@ -4,6 +4,12 @@
|
||||
|
||||
Promotions move releases through environments (Dev -> Staging -> Production). The promotion state machine manages the lifecycle from request to completion.
|
||||
|
||||
For policy-driven evidence gate inputs, checks, and outcomes, see `evidence-based-release-gates.md`.
|
||||
|
||||
Evidence-gate outcomes include explicit `hold_async` and `escalate` semantics in decision records:
|
||||
- `hold_async` maps to `DecisionOutcome.HoldAsync` for asynchronous evidence completion.
|
||||
- `escalate` maps to `DecisionOutcome.Escalate` when retry budgets are exhausted or lane policy requires human disposition.
|
||||
|
||||
## Promotion States
|
||||
|
||||
```
|
||||
|
||||
Reference in New Issue
Block a user