save progress

This commit is contained in:
StellaOps Bot
2026-01-03 00:47:24 +02:00
parent 3f197814c5
commit ca578801fd
319 changed files with 32478 additions and 2202 deletions

View File

@@ -0,0 +1,490 @@
# Policy Evaluation Flow
## Overview
The Policy Evaluation Flow describes how StellaOps applies K4 lattice logic to vulnerability findings, incorporating VEX statements, reachability analysis, and confidence scoring to produce deterministic pass/fail verdicts. This is the core decision-making flow that determines whether a container image meets security requirements.
**Business Value**: Consistent, explainable security verdicts with full audit trail for compliance and governance.
## Actors
| Actor | Type | Role |
|-------|------|------|
| Scanner | Service | Submits findings for evaluation |
| Policy Engine | Service | Applies policy rules |
| VexLens | Service | Provides VEX consensus |
| ReachGraph | Service | Provides reachability state |
| Policy Store | Component | Stores policy definitions |
## Prerequisites
- Policy set configured for the tenant
- Scan findings generated with SBOM
- VEX statements loaded (optional)
- Reachability analysis completed (optional)
## K4 Lattice Model
StellaOps uses a 7-state K4 lattice for vulnerability reachability:
```
┌─────────────────────┐
│ ConfirmedReachable │ (Highest certainty)
└──────────┬──────────┘
┌──────────────────────┼──────────────────────┐
│ │ │
▼ ▼ ▼
┌───────────────┐ ┌────────────────┐ ┌─────────────────┐
│RuntimeObserved│ │StaticallyReach.│ │ Contested │
└───────┬───────┘ └────────┬───────┘ └────────┬────────┘
│ │ │
└──────────────────────┼──────────────────────┘
┌─────────────────────┐
│ Unknown │ (Default state)
└──────────┬──────────┘
┌──────────────────────┼──────────────────────┐
│ │ │
▼ ▼ ▼
┌───────────────┐ ┌────────────────┐ ┌─────────────────┐
│RuntimeUnobserv│ │Statically Unr. │ │ │
└───────┬───────┘ └────────┬───────┘ └─────────────────┘
│ │
└──────────┬──────────┘
┌─────────────────────┐
│ConfirmedUnreachable │ (Lowest risk)
└─────────────────────┘
```
### State Definitions
| State | Code | Description |
|-------|------|-------------|
| Unknown | `U` | No reachability data available |
| StaticallyReachable | `SR` | Static analysis shows potential call path |
| StaticallyUnreachable | `SU` | Static analysis shows no call path |
| RuntimeObserved | `RO` | Runtime telemetry confirmed execution |
| RuntimeUnobserved | `RU` | Runtime telemetry shows no execution |
| ConfirmedReachable | `CR` | Both static and runtime confirm reachability |
| ConfirmedUnreachable | `CU` | Both static and runtime confirm unreachable |
| Contested | `X` | Conflicting evidence (requires review) |
## Flow Diagram
```
┌─────────────────────────────────────────────────────────────────────────────────┐
│ Policy Evaluation Flow │
└─────────────────────────────────────────────────────────────────────────────────┘
┌─────────┐ ┌─────────┐ ┌─────────┐ ┌───────────┐ ┌─────────────┐
│ Scanner │ │ Policy │ │ VexLens │ │ ReachGraph│ │Policy Store │
└────┬────┘ └────┬────┘ └────┬────┘ └─────┬─────┘ └──────┬──────┘
│ │ │ │ │
│ Evaluate │ │ │ │
│ request │ │ │ │
│────────────>│ │ │ │
│ │ │ │ │
│ │ Load policy │ │ │
│ │ set │ │ │
│ │─────────────────────────────────────────────>
│ │ │ │ │
│ │ Policy │ │ │
│ │ rules │ │ │
│ │<─────────────────────────────────────────────
│ │ │ │ │
│ │ Get VEX │ │ │
│ │ consensus │ │ │
│ │────────────>│ │ │
│ │ │ │ │
│ │ │ Query issuers│ │
│ │ │──────┐ │ │
│ │ │ │ │ │
│ │ │<─────┘ │ │
│ │ │ │ │
│ │ VEX status │ │ │
│ │ per CVE │ │ │
│ │<────────────│ │ │
│ │ │ │ │
│ │ Get reach │ │ │
│ │ states │ │ │
│ │─────────────────────────────> │
│ │ │ │ │
│ │ │ │ Query call │
│ │ │ │ graph │
│ │ │ │───────┐ │
│ │ │ │ │ │
│ │ │ │<──────┘ │
│ │ │ │ │
│ │ K4 states │ │ │
│ │<───────────────────────────── │
│ │ │ │ │
│ │ Apply rules │ │ │
│ │──────┐ │ │ │
│ │ │ │ │ │
│ │<─────┘ │ │ │
│ │ │ │ │
│ │ Compute │ │ │
│ │ confidence │ │ │
│ │──────┐ │ │ │
│ │ │ │ │ │
│ │<─────┘ │ │ │
│ │ │ │ │
│ Verdict + │ │ │ │
│ explain │ │ │ │
│<────────────│ │ │ │
│ │ │ │ │
```
## Step-by-Step
### 1. Evaluation Request
Scanner submits findings for policy evaluation:
```http
POST /internal/evaluate HTTP/1.1
Content-Type: application/json
```
### 2. Policy Loading
Policy Engine loads the policy set from storage:
```yaml
# Policy Set: production
version: "stella-dsl@1"
name: production
description: Production deployment policy
rules:
- name: no-critical-reachable
description: Block critical CVEs with reachable code
condition: |
severity == 'critical' AND
reachability IN ['SR', 'RO', 'CR'] AND
vex_status != 'not_affected'
action: FAIL
- name: no-critical-unfixed
description: Block critical CVEs without fixes
condition: |
severity == 'critical' AND
fixed_version == null
action: FAIL
- name: warn-high-reachable
description: Warn on high CVEs with reachable code
condition: |
severity == 'high' AND
reachability IN ['SR', 'RO', 'CR']
action: WARN
- name: allow-vex-not-affected
description: Allow CVEs marked not affected by trusted issuer
condition: |
vex_status == 'not_affected' AND
vex_issuer_trust >= 0.8
action: PASS
defaults:
action: PASS
confidence_threshold: 0.7
```
### 3. VEX Consensus Query
Policy Engine queries VexLens for VEX statements:
```http
POST /internal/vex/consensus HTTP/1.1
Content-Type: application/json
```
Response with issuer consensus:
```json
{
"statements": [
{
"vulnerability": "CVE-2024-1234",
"status": "affected",
"issuers": [
{"name": "vendor-psirt", "trust": 0.95, "status": "affected"},
{"name": "osv", "trust": 0.7, "status": "affected"}
],
"consensus": "affected",
"confidence": 0.92
},
{
"vulnerability": "CVE-2024-5678",
"status": "not_affected",
"justification": "vulnerable_code_not_in_execute_path",
"issuers": [
{"name": "vendor-psirt", "trust": 0.95, "status": "not_affected"}
],
"consensus": "not_affected",
"confidence": 0.95
}
]
}
```
### 4. Reachability State Query
Policy Engine queries ReachGraph for K4 states:
```http
POST /internal/reachability/states HTTP/1.1
Content-Type: application/json
```
Response with K4 lattice states:
```json
{
"states": [
{
"package": "pkg:npm/lodash@4.17.20",
"state": "StaticallyReachable",
"evidence": {
"static": {"call_paths": 3, "entry_points": ["src/api/handler.js:45"]},
"runtime": null
}
},
{
"package": "pkg:npm/express@4.18.0",
"state": "RuntimeObserved",
"evidence": {
"static": {"call_paths": 12},
"runtime": {"invocations": 1547, "last_seen": "2024-12-29T09:00:00Z"}
}
}
]
}
```
### 5. Rule Evaluation
Policy Engine evaluates each finding against rules:
```
Finding: CVE-2024-1234 in pkg:npm/lodash@4.17.20
- severity: critical
- reachability: StaticallyReachable (SR)
- vex_status: affected
- fixed_version: 4.17.21
Rule: no-critical-reachable
- condition: severity == 'critical' AND reachability IN ['SR', 'RO', 'CR'] AND vex_status != 'not_affected'
- evaluation: critical == 'critical' ✓ AND SR IN ['SR', 'RO', 'CR'] ✓ AND 'affected' != 'not_affected' ✓
- result: MATCH → FAIL
```
### 6. Confidence Scoring
Policy Engine computes confidence score based on 5 factors:
| Factor | Weight | Description |
|--------|--------|-------------|
| Reachability | 0.30 | K4 state certainty |
| Runtime | 0.25 | Runtime observation freshness |
| VEX | 0.20 | VEX issuer trust level |
| Provenance | 0.15 | SBOM completeness |
| Policy | 0.10 | Rule specificity |
```
Confidence = Σ(factor_weight × factor_score)
For CVE-2024-1234:
- Reachability: 0.30 × 0.7 (SR state) = 0.21
- Runtime: 0.25 × 0.0 (no runtime data) = 0.00
- VEX: 0.20 × 0.92 (affected consensus) = 0.18
- Provenance: 0.15 × 1.0 (complete SBOM) = 0.15
- Policy: 0.10 × 1.0 (exact rule match) = 0.10
Total Confidence: 0.64
```
### 7. Verdict Assembly
Policy Engine assembles final verdict:
```json
{
"verdict": "FAIL",
"confidence": 0.64,
"summary": {
"total_findings": 2,
"blocked": 1,
"warned": 0,
"passed": 1
},
"violations": [
{
"finding": {
"cve": "CVE-2024-1234",
"package": "pkg:npm/lodash@4.17.20",
"severity": "critical"
},
"rule": "no-critical-reachable",
"action": "FAIL",
"explain": {
"reason": "Critical CVE with reachable code path",
"factors": {
"reachability": "StaticallyReachable - 3 call paths from entry points",
"vex": "Marked as 'affected' by vendor-psirt (trust: 0.95)",
"remediation": "Upgrade lodash to 4.17.21"
}
}
}
],
"passed": [
{
"finding": {
"cve": "CVE-2024-5678",
"package": "pkg:npm/express@4.18.0",
"severity": "high"
},
"rule": "allow-vex-not-affected",
"action": "PASS",
"explain": {
"reason": "VEX statement confirms not affected",
"factors": {
"vex": "Not affected - vulnerable_code_not_in_execute_path",
"issuer": "vendor-psirt (trust: 0.95)"
}
}
}
]
}
```
## Data Contracts
### Policy Rule Schema
```typescript
interface PolicyRule {
name: string;
description?: string;
condition: string; // stella-dsl@1 expression
action: 'PASS' | 'WARN' | 'FAIL';
priority?: number;
exceptions?: Array<{
id: string;
expires?: string;
justification: string;
}>;
}
```
### Verdict Schema
```typescript
interface PolicyVerdict {
verdict: 'PASS' | 'WARN' | 'FAIL';
confidence: number; // 0.0-1.0
summary: {
total_findings: number;
blocked: number;
warned: number;
passed: number;
};
violations: Array<ViolationDetail>;
warnings: Array<ViolationDetail>;
passed: Array<PassedDetail>;
metadata: {
policy_set: string;
policy_version: string;
evaluated_at: string;
evaluation_ms: number;
};
}
```
## Error Handling
| Error | Recovery |
|-------|----------|
| Policy set not found | Use default policy or return 400 |
| VexLens timeout | Continue without VEX data, reduce confidence |
| ReachGraph timeout | Use Unknown state, reduce confidence |
| Invalid rule syntax | Skip rule, log error, continue |
| Conflicting rules | Apply highest priority rule |
## Observability
### Metrics
| Metric | Type | Labels |
|--------|------|--------|
| `policy_evaluation_total` | Counter | `policy_set`, `verdict` |
| `policy_evaluation_duration_ms` | Histogram | `policy_set` |
| `policy_rule_matches_total` | Counter | `rule`, `action` |
| `policy_confidence_score` | Histogram | `policy_set` |
### Trace Context
```
policy-evaluation
├── policy-load
├── vexlens-query
├── reachgraph-query
├── rule-evaluation
│ ├── rule-no-critical-reachable
│ ├── rule-no-critical-unfixed
│ └── rule-allow-vex-not-affected
├── confidence-scoring
└── verdict-assembly
```
## Related Flows
- [Scan Submission Flow](02-scan-submission-flow.md) - Parent flow
- [CI/CD Gate Flow](10-cicd-gate-flow.md) - Pipeline integration
- [Exception Approval Workflow](17-exception-approval-workflow.md) - Policy exceptions
- [Multi-Tenant Policy Rollout Flow](14-multi-tenant-policy-rollout-flow.md) - Policy distribution
| ReachGraph timeout | Use Unknown state, reduce confidence |
| Invalid rule syntax | Skip rule, log error, continue |
| Conflicting rules | Apply highest priority rule |
## Observability
### Metrics
| Metric | Type | Labels |
|--------|------|--------|
| `policy_evaluation_total` | Counter | `policy_set`, `verdict` |
| `policy_evaluation_duration_ms` | Histogram | `policy_set` |
| `policy_rule_matches_total` | Counter | `rule`, `action` |
| `policy_confidence_score` | Histogram | `policy_set` |
### Trace Context
```
policy-evaluation
├── policy-load
├── vexlens-query
├── reachgraph-query
├── rule-evaluation
│ ├── rule-no-critical-reachable
│ ├── rule-no-critical-unfixed
│ └── rule-allow-vex-not-affected
├── confidence-scoring
└── verdict-assembly
```
## Related Flows
- [Scan Submission Flow](02-scan-submission-flow.md) - Parent flow
- [CI/CD Gate Flow](10-cicd-gate-flow.md) - Pipeline integration
- [Exception Approval Workflow](17-exception-approval-workflow.md) - Policy exceptions
- [Multi-Tenant Policy Rollout Flow](14-multi-tenant-policy-rollout-flow.md) - Policy distribution