Merge branch 'main' of https://git.stella-ops.org/stella-ops.org/git.stella-ops.org
This commit is contained in:
@@ -436,6 +436,143 @@ Binary matches are recorded as proof segments:
|
||||
|
||||
---
|
||||
|
||||
## 5b. Fix Evidence Chain
|
||||
|
||||
The **Fix Evidence Chain** provides auditable proof of why a CVE is marked as fixed (or not) for a specific distro/package combination. This is critical for patch-aware backport handling where package versions can be misleading.
|
||||
|
||||
### 5b.1 Evidence Sources
|
||||
|
||||
| Source | Confidence | Description |
|
||||
|--------|------------|-------------|
|
||||
| **Security Feed (OVAL)** | 0.95-0.99 | Authoritative feed from distro (Debian Security Tracker, Red Hat OVAL) |
|
||||
| **Patch Header (DEP-3)** | 0.87-0.95 | CVE reference in Debian/Ubuntu patch metadata |
|
||||
| **Changelog** | 0.75-0.85 | CVE mention in debian/changelog or RPM %changelog |
|
||||
| **Upstream Patch Match** | 0.90 | Binary diff matches known upstream fix |
|
||||
|
||||
### 5b.2 Evidence Storage
|
||||
|
||||
Evidence is stored in two PostgreSQL tables:
|
||||
|
||||
```sql
|
||||
-- Fix index: one row per (distro, release, source_pkg, cve_id)
|
||||
CREATE TABLE binaries.cve_fix_index (
|
||||
id UUID PRIMARY KEY,
|
||||
tenant_id TEXT NOT NULL,
|
||||
distro TEXT NOT NULL, -- debian, ubuntu, alpine, rhel
|
||||
release TEXT NOT NULL, -- bookworm, jammy, v3.19
|
||||
source_pkg TEXT NOT NULL,
|
||||
cve_id TEXT NOT NULL,
|
||||
state TEXT NOT NULL, -- fixed, vulnerable, not_affected, wontfix, unknown
|
||||
fixed_version TEXT,
|
||||
method TEXT NOT NULL, -- security_feed, changelog, patch_header, upstream_match
|
||||
confidence DECIMAL(3,2) NOT NULL,
|
||||
evidence_id UUID REFERENCES binaries.fix_evidence(id),
|
||||
snapshot_id UUID,
|
||||
indexed_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
||||
UNIQUE (tenant_id, distro, release, source_pkg, cve_id)
|
||||
);
|
||||
|
||||
-- Evidence blobs: audit trail
|
||||
CREATE TABLE binaries.fix_evidence (
|
||||
id UUID PRIMARY KEY,
|
||||
tenant_id TEXT NOT NULL,
|
||||
evidence_type TEXT NOT NULL, -- changelog, patch_header, security_feed
|
||||
source_file TEXT, -- Path to source file (changelog, patch)
|
||||
source_sha256 TEXT, -- Hash of source file
|
||||
excerpt TEXT, -- Relevant snippet (max 1KB)
|
||||
metadata JSONB NOT NULL, -- Structured metadata
|
||||
snapshot_id UUID,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT now()
|
||||
);
|
||||
```
|
||||
|
||||
### 5b.3 Evidence Types
|
||||
|
||||
**ChangelogEvidence:**
|
||||
```json
|
||||
{
|
||||
"evidence_type": "changelog",
|
||||
"source_file": "debian/changelog",
|
||||
"excerpt": "* Fix CVE-2024-0727: PKCS12 decoding crash",
|
||||
"metadata": {
|
||||
"version": "3.0.11-1~deb12u2",
|
||||
"line_number": 5
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**PatchHeaderEvidence:**
|
||||
```json
|
||||
{
|
||||
"evidence_type": "patch_header",
|
||||
"source_file": "debian/patches/CVE-2024-0727.patch",
|
||||
"excerpt": "CVE: CVE-2024-0727\nOrigin: upstream, https://github.com/openssl/commit/abc123",
|
||||
"metadata": {
|
||||
"patch_sha256": "abc123def456..."
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**SecurityFeedEvidence:**
|
||||
```json
|
||||
{
|
||||
"evidence_type": "security_feed",
|
||||
"metadata": {
|
||||
"feed_id": "debian-security-tracker",
|
||||
"entry_id": "DSA-5678-1",
|
||||
"published_at": "2024-01-15T10:00:00Z"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 5b.4 Confidence Resolution
|
||||
|
||||
When multiple evidence sources exist for the same CVE, the system keeps the **highest confidence** entry:
|
||||
|
||||
```csharp
|
||||
ON CONFLICT (tenant_id, distro, release, source_pkg, cve_id)
|
||||
DO UPDATE SET
|
||||
confidence = GREATEST(existing.confidence, new.confidence),
|
||||
method = CASE
|
||||
WHEN existing.confidence < new.confidence THEN new.method
|
||||
ELSE existing.method
|
||||
END,
|
||||
evidence_id = CASE
|
||||
WHEN existing.confidence < new.confidence THEN new.evidence_id
|
||||
ELSE existing.evidence_id
|
||||
END
|
||||
```
|
||||
|
||||
### 5b.5 Parsers
|
||||
|
||||
The following parsers extract CVE fix information:
|
||||
|
||||
| Parser | Distros | Input | Confidence |
|
||||
|--------|---------|-------|------------|
|
||||
| `DebianChangelogParser` | Debian, Ubuntu | debian/changelog | 0.80 |
|
||||
| `PatchHeaderParser` | Debian, Ubuntu | debian/patches/*.patch (DEP-3) | 0.87 |
|
||||
| `AlpineSecfixesParser` | Alpine | APKBUILD secfixes block | 0.95 |
|
||||
| `RpmChangelogParser` | RHEL, Fedora, CentOS | RPM spec %changelog | 0.75 |
|
||||
|
||||
### 5b.6 Query Flow
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant SW as Scanner.Worker
|
||||
participant BVS as BinaryVulnerabilityService
|
||||
participant FIR as FixIndexRepository
|
||||
participant PG as PostgreSQL
|
||||
|
||||
SW->>BVS: GetFixStatusAsync(debian, bookworm, openssl, CVE-2024-0727)
|
||||
BVS->>FIR: GetFixStatusAsync(...)
|
||||
FIR->>PG: SELECT FROM cve_fix_index WHERE ...
|
||||
PG-->>FIR: FixIndexEntry (state=fixed, confidence=0.87)
|
||||
FIR-->>BVS: FixStatusResult
|
||||
BVS-->>SW: {state: Fixed, confidence: 0.87, method: PatchHeader}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 6. Security Considerations
|
||||
|
||||
### 6.1 Trust Boundaries
|
||||
|
||||
@@ -206,7 +206,111 @@ All payloads are immutable and include analyzer fingerprints (`scanner.native@sh
|
||||
|
||||
---
|
||||
|
||||
### 6.2 · Trust Lattice Policy Gates
|
||||
### 6.2 · CI/CD Release Gate API
|
||||
|
||||
The Policy Engine exposes a gate evaluation API for CI/CD pipelines to validate images before deployment.
|
||||
|
||||
#### Gate Endpoint
|
||||
|
||||
```
|
||||
POST /api/v1/policy/gate/evaluate
|
||||
```
|
||||
|
||||
**Request:**
|
||||
```json
|
||||
{
|
||||
"imageDigest": "sha256:abc123def456",
|
||||
"baselineRef": "sha256:baseline789",
|
||||
"policyId": "production-gate",
|
||||
"tenantId": "tenant-1"
|
||||
}
|
||||
```
|
||||
|
||||
**Response:**
|
||||
```json
|
||||
{
|
||||
"verdict": "pass",
|
||||
"status": "Pass",
|
||||
"reason": "No new critical vulnerabilities",
|
||||
"deltaCount": 0,
|
||||
"criticalCount": 0,
|
||||
"highCount": 2,
|
||||
"mediumCount": 5,
|
||||
"lowCount": 12,
|
||||
"evaluatedAt": "2025-12-26T12:00:00Z",
|
||||
"policyVersion": "v1.2.0"
|
||||
}
|
||||
```
|
||||
|
||||
#### Gate Status Values
|
||||
|
||||
| Status | Exit Code | Description |
|
||||
|--------|-----------|-------------|
|
||||
| `Pass` | 0 | No blocking issues; safe to deploy |
|
||||
| `Warn` | 1 | Non-blocking issues detected; configurable pass-through |
|
||||
| `Fail` | 2 | Blocking issues; deployment should be halted |
|
||||
|
||||
#### Webhook Integration
|
||||
|
||||
The Policy Gateway accepts webhooks from container registries for automated gate evaluation:
|
||||
|
||||
**Docker Registry v2:**
|
||||
```
|
||||
POST /api/v1/webhooks/registry/docker
|
||||
```
|
||||
|
||||
**Harbor:**
|
||||
```
|
||||
POST /api/v1/webhooks/registry/harbor
|
||||
```
|
||||
|
||||
**Generic (Zastava events):**
|
||||
```
|
||||
POST /api/v1/webhooks/registry/generic
|
||||
```
|
||||
|
||||
Webhook handlers enqueue async gate evaluation jobs in the Scheduler via `GateEvaluationJob`.
|
||||
|
||||
#### Gate Bypass Auditing
|
||||
|
||||
Bypass attempts are logged to `policy.gate_bypass_audit`:
|
||||
|
||||
```json
|
||||
{
|
||||
"bypassId": "bypass-uuid",
|
||||
"imageDigest": "sha256:abc123",
|
||||
"actor": "deploy-service@example.com",
|
||||
"justification": "Emergency hotfix - JIRA-12345",
|
||||
"ipAddress": "10.0.0.100",
|
||||
"ciContext": {
|
||||
"provider": "github-actions",
|
||||
"runId": "12345678",
|
||||
"workflow": "deploy.yml"
|
||||
},
|
||||
"createdAt": "2025-12-26T12:00:00Z"
|
||||
}
|
||||
```
|
||||
|
||||
#### CLI Integration
|
||||
|
||||
```bash
|
||||
# Evaluate gate
|
||||
stella gate evaluate --image sha256:abc123 --baseline sha256:baseline
|
||||
|
||||
# Check gate status
|
||||
stella gate status --job-id <job-id>
|
||||
|
||||
# Override with justification
|
||||
stella gate evaluate --image sha256:abc123 \
|
||||
--allow-override \
|
||||
--justification "Emergency hotfix approved by CISO - JIRA-12345"
|
||||
```
|
||||
|
||||
**See also:** [CI/CD Gate Workflows](.github/workflows/stellaops-gate-example.yml), [Keyless Signing Guide](../signer/guides/keyless-signing.md)
|
||||
|
||||
---
|
||||
|
||||
### 6.3 · Trust Lattice Policy Gates
|
||||
|
||||
The Policy Engine evaluates Trust Lattice gates after claim score merging to enforce trust-based constraints on VEX verdicts.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user