Sprints completed: - SPRINT_20260110_012_* (golden set diff layer - 10 sprints) - SPRINT_20260110_013_* (advisory chat - 4 sprints) Build fixes applied: - Fix namespace conflicts with Microsoft.Extensions.Options.Options.Create - Fix VexDecisionReachabilityIntegrationTests API drift (major rewrite) - Fix VexSchemaValidationTests FluentAssertions method name - Fix FixChainGateIntegrationTests ambiguous type references - Fix AdvisoryAI test files required properties and namespace aliases - Add stub types for CveMappingController (ICveSymbolMappingService) - Fix VerdictBuilderService static context issue Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
319 lines
9.8 KiB
Markdown
319 lines
9.8 KiB
Markdown
# Policy Engine FixChain Gates
|
|
|
|
> **Sprint:** SPRINT_20260110_012_008_POLICY
|
|
> **Last Updated:** 10-Jan-2026
|
|
|
|
## Overview
|
|
|
|
FixChain gates are policy predicates that control release promotion based on verified fix status. They integrate FixChain attestations from the binary-level fix verification system into policy decisions, blocking or warning on releases that contain critical vulnerabilities without verified fixes.
|
|
|
|
## Why This Matters
|
|
|
|
| Current State | With FixChain Gates |
|
|
|---------------|---------------------|
|
|
| Manual fix verification | Automated policy gates |
|
|
| Trust vendor fix claims | Require verification evidence |
|
|
| Inconsistent release criteria | Codified fix requirements |
|
|
| Post-deployment discovery | Pre-deployment blocking |
|
|
|
|
## Configuration
|
|
|
|
### YAML Policy Configuration
|
|
|
|
```yaml
|
|
# stellaops.yaml
|
|
Policy:
|
|
Predicates:
|
|
FixChainGate:
|
|
Enabled: true
|
|
DefaultMinConfidence: 0.85
|
|
DefaultGracePeriodDays: 7
|
|
NotifyOnBlock: true
|
|
NotifyOnWarn: true
|
|
|
|
policies:
|
|
release-gates:
|
|
name: "Release Gate Policy"
|
|
version: "1.0.0"
|
|
description: "Gates for production release promotion"
|
|
|
|
gates:
|
|
# Critical vulnerabilities - strict requirements
|
|
- name: "critical-fix-required"
|
|
predicate: fixChainRequired
|
|
parameters:
|
|
severities: ["critical"]
|
|
minConfidence: 0.95
|
|
allowInconclusive: false
|
|
gracePeriodDays: 3
|
|
requireApprovedGoldenSet: true
|
|
action: block
|
|
message: "Critical vulnerabilities require verified fix with 95%+ confidence"
|
|
|
|
# High vulnerabilities - moderate requirements
|
|
- name: "high-fix-recommended"
|
|
predicate: fixChainRequired
|
|
parameters:
|
|
severities: ["high"]
|
|
minConfidence: 0.80
|
|
allowInconclusive: true
|
|
gracePeriodDays: 14
|
|
requireApprovedGoldenSet: true
|
|
action: warn
|
|
message: "High vulnerabilities should have verified fix"
|
|
|
|
# Exception for specific components
|
|
- name: "vendor-component-exception"
|
|
predicate: componentException
|
|
parameters:
|
|
components:
|
|
- "pkg:deb/debian/vendor-lib@*"
|
|
reason: "Vendor provides attestation separately"
|
|
action: allow
|
|
|
|
fallback: block
|
|
auditLog: true
|
|
```
|
|
|
|
### Parameter Reference
|
|
|
|
| Parameter | Type | Default | Description |
|
|
|-----------|------|---------|-------------|
|
|
| `severities` | string[] | `["critical", "high"]` | Severity levels requiring verification |
|
|
| `minConfidence` | decimal | `0.85` | Minimum confidence for "fixed" verdict |
|
|
| `allowInconclusive` | bool | `false` | Whether inconclusive verdicts pass |
|
|
| `gracePeriodDays` | int | `7` | Days after CVE publication before gate applies |
|
|
| `requireApprovedGoldenSet` | bool | `true` | Require golden set to be approved |
|
|
| `failureAction` | string | `block` | Action on failure: `block` or `warn` |
|
|
|
|
## Gate Outcomes
|
|
|
|
| Outcome | Passed | Description |
|
|
|---------|--------|-------------|
|
|
| `FixVerified` | Yes | Fix verified with sufficient confidence |
|
|
| `SeverityExempt` | Yes | Severity does not require verification |
|
|
| `GracePeriod` | Yes | Within grace period after CVE publication |
|
|
| `AttestationRequired` | No | No attestation found, severity requires it |
|
|
| `InsufficientConfidence` | No | Confidence below threshold |
|
|
| `InconclusiveNotAllowed` | No | Inconclusive verdict, policy doesn't allow |
|
|
| `StillVulnerable` | No | Verification shows vulnerability present |
|
|
| `GoldenSetNotApproved` | No | Golden set not reviewed/approved |
|
|
| `PartialFix` | Depends | Partial fix detected |
|
|
|
|
## K4 Lattice Integration
|
|
|
|
```
|
|
+-----------------+
|
|
| ReleaseBlocked |
|
|
+--------+--------+
|
|
|
|
|
+--------------------+--------------------+
|
|
| |
|
|
v v
|
|
+---------------+ +---------------+
|
|
| FixRequired | | ManualReview |
|
|
| (Critical+ | | Required |
|
|
| Unverified) | | |
|
|
+-------+-------+ +-------+-------+
|
|
| |
|
|
+--------------------+--------------------+
|
|
|
|
|
v
|
|
+-----------------+
|
|
| ReleaseAllowed |
|
|
+-----------------+
|
|
|
|
Lattice Rules:
|
|
Critical AND NoFixChain -> ReleaseBlocked
|
|
Critical AND FixChain(>=0.95) -> ReleaseAllowed
|
|
Critical AND Inconclusive -> ManualReviewRequired
|
|
High AND NoFixChain -> ManualReviewRequired
|
|
High AND FixChain(>=0.80) -> ReleaseAllowed
|
|
```
|
|
|
|
## Usage
|
|
|
|
### Programmatic Evaluation
|
|
|
|
```csharp
|
|
// Inject the predicate
|
|
var predicate = services.GetRequiredService<IFixChainGatePredicate>();
|
|
|
|
// Create context for a finding
|
|
var context = new FixChainGateContext
|
|
{
|
|
CveId = "CVE-2024-12345",
|
|
ComponentPurl = "pkg:npm/lodash@4.17.20",
|
|
Severity = "critical",
|
|
CvssScore = 9.8m,
|
|
BinarySha256 = binaryDigest,
|
|
CvePublishedAt = DateTimeOffset.Parse("2024-01-15")
|
|
};
|
|
|
|
// Configure parameters
|
|
var parameters = new FixChainGateParameters
|
|
{
|
|
Severities = ImmutableArray.Create("critical", "high"),
|
|
MinConfidence = 0.90m,
|
|
AllowInconclusive = false,
|
|
GracePeriodDays = 7,
|
|
RequireApprovedGoldenSet = true
|
|
};
|
|
|
|
// Evaluate
|
|
var result = await predicate.EvaluateAsync(context, parameters, ct);
|
|
|
|
if (!result.Passed)
|
|
{
|
|
Console.WriteLine($"Gate blocked: {result.Reason}");
|
|
foreach (var rec in result.Recommendations)
|
|
{
|
|
Console.WriteLine($" - {rec}");
|
|
}
|
|
foreach (var cmd in result.CliCommands)
|
|
{
|
|
Console.WriteLine($" $ {cmd}");
|
|
}
|
|
}
|
|
```
|
|
|
|
### Batch Evaluation
|
|
|
|
```csharp
|
|
var batchService = services.GetRequiredService<IFixChainGateBatchService>();
|
|
|
|
var contexts = findings.Select(f => new FixChainGateContext
|
|
{
|
|
CveId = f.CveId,
|
|
ComponentPurl = f.ComponentPurl,
|
|
Severity = f.Severity,
|
|
CvssScore = f.CvssScore
|
|
}).ToList();
|
|
|
|
var batchResult = await batchService.EvaluateBatchAsync(contexts, parameters, ct);
|
|
|
|
if (!batchResult.AllPassed)
|
|
{
|
|
Console.WriteLine($"Blocking issues: {batchResult.BlockingResults.Length}");
|
|
Console.WriteLine($"Warnings: {batchResult.WarningResults.Length}");
|
|
}
|
|
```
|
|
|
|
### Policy Gate Registry Integration
|
|
|
|
```csharp
|
|
// In Startup/Program.cs
|
|
services.AddFixChainGate(configuration);
|
|
|
|
// Register with policy gate registry
|
|
var registry = services.BuildServiceProvider()
|
|
.GetRequiredService<IPolicyGateRegistry>();
|
|
registry.RegisterFixChainGate();
|
|
```
|
|
|
|
## CLI Usage
|
|
|
|
### Check Gates for an Artifact
|
|
|
|
```bash
|
|
stella policy check-gates \
|
|
--artifact sha256:abc123... \
|
|
--policy release-gates \
|
|
--format table
|
|
```
|
|
|
|
Output:
|
|
```
|
|
Release Gate Evaluation: sha256:abc123...
|
|
Policy: release-gates
|
|
|
|
+----------------------------+---------+----------------------------------------+
|
|
| Gate | Status | Reason |
|
|
+----------------------------+---------+----------------------------------------+
|
|
| critical-fix-required | PASS | No critical vulnerabilities |
|
|
| high-fix-recommended | WARN | 2 findings without verified fix |
|
|
| vendor-component-exception | PASS | Exception applied |
|
|
+----------------------------+---------+----------------------------------------+
|
|
|
|
Warnings (2):
|
|
- CVE-2024-1234 on pkg:npm/lodash@4.17.20: No FixChain attestation
|
|
- CVE-2024-5678 on pkg:npm/axios@0.21.0: Inconclusive verdict
|
|
|
|
Recommendations:
|
|
- stella scanner golden init --cve CVE-2024-1234 --component lodash
|
|
- stella scanner golden init --cve CVE-2024-5678 --component axios
|
|
|
|
Overall: ALLOWED (with warnings)
|
|
```
|
|
|
|
### JSON Output
|
|
|
|
```bash
|
|
stella policy check-gates \
|
|
--artifact sha256:abc123... \
|
|
--policy release-gates \
|
|
--format json
|
|
```
|
|
|
|
## Metrics
|
|
|
|
The gate exposes OpenTelemetry metrics:
|
|
|
|
| Metric | Type | Description |
|
|
|--------|------|-------------|
|
|
| `policy_fixchain_gate_evaluations_total` | Counter | Total evaluations |
|
|
| `policy_fixchain_gate_passes_total` | Counter | Gate passes |
|
|
| `policy_fixchain_gate_blocks_total` | Counter | Gate blocks |
|
|
| `policy_fixchain_gate_warnings_total` | Counter | Gate warnings |
|
|
| `policy_fixchain_gate_evaluation_duration_seconds` | Histogram | Evaluation duration |
|
|
| `policy_fixchain_gate_errors_total` | Counter | Evaluation errors |
|
|
|
|
## Troubleshooting
|
|
|
|
### Gate Blocking Unexpectedly
|
|
|
|
1. **Check severity configuration**: Ensure the severity matches configured severities
|
|
```bash
|
|
stella policy show --policy release-gates
|
|
```
|
|
|
|
2. **Verify attestation exists**: Check if attestation is present
|
|
```bash
|
|
stella attestor query --cve CVE-2024-XXXX --predicate fixchain
|
|
```
|
|
|
|
3. **Check confidence level**: Verify confidence meets threshold
|
|
```bash
|
|
stella scanner golden show --cve CVE-2024-XXXX --verbose
|
|
```
|
|
|
|
4. **Review golden set status**: Check if golden set is approved
|
|
```bash
|
|
stella scanner golden status --cve CVE-2024-XXXX
|
|
```
|
|
|
|
### Grace Period Issues
|
|
|
|
- Grace period starts from CVE publication date in the advisory
|
|
- If publication date is unknown, grace period doesn't apply
|
|
- Use `--grace-period-override` for manual override
|
|
|
|
### Inconclusive Verdicts
|
|
|
|
Inconclusive verdicts typically occur when:
|
|
- Binary is stripped and symbols unavailable
|
|
- Golden set incomplete or too generic
|
|
- Compiler optimizations changed code structure
|
|
|
|
Resolution:
|
|
1. Obtain debug symbols
|
|
2. Enhance golden set with more specific targets
|
|
3. Consider policy exception with justification
|
|
|
|
## Related Documentation
|
|
|
|
- [FixChain Attestation Predicate](../../attestor/fix-chain-predicate.md)
|
|
- [Golden Set Schema](../../binary-index/golden-set-schema.md)
|
|
- [Risk Engine FixChain Integration](../../risk-engine/fix-chain-integration.md)
|
|
- [Policy Engine Architecture](./architecture.md)
|