This commit is contained in:
StellaOps Bot
2025-12-22 09:56:20 +02:00
parent 00bc4f79dd
commit dfaa2079aa
7 changed files with 1574 additions and 12 deletions

View File

@@ -0,0 +1,250 @@
# Policy Merge Preview
## Overview
The **Policy Merge Preview** shows how VEX statements from different sources combine using lattice logic. This visualization helps analysts understand:
1. What each source contributes
2. How conflicts are resolved
3. What evidence is missing
4. The final merged status
## Merge Semantics
StellaOps uses a three-layer merge model:
```
vendor ⊕ distro ⊕ internal = final
```
Where ⊕ represents the lattice join operation.
### Layer Hierarchy
| Layer | Description | Typical Trust |
|-------|-------------|---------------|
| **Vendor** | Software vendor's VEX statements | 0.95-1.0 |
| **Distro** | Distribution maintainer's assessments | 0.85-0.95 |
| **Internal** | Organization's own assessments | 0.70-0.90 |
### Lattice Operations
Using K4 (Kleene's 4-valued logic):
| Status | Lattice Position |
|--------|-----------------|
| Affected | Top (Both) |
| UnderInvestigation | Unknown (Neither) |
| Fixed | True |
| NotAffected | False |
Join table (⊕):
```
| Affected | Under... | Fixed | NotAffected
---------+----------+----------+-------+------------
Affected | A | A | A | A
Under... | A | U | U | U
Fixed | A | U | F | F
NotAff | A | U | F | N
```
## API Endpoint
### GET /policy/merge-preview/{cveId}
**Parameters:**
- `cveId`: CVE identifier
- `artifact`: Artifact digest (query param)
**Response:**
```json
{
"cveId": "CVE-2024-1234",
"artifactDigest": "sha256:abc...",
"contributions": [
{
"layer": "vendor",
"sources": ["lodash-security"],
"status": "NotAffected",
"trustScore": 0.95,
"statements": [...],
"mergeTrace": {
"explanation": "Vendor states not affected due to version"
}
},
{
"layer": "distro",
"sources": ["redhat-csaf"],
"status": "Affected",
"trustScore": 0.90,
"statements": [...],
"mergeTrace": {
"explanation": "Distro states affected without context"
}
},
{
"layer": "internal",
"sources": [],
"status": null,
"trustScore": 0,
"statements": [],
"mergeTrace": null
}
],
"finalStatus": "NotAffected",
"finalConfidence": 0.925,
"missingEvidence": [
{
"type": "internal-assessment",
"description": "Add internal security assessment",
"priority": "medium"
}
],
"latticeType": "K4",
"generatedAt": "2024-12-22T12:00:00Z"
}
```
## Conflict Resolution
When sources disagree, resolution follows:
1. **Trust Weight**: Higher trust wins
2. **Lattice Position**: If trust equal, higher lattice position wins
3. **Freshness**: If still tied, more recent statement wins
4. **Tie**: First statement wins
### Resolution Trace
Each merge includes explanation:
```json
{
"leftSource": "vendor:lodash",
"rightSource": "distro:redhat",
"leftStatus": "NotAffected",
"rightStatus": "Affected",
"leftTrust": 0.95,
"rightTrust": 0.90,
"resultStatus": "NotAffected",
"explanation": "'vendor:lodash' has higher trust weight than 'distro:redhat'"
}
```
## UI Components
### Layer Cards
Each layer shows:
- Source names
- Current status badge
- Trust score bar
- Statement count
### Merge Flow Diagram
Visual representation:
```
┌─────────┐ ┌─────────┐ ┌──────────┐ ┌─────────┐
│ Vendor │ ──⊕─│ Distro │ ──⊕─│ Internal │ ──=─│ Final │
│ NotAff. │ │ Affected│ │ — │ │ NotAff. │
│ (0.95) │ │ (0.90) │ │ │ │ (0.925) │
└─────────┘ └─────────┘ └──────────┘ └─────────┘
```
### Missing Evidence CTA
Prominent call-to-action for missing evidence:
```
┌─────────────────────────────────────────┐
│ ⚠ Improve Confidence │
│ │
│ [+] Add internal security assessment │
│ Increases confidence by ~5% │
│ │
│ [+] Add reachability analysis │
│ Determines if code is called │
└─────────────────────────────────────────┘
```
### Merge Traces (Expandable)
Detailed explanation of each merge:
```
▼ Merge Details
Vendor layer:
Sources: lodash-security
Status: NotAffected (trust: 95%)
Distro layer:
Sources: redhat-csaf
Status: Affected (trust: 90%)
Merge: 'lodash-security' has higher trust weight
Internal layer:
No statements
Final: NotAffected (confidence: 92.5%)
```
## Configuration
### Trust Weights
Configure in `trust.yaml`:
```yaml
sources:
vendor: 1.0
distro: 0.9
nvd: 0.8
internal: 0.85
community: 0.5
unknown: 0.3
```
### Lattice Type
Configure lattice in `policy.yaml`:
```yaml
lattice:
type: K4 # or Boolean, 8-state
joinStrategy: trust-weighted
```
## Use Cases
### 1. Understanding Disagreement
When vendor says "not affected" but NVD says "affected":
- View merge preview
- See trust scores
- Understand why vendor wins
- Decide if internal assessment needed
### 2. Adding Internal Context
When external sources lack context:
- View missing evidence
- Click "Add evidence"
- Submit internal VEX statement
- See confidence increase
### 3. Audit Documentation
For compliance:
- Export merge preview
- Include in audit report
- Document decision rationale
## Best Practices
1. **Review Conflicts**: When layers disagree, investigate why
2. **Add Internal Context**: Your reachability data often resolves conflicts
3. **Trust Calibration**: Adjust trust weights based on source accuracy
4. **Document Decisions**: Use merge preview in exception justifications
## Related Documentation
- [VEX Trust Scoring](../excititor/scoring.md)
- [Lattice Configuration](../policy/implementation_plan.md)
- [REPLAY.yaml Specification](./replay-yaml.md)

View File

@@ -0,0 +1,295 @@
# REPLAY.yaml Manifest Specification
## Overview
The **REPLAY.yaml** manifest defines the complete set of inputs required to reproduce a StellaOps evaluation. It is the root document in a `.stella-replay.tgz` bundle.
## File Location
```
.stella-replay.tgz
├── REPLAY.yaml # This manifest
├── sboms/
├── vex/
├── reach/
├── exceptions/
├── policies/
├── feeds/
├── config/
└── SIGNATURE.sig # Optional DSSE signature
```
## Schema Version
Current schema version: `1.0.0`
```yaml
version: "1.0.0"
```
## Complete Example
```yaml
version: "1.0.0"
snapshot:
id: "snap-20241222-abc123"
createdAt: "2024-12-22T12:00:00Z"
artifact: "sha256:abc123..."
previousId: "snap-20241221-xyz789"
inputs:
sboms:
- path: "sboms/cyclonedx.json"
format: "cyclonedx-1.6"
digest: "sha256:def456..."
- path: "sboms/spdx.json"
format: "spdx-3.0.1"
digest: "sha256:ghi789..."
vex:
- path: "vex/vendor-lodash.json"
source: "vendor:lodash"
format: "openvex"
digest: "sha256:jkl012..."
trustScore: 0.95
- path: "vex/redhat-csaf.json"
source: "distro:redhat"
format: "csaf"
digest: "sha256:mno345..."
trustScore: 0.90
reachability:
- path: "reach/api-handler.json"
entryPoint: "/api/handler"
digest: "sha256:pqr678..."
nodeCount: 42
edgeCount: 57
exceptions:
- path: "exceptions/exc-001.json"
exceptionId: "exc-001"
digest: "sha256:stu901..."
policies:
bundlePath: "policies/bundle.tar.gz"
digest: "sha256:vwx234..."
version: "2.1.0"
rulesHash: "sha256:yza567..."
feeds:
- feedId: "nvd"
name: "National Vulnerability Database"
version: "2024-12-22T00:00:00Z"
digest: "sha256:bcd890..."
fetchedAt: "2024-12-22T06:00:00Z"
- feedId: "ghsa"
name: "GitHub Security Advisories"
version: "2024-12-22T01:00:00Z"
digest: "sha256:efg123..."
fetchedAt: "2024-12-22T06:15:00Z"
lattice:
type: "K4"
configDigest: "sha256:hij456..."
trust:
configDigest: "sha256:klm789..."
defaultWeight: 0.5
outputs:
verdictPath: "verdict.json"
verdictDigest: "sha256:nop012..."
findingsPath: "findings.ndjson"
findingsDigest: "sha256:qrs345..."
seeds:
rng: 12345678
sampling: 87654321
environment:
STELLAOPS_POLICY_VERSION: "2.1.0"
STELLAOPS_LATTICE_TYPE: "K4"
signature:
algorithm: "ecdsa-p256"
keyId: "signing-key-prod-2024"
value: "MEUCIQDx..."
```
## Field Reference
### snapshot
Metadata about the snapshot itself.
| Field | Type | Required | Description |
|-------|------|----------|-------------|
| id | string | Yes | Unique snapshot identifier |
| createdAt | datetime | Yes | ISO 8601 timestamp |
| artifact | string | Yes | Artifact digest being evaluated |
| previousId | string | No | Previous snapshot for diff |
### inputs.sboms
SBOM documents included in bundle.
| Field | Type | Required | Description |
|-------|------|----------|-------------|
| path | string | Yes | Path within bundle |
| format | string | Yes | `cyclonedx-1.6` or `spdx-3.0.1` |
| digest | string | Yes | Content digest |
### inputs.vex
VEX documents from various sources.
| Field | Type | Required | Description |
|-------|------|----------|-------------|
| path | string | Yes | Path within bundle |
| source | string | Yes | Source identifier (vendor:*, distro:*, etc.) |
| format | string | Yes | `openvex`, `csaf`, `cyclonedx-vex` |
| digest | string | Yes | Content digest |
| trustScore | number | Yes | Trust weight (0.0-1.0) |
### inputs.reachability
Reachability subgraph data.
| Field | Type | Required | Description |
|-------|------|----------|-------------|
| path | string | Yes | Path within bundle |
| entryPoint | string | Yes | Entry point identifier |
| digest | string | Yes | Content digest |
| nodeCount | integer | No | Number of nodes |
| edgeCount | integer | No | Number of edges |
### inputs.exceptions
Active exceptions at snapshot time.
| Field | Type | Required | Description |
|-------|------|----------|-------------|
| path | string | Yes | Path within bundle |
| exceptionId | string | Yes | Exception identifier |
| digest | string | Yes | Content digest |
### inputs.policies
Policy bundle reference.
| Field | Type | Required | Description |
|-------|------|----------|-------------|
| bundlePath | string | Yes | Path to policy bundle |
| digest | string | Yes | Bundle digest |
| version | string | No | Policy version |
| rulesHash | string | Yes | Hash of compiled rules |
### inputs.feeds
Advisory feed versions at snapshot time.
| Field | Type | Required | Description |
|-------|------|----------|-------------|
| feedId | string | Yes | Feed identifier |
| name | string | No | Human-readable name |
| version | string | Yes | Feed version/timestamp |
| digest | string | Yes | Feed content digest |
| fetchedAt | datetime | Yes | When feed was fetched |
### inputs.lattice
Lattice configuration for merge semantics.
| Field | Type | Required | Description |
|-------|------|----------|-------------|
| type | string | Yes | `K4`, `Boolean`, `8-state` |
| configDigest | string | Yes | Configuration hash |
### inputs.trust
Trust weight configuration.
| Field | Type | Required | Description |
|-------|------|----------|-------------|
| configDigest | string | Yes | Configuration hash |
| defaultWeight | number | No | Default trust weight |
### outputs
Evaluation outputs for verification.
| Field | Type | Required | Description |
|-------|------|----------|-------------|
| verdictPath | string | Yes | Path to verdict file |
| verdictDigest | string | Yes | Verdict content digest |
| findingsPath | string | No | Path to findings file |
| findingsDigest | string | No | Findings content digest |
### seeds
Random seeds for deterministic evaluation.
| Field | Type | Required | Description |
|-------|------|----------|-------------|
| rng | integer | No | Random number generator seed |
| sampling | integer | No | Sampling algorithm seed |
### environment
Environment variables captured (non-sensitive).
Key-value pairs of environment configuration.
### signature
DSSE signature over manifest.
| Field | Type | Required | Description |
|-------|------|----------|-------------|
| algorithm | string | Yes | Signing algorithm |
| keyId | string | Yes | Signing key identifier |
| value | string | Yes | Base64-encoded signature |
## Digest Format
All digests use the format:
```
sha256:<64-char-hex>
```
Example:
```
sha256:a1b2c3d4e5f6...
```
## Validation
Bundle validation checks:
1. REPLAY.yaml exists at bundle root
2. All referenced files exist
3. All digests match content
4. Schema validates against JSON Schema
5. Signature verifies (if present)
## CLI Usage
```bash
# Create bundle
stella snapshot export --output snapshot.stella-replay.tgz
# Verify bundle
stella snapshot verify snapshot.stella-replay.tgz
# Replay from bundle
stella replay --bundle snapshot.stella-replay.tgz
# View manifest
stella snapshot manifest snapshot.stella-replay.tgz
```
## Related Documentation
- [Knowledge Snapshot Model](./knowledge-snapshot.md)
- [Merge Preview](./merge-preview.md)
- [Replay Engine](../../modules/policy/implementation_plan.md)