Files
git.stella-ops.org/docs/modules/policy/determinization-api.md

432 lines
16 KiB
Markdown

# Determinization Gate API Reference
> **Audience:** Backend integrators, policy operators, and security engineers working with CVE observations.
> **Sprint:** 20260106_001_003_POLICY_determinization_gates
This document describes the Determinization Gate API and the `GuardedPass` verdict status for uncertain CVE observations.
---
## 1. Overview
The Determinization Gate evaluates CVE observations against uncertainty thresholds and produces verdicts based on available evidence (EPSS, VEX, reachability, runtime, backport signals). It introduces `GuardedPass` status for observations that don't have enough evidence for a confident determination but don't exceed risk thresholds.
### Key Components
| Component | Purpose |
|-----------|---------|
| `DeterminizationGate` | Policy gate that evaluates uncertainty and produces verdicts |
| `DeterminizationPolicy` | Rule set for allow/quarantine/escalate decisions |
| `SignalUpdateHandler` | Handles signal updates and triggers re-evaluation |
| `DeterminizationGateMetrics` | OpenTelemetry metrics for observability |
---
## 2. PolicyVerdictStatus
Policy evaluations return a `PolicyVerdictStatus` indicating the outcome:
| Status | Code | Description | Monitoring Required |
|--------|------|-------------|---------------------|
| `Pass` | 0 | Finding meets policy requirements. No action needed. | No |
| `Blocked` | 1 | Finding fails policy checks; must be remediated. | No |
| `Ignored` | 2 | Finding deliberately ignored via policy exception. | No |
| `Warned` | 3 | Finding passes but with warnings. | No |
| `Deferred` | 4 | Decision deferred; needs additional evidence. | No |
| `Escalated` | 5 | Decision escalated for human review. | No |
| `RequiresVex` | 6 | VEX statement required to make decision. | No |
| `GuardedPass` | 7 | Finding allowed with runtime monitoring guardrails. | **Yes** |
---
## 3. GuardedPass Status
`GuardedPass` is a specialized status for CVE observations with uncertain evidence. It enables "allow with guardrails" semantics.
### 3.1 When Issued
- Observation has insufficient evidence for full determination (high entropy)
- Trust score below thresholds but above blocking level
- Non-production environments with moderate uncertainty
- Reachability status is unknown but not confirmed reachable
### 3.2 GuardRails Object
When `GuardedPass` is returned, the verdict includes a `guardRails` object:
```json
{
"status": "GuardedPass",
"reason": "Uncertain observation allowed with guardrails in staging",
"matchedRule": "GuardedAllowNonProd",
"guardRails": {
"enableRuntimeMonitoring": true,
"reviewInterval": "7.00:00:00",
"epssEscalationThreshold": 0.4,
"escalatingReachabilityStates": ["Reachable", "ObservedReachable"],
"maxGuardedDuration": "30.00:00:00",
"policyRationale": "Auto-allowed: entropy=0.45, trust=0.38, env=staging"
},
"suggestedObservationState": "PendingDeterminization",
"uncertaintyScore": {
"entropy": 0.45,
"completeness": 0.55,
"tier": "Medium",
"missingSignals": ["runtime", "backport"]
}
}
```
### 3.3 Consumer Responsibilities
When receiving `GuardedPass`:
1. **Enable Runtime Monitoring:** Start observing the component for vulnerable code execution
2. **Schedule Review:** Set up periodic review at `reviewInterval`
3. **EPSS Escalation:** Auto-escalate if EPSS score exceeds `epssEscalationThreshold`
4. **Reachability Escalation:** Auto-escalate if reachability transitions to escalating states
5. **Duration Limit:** Convert to `Blocked` if guard duration exceeds `maxGuardedDuration`
---
## 4. Determinization Rules
The gate evaluates rules in priority order.
### 4.1 Anchored Evidence Rules (v1.1)
> **Sprint:** SPRINT_20260112_004_BE_policy_determinization_attested_rules
Anchored evidence (DSSE-signed with optional Rekor transparency) takes highest priority in rule evaluation. These rules short-circuit evaluation when cryptographically attested evidence is present.
| Priority | Rule | Condition | Result |
|----------|------|-----------|--------|
| 1 | AnchoredAffectedWithRuntimeHardFail | Anchored VEX affected + anchored runtime telemetry confirms loading | **Blocked** (hard fail) |
| 2 | AnchoredVexNotAffectedAllow | Anchored VEX not_affected or fixed | Pass (short-circuit) |
| 3 | AnchoredBackportProofAllow | Anchored backport proof detected | Pass (short-circuit) |
| 4 | AnchoredUnreachableAllow | Anchored reachability shows unreachable | Pass (short-circuit) |
**Anchor Metadata Fields:**
Evidence anchoring is tracked via these fields on each evidence type:
```json
{
"anchor": {
"anchored": true,
"envelope_digest": "sha256:abc123...",
"predicate_type": "https://stellaops.io/vex/v1",
"rekor_log_index": 12345678,
"rekor_entry_id": "24296fb24b8ad77a...",
"scope": "finding",
"verified": true,
"attested_at": "2026-01-14T12:00:00Z"
}
}
```
Evidence types with anchor support:
- `VexClaimSummary` (via `VexClaimAnchor`)
- `BackportEvidence`
- `RuntimeEvidence`
- `ReachabilityEvidence`
### 4.2 Standard Rules
Standard rules apply when no anchored evidence short-circuits evaluation:
| Priority | Rule | Condition | Result |
|----------|------|-----------|--------|
| 10 | RuntimeEscalation | Runtime evidence shows vulnerable code loaded | Escalated |
| 20 | EpssQuarantine | EPSS score exceeds threshold | Blocked |
| 25 | ReachabilityQuarantine | Code proven reachable | Blocked |
| 30 | ProductionEntropyBlock | High entropy in production | Blocked |
| 40 | StaleEvidenceDefer | Evidence is stale | Deferred |
| 50 | GuardedAllowNonProd | Uncertain in non-prod | GuardedPass |
| 60 | UnreachableAllow | Unreachable with high confidence | Pass |
| 65 | VexNotAffectedAllow | VEX not_affected from trusted issuer | Pass |
| 70 | SufficientEvidenceAllow | Low entropy, high trust | Pass |
| 80 | GuardedAllowModerateUncertainty | Moderate uncertainty, reasonable trust | GuardedPass |
| 100 | DefaultDefer | No rule matched | Deferred |
---
## 5. Environment Thresholds
Thresholds vary by deployment environment:
| Environment | MinConfidence | MaxEntropy | EPSS Threshold | Require Reachability |
|-------------|---------------|------------|----------------|---------------------|
| Production | 0.75 | 0.3 | 0.3 | Yes |
| Staging | 0.60 | 0.5 | 0.4 | Yes |
| Development | 0.40 | 0.7 | 0.6 | No |
---
## 6. Signal Update Events
The Determinization Gate subscribes to signal updates for automatic re-evaluation:
| Event Type | Description |
|------------|-------------|
| `epss.updated` | EPSS score changed |
| `vex.updated` | VEX statement added/modified |
| `reachability.updated` | Reachability analysis completed |
| `runtime.updated` | Runtime observation recorded |
| `backport.updated` | Backport detection result |
| `observation.state_changed` | Observation state transition |
---
## 7. Metrics
OpenTelemetry metrics for monitoring:
| Metric | Type | Description |
|--------|------|-------------|
| `stellaops_policy_determinization_evaluations_total` | Counter | Total evaluations by status/environment/rule |
| `stellaops_policy_determinization_rule_matches_total` | Counter | Rule matches by rule name/status/environment |
| `stellaops_policy_observation_state_transitions_total` | Counter | State transitions by from/to state/trigger |
| `stellaops_policy_determinization_entropy` | Histogram | Distribution of entropy scores |
| `stellaops_policy_determinization_trust_score` | Histogram | Distribution of trust scores |
| `stellaops_policy_determinization_evaluation_duration_ms` | Histogram | Evaluation latency |
---
## 8. Service Registration
Add determinization services via dependency injection:
```csharp
// Register all determinization services
services.AddDeterminizationEngine();
// Or as part of full Policy Engine registration
services.AddPolicyEngine(); // Includes determinization
```
---
## 9. Related Documentation
- [Determinization Library](./determinization-architecture.md) - Core determinization models
- [Policy Engine Architecture](./architecture.md) - Overall policy engine design
- [Signal Snapshot Models](../../api/signals/reachability-contract.md) - Signal data structures
---
*Last updated: 2026-01-07 (Sprint 20260106_001_003)*
---
## 10. Unknown Mapping and Grey Queue Semantics
> **Sprint:** SPRINT_20260112_004_POLICY_unknowns_determinization_greyqueue
When evidence is incomplete or conflicting, the Determinization Gate produces outcomes that map to the "Grey Queue" for operator review.
### 10.1 Unknown State Mapping
The Grey Queue captures observations with uncertain status:
| Policy Verdict | Observation State | OpenVEX Mapping | Description |
|----------------|------------------|-----------------|-------------|
| `GuardedPass` | `PendingDeterminization` | `under_investigation` | Allowed with guardrails; monitoring required |
| `Deferred` | `PendingDeterminization` | `under_investigation` | Decision deferred; needs additional evidence |
| `Escalated` (conflict) | `Disputed` | `under_investigation` | Conflicting evidence; manual adjudication required |
### 10.2 Reanalysis Fingerprint
Each unknown is assigned a deterministic fingerprint enabling reproducible replays:
```json
{
"fingerprintId": "sha256:abc123...",
"dsseBundleDigest": "sha256:def456...",
"evidenceDigests": [
"sha256:111...",
"sha256:222..."
],
"toolVersions": {
"scanner": "2.1.0",
"reachability": "1.5.2"
},
"productVersion": "1.0.0",
"policyConfigHash": "sha256:789...",
"signalWeightsHash": "sha256:aaa...",
"computedAt": "2026-01-15T10:00:00Z",
"triggers": [
{
"type": "epss.updated@1",
"receivedAt": "2026-01-15T09:55:00Z",
"delta": 0.15
}
],
"nextActions": ["await_vex", "run_reachability"]
}
```
### 10.3 Conflict Detection and Routing
Conflicting evidence automatically routes to `Disputed` state:
| Conflict Type | Detection | Adjudication Path |
|---------------|-----------|-------------------|
| `VexReachabilityContradiction` | VEX not_affected + confirmed reachable | Manual review |
| `StaticRuntimeContradiction` | Static unreachable + runtime execution | Auto-escalate |
| `VexStatusConflict` | Multiple providers with conflicting status | Trust-weighted resolution or manual |
| `BackportStatusConflict` | Backport claimed + affected status | Manual review |
| `EpssRiskContradiction` | Low EPSS + KEV or high exploitation | Auto-escalate |
### 10.4 Trigger Events for Reanalysis
The Grey Queue tracks triggers that caused reanalysis:
| Event Type | Version | Delta Threshold | Description |
|------------|---------|-----------------|-------------|
| `epss.updated` | 1 | 0.1 | EPSS score changed significantly |
| `vex.updated` | 1 | N/A | VEX statement added/modified |
| `reachability.updated` | 1 | N/A | Reachability analysis completed |
| `runtime.updated` | 1 | N/A | Runtime observation recorded |
| `sbom.updated` | 1 | N/A | SBOM content changed |
| `dsse_validation.changed` | 1 | N/A | DSSE validation status changed |
| `rekor_entry.added` | 1 | N/A | New Rekor transparency entry |
### 10.5 Next Actions
Each unknown suggests next actions for resolution:
| Action | Description |
|--------|-------------|
| `await_vex` | Wait for vendor VEX statement |
| `run_reachability` | Execute reachability analysis |
| `enable_runtime` | Deploy runtime telemetry |
| `verify_backport` | Confirm backport availability |
| `manual_review` | Escalate to security team |
| `trust_resolution` | Resolve issuer trust conflict |
---
## 11. Related Documentation
- [Determinization Library](./determinization-architecture.md) - Core determinization models
- [Policy Engine Architecture](./architecture.md) - Overall policy engine design
- [Signal Snapshot Models](../../api/signals/reachability-contract.md) - Signal data structures
- [VEX Consensus Guide](../../VEX_CONSENSUS_GUIDE.md) - VEX correlation and consensus
---
## 12. Determinization Configuration
> **Sprint:** SPRINT_20260112_012_POLICY_determinization_reanalysis_config
The Determinization Gate uses persisted configuration for reanalysis triggers, conflict handling, and per-environment thresholds.
### 12.1 Configuration Schema
```json
{
"reanalysisTriggers": {
"epssDeltaThreshold": 0.2,
"triggerOnThresholdCrossing": true,
"triggerOnRekorEntry": true,
"triggerOnVexStatusChange": true,
"triggerOnRuntimeTelemetryChange": true,
"triggerOnPatchProofAdded": true,
"triggerOnDsseValidationChange": true,
"triggerOnToolVersionChange": false
},
"conflictHandling": {
"vexReachabilityContradiction": "RequireManualReview",
"staticRuntimeContradiction": "RequireManualReview",
"vexStatusConflict": "RequestVendorClarification",
"backportStatusConflict": "RequireManualReview",
"escalationSeverityThreshold": 0.85,
"conflictTtlHours": 48
},
"environmentThresholds": {
"production": {
"minConfidence": 0.75,
"maxEntropy": 0.3,
"epssThreshold": 0.3,
"requireReachability": true
},
"staging": {
"minConfidence": 0.60,
"maxEntropy": 0.5,
"epssThreshold": 0.4,
"requireReachability": true
},
"development": {
"minConfidence": 0.40,
"maxEntropy": 0.7,
"epssThreshold": 0.6,
"requireReachability": false
}
}
}
```
### 12.2 Reanalysis Trigger Defaults
| Trigger | Default | Description |
|---------|---------|-------------|
| `epssDeltaThreshold` | 0.2 | Minimum EPSS delta to trigger reanalysis |
| `triggerOnThresholdCrossing` | true | Trigger when EPSS crosses a bucket threshold |
| `triggerOnRekorEntry` | true | Trigger on new Rekor transparency entry |
| `triggerOnVexStatusChange` | true | Trigger when VEX status changes |
| `triggerOnRuntimeTelemetryChange` | true | Trigger on runtime exploit/reachability signals |
| `triggerOnPatchProofAdded` | true | Trigger when binary patch proof is added |
| `triggerOnDsseValidationChange` | true | Trigger when DSSE validation state changes |
| `triggerOnToolVersionChange` | false | Trigger on tool version updates (disabled by default) |
### 12.3 Conflict Handling Actions
| Action | Description |
|--------|-------------|
| `AutoResolve` | System resolves using trust scores |
| `RequireManualReview` | Route to Grey Queue for operator review |
| `RequestVendorClarification` | Queue for vendor outreach |
| `Escalate` | Escalate to security team |
| `Block` | Block until conflict is resolved |
### 12.4 Environment Threshold Presets
| Preset | MinConfidence | MaxEntropy | EPSS Threshold |
|--------|---------------|------------|----------------|
| Relaxed (dev) | 0.40 | 0.7 | 0.6 |
| Standard (staging) | 0.60 | 0.5 | 0.4 |
| Strict (production) | 0.75 | 0.3 | 0.3 |
### 12.5 Configuration API
| Endpoint | Method | Description |
|----------|--------|-------------|
| `/api/v1/policy/config/determinization` | GET | Get effective config for tenant |
| `/api/v1/policy/config/determinization/defaults` | GET | Get system defaults |
| `/api/v1/policy/config/determinization/audit` | GET | Get configuration change history |
| `/api/v1/policy/config/determinization` | PUT | Update config (policy-admin required) |
| `/api/v1/policy/config/determinization/validate` | POST | Validate config without saving |
### 12.6 Configuration Binding
In `appsettings.yaml`:
```yaml
Policy:
Determinization:
ReanalysisTriggers:
EpssDeltaThreshold: 0.2
TriggerOnThresholdCrossing: true
TriggerOnRekorEntry: true
TriggerOnVexStatusChange: true
TriggerOnToolVersionChange: false
ConflictHandling:
VexReachabilityContradiction: RequireManualReview
EscalationSeverityThreshold: 0.85
EnvironmentThresholds:
Production:
MinConfidence: 0.75
MaxEntropy: 0.3
```