new two advisories and sprints work on them
This commit is contained in:
@@ -866,6 +866,119 @@ curl https://rekor.sigstore.dev/api/v1/log/publicKey > fixtures/rekor-pubkey.pem
|
||||
|
||||
---
|
||||
|
||||
## 9A. PERIODIC VERIFICATION (Background Job)
|
||||
|
||||
**Sprint Reference**: `SPRINT_20260117_001_ATTESTOR_periodic_rekor_verification`
|
||||
|
||||
### 9A.1 Overview
|
||||
|
||||
The Periodic Verification system provides continuous validation of previously logged Rekor entries. This addresses the gap where entries are logged but never re-verified, enabling detection of:
|
||||
|
||||
- Signature tampering or key compromise
|
||||
- Merkle tree rollbacks (split-view attacks)
|
||||
- Time skew violations indicating replay attempts
|
||||
- Root consistency drift between stored and remote state
|
||||
|
||||
### 9A.2 Architecture
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────────┐
|
||||
│ Periodic Verification Job │
|
||||
├─────────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ ┌─────────────────────┐ ┌─────────────────────┐ │
|
||||
│ │ RekorVerification │───►│ IRekorVerification │ │
|
||||
│ │ Job (Scheduler) │ │ Service │ │
|
||||
│ └─────────┬───────────┘ └──────────┬──────────┘ │
|
||||
│ │ │ │
|
||||
│ │ batch query │ verify │
|
||||
│ ▼ ▼ │
|
||||
│ ┌─────────────────────┐ ┌─────────────────────┐ │
|
||||
│ │ IRekorEntry │ │ RekorVerification │ │
|
||||
│ │ Repository │ │ Metrics │ │
|
||||
│ └─────────────────────┘ └──────────┬──────────┘ │
|
||||
│ │ │
|
||||
│ ▼ │
|
||||
│ ┌─────────────────────┐ │
|
||||
│ │ IRekorVerification │ │
|
||||
│ │ StatusProvider │ │
|
||||
│ └─────────────────────┘ │
|
||||
└─────────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
### 9A.3 Configuration
|
||||
|
||||
```yaml
|
||||
attestor:
|
||||
rekor:
|
||||
verification:
|
||||
enabled: true
|
||||
intervalMinutes: 60 # Run every hour
|
||||
batchSize: 100 # Entries per batch
|
||||
sampleRate: 0.1 # 10% sampling for large deployments
|
||||
maxTimeSkewSeconds: 300 # 5 minute tolerance
|
||||
alertOnRootInconsistency: true
|
||||
```
|
||||
|
||||
### 9A.4 Verification Checks
|
||||
|
||||
| Check | Description | Failure Severity |
|
||||
|-------|-------------|------------------|
|
||||
| Signature | Verify entry signature against stored public key | Critical |
|
||||
| Inclusion Proof | RFC 6962 Merkle inclusion proof verification | Critical |
|
||||
| Time Skew | Validate integrated_time within tolerance | Warning |
|
||||
| Root Consistency | Compare stored tree root with remote | Critical |
|
||||
|
||||
### 9A.5 Metrics (OpenTelemetry)
|
||||
|
||||
```
|
||||
# Meter: StellaOps.Attestor.RekorVerification
|
||||
|
||||
attestor.rekor.verification.runs # Counter
|
||||
attestor.rekor.verification.entries.verified # Counter
|
||||
attestor.rekor.verification.entries.failed # Counter
|
||||
attestor.rekor.verification.entries.skipped # Counter
|
||||
attestor.rekor.verification.time_skew_violations # Counter
|
||||
attestor.rekor.verification.signature_failures # Counter
|
||||
attestor.rekor.verification.inclusion_proof_failures # Counter
|
||||
attestor.rekor.verification.root_consistency_checks # Counter
|
||||
attestor.rekor.verification.entry_duration # Histogram
|
||||
attestor.rekor.verification.batch_duration # Histogram
|
||||
```
|
||||
|
||||
### 9A.6 Health Check Integration
|
||||
|
||||
The `RekorVerificationHealthCheck` integrates with the Doctor diagnostic system:
|
||||
|
||||
```
|
||||
Check ID: check.attestation.rekor.verification.job
|
||||
|
||||
Status Levels:
|
||||
- Healthy: Last run within expected window, failure rate < 1%
|
||||
- Degraded: Failure rate 1-5%, or last run overdue
|
||||
- Unhealthy: Failure rate > 5%, root inconsistency detected, or job not running
|
||||
```
|
||||
|
||||
### 9A.7 Alerting
|
||||
|
||||
| Condition | Alert Level | Action |
|
||||
|-----------|-------------|--------|
|
||||
| Root inconsistency | P1 Critical | Immediate investigation required |
|
||||
| Signature failure rate > 5% | P2 High | Review key material |
|
||||
| Job not running > 3x interval | P3 Medium | Check scheduler |
|
||||
| Time skew violations > 10% | P3 Medium | Check NTP sync |
|
||||
|
||||
### 9A.8 Offline Verification
|
||||
|
||||
When network access to Rekor is unavailable, the system falls back to stored inclusion proofs:
|
||||
|
||||
1. Read stored `inclusion_proof` from database
|
||||
2. Verify Merkle path locally against stored root
|
||||
3. Log verification as "offline" mode
|
||||
4. Schedule online re-verification when connectivity returns
|
||||
|
||||
---
|
||||
|
||||
## 10. MIGRATION GUIDE
|
||||
|
||||
### 10.1 Database Migrations
|
||||
|
||||
@@ -589,7 +589,120 @@ Pre-computed test cases with known results:
|
||||
|
||||
---
|
||||
|
||||
## 15. References
|
||||
## 15. Delta-Sig Predicate Attestation
|
||||
|
||||
**Sprint Reference**: `SPRINT_20260117_003_BINDEX_delta_sig_predicate`
|
||||
|
||||
Delta-sig predicates provide a supply chain attestation format for binary patches, enabling policy-gated releases based on function-level change scope.
|
||||
|
||||
### 15.1 Predicate Structure
|
||||
|
||||
```jsonc
|
||||
{
|
||||
"_type": "https://in-toto.io/Statement/v1",
|
||||
"predicateType": "https://stellaops.io/delta-sig/v1",
|
||||
"subject": [
|
||||
{
|
||||
"name": "libexample-1.1.so",
|
||||
"digest": {
|
||||
"sha256": "abc123..."
|
||||
}
|
||||
}
|
||||
],
|
||||
"predicate": {
|
||||
"before": {
|
||||
"name": "libexample-1.0.so",
|
||||
"digest": { "sha256": "def456..." }
|
||||
},
|
||||
"after": {
|
||||
"name": "libexample-1.1.so",
|
||||
"digest": { "sha256": "abc123..." }
|
||||
},
|
||||
"diff": [
|
||||
{
|
||||
"function": "process_input",
|
||||
"changeType": "modified",
|
||||
"beforeHash": "sha256:old...",
|
||||
"afterHash": "sha256:new...",
|
||||
"bytesDelta": 48,
|
||||
"semanticSimilarity": 0.87
|
||||
},
|
||||
{
|
||||
"function": "new_handler",
|
||||
"changeType": "added",
|
||||
"afterHash": "sha256:new...",
|
||||
"bytesDelta": 256
|
||||
}
|
||||
],
|
||||
"summary": {
|
||||
"functionsAdded": 1,
|
||||
"functionsRemoved": 0,
|
||||
"functionsModified": 1,
|
||||
"totalBytesChanged": 304
|
||||
},
|
||||
"timestamp": "2026-01-16T12:00:00Z"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 15.2 Policy Gate Integration
|
||||
|
||||
The `DeltaScopePolicyGate` enforces limits on patch scope:
|
||||
|
||||
```yaml
|
||||
policy:
|
||||
deltaSig:
|
||||
maxAddedFunctions: 10
|
||||
maxRemovedFunctions: 5
|
||||
maxModifiedFunctions: 20
|
||||
maxBytesChanged: 50000
|
||||
minSemanticSimilarity: 0.5
|
||||
requireSemanticAnalysis: false
|
||||
```
|
||||
|
||||
### 15.3 Attestor Integration
|
||||
|
||||
Delta-sig predicates integrate with the Attestor module:
|
||||
|
||||
1. **Generate** - Create predicate from before/after binary analysis
|
||||
2. **Sign** - Create DSSE envelope with cosign/fulcio signature
|
||||
3. **Submit** - Log to Rekor transparency log
|
||||
4. **Verify** - Validate signature and inclusion proof
|
||||
|
||||
### 15.4 CLI Commands
|
||||
|
||||
```bash
|
||||
# Generate delta-sig predicate
|
||||
stella binary diff --before old.so --after new.so --output delta.json
|
||||
|
||||
# Generate and attest in one step
|
||||
stella binary attest --before old.so --after new.so --sign --rekor
|
||||
|
||||
# Verify attestation
|
||||
stella binary verify --predicate delta.json --signature sig.dsse
|
||||
|
||||
# Check against policy gate
|
||||
stella binary gate --predicate delta.json --policy policy.yaml
|
||||
```
|
||||
|
||||
### 15.5 Semantic Similarity Scoring
|
||||
|
||||
When `requireSemanticAnalysis` is enabled, the gate also checks:
|
||||
|
||||
| Threshold | Meaning |
|
||||
|-----------|---------|
|
||||
| > 0.9 | Near-identical (cosmetic changes) |
|
||||
| 0.7 - 0.9 | Similar (refactoring, optimization) |
|
||||
| 0.5 - 0.7 | Moderate changes (significant logic) |
|
||||
| < 0.5 | Major rewrite (requires review) |
|
||||
|
||||
### 15.6 Evidence Storage
|
||||
|
||||
Delta-sig predicates are stored in the Evidence Locker and can be included in portable bundles for air-gapped verification.
|
||||
|
||||
---
|
||||
|
||||
## 16. References
|
||||
|
||||
### Internal
|
||||
|
||||
@@ -604,8 +717,10 @@ Pre-computed test cases with known results:
|
||||
- [ghidriff Tool](https://github.com/clearbluejar/ghidriff)
|
||||
- [SemDiff Paper (arXiv)](https://arxiv.org/abs/2308.01463)
|
||||
- [SEI Semantic Equivalence Research](https://www.sei.cmu.edu/annual-reviews/2022-research-review/semantic-equivalence-checking-of-decompiled-binaries/)
|
||||
- [in-toto Attestation Framework](https://in-toto.io/)
|
||||
- [SLSA Provenance Spec](https://slsa.dev/provenance/v1)
|
||||
|
||||
---
|
||||
|
||||
*Document Version: 1.0.1*
|
||||
*Last Updated: 2026-01-14*
|
||||
*Document Version: 1.1.0*
|
||||
*Last Updated: 2026-01-16*
|
||||
|
||||
@@ -132,3 +132,101 @@ All observation documents are immutable. New information creates a new observati
|
||||
- `EXCITITOR-GRAPH-24-*` relies on this schema to build overlays.
|
||||
- `DOCS-LNM-22-002` (Link-Not-Merge documentation) references this file.
|
||||
- `EXCITITOR-ATTEST-73-*` uses `document.digest` + `signature` to embed provenance in attestation payloads.
|
||||
|
||||
---
|
||||
|
||||
## Rekor Transparency Log Linkage
|
||||
|
||||
**Sprint Reference**: `SPRINT_20260117_002_EXCITITOR_vex_rekor_linkage`
|
||||
|
||||
VEX observations can be attested to the Sigstore Rekor transparency log, providing an immutable, publicly verifiable record of when each observation was recorded. This supports:
|
||||
|
||||
- **Auditability**: Independent verification that an observation existed at a specific time
|
||||
- **Non-repudiation**: Cryptographic proof of observation provenance
|
||||
- **Supply chain compliance**: Evidence for regulatory and security requirements
|
||||
- **Offline verification**: Stored inclusion proofs enable air-gapped verification
|
||||
|
||||
### Rekor Linkage Fields
|
||||
|
||||
The following fields are added to `vex_observations` when an observation is attested:
|
||||
|
||||
| Field | Type | Description |
|
||||
|-------|------|-------------|
|
||||
| `rekor_uuid` | TEXT | Rekor entry UUID (64-char hex) |
|
||||
| `rekor_log_index` | BIGINT | Monotonically increasing log position |
|
||||
| `rekor_integrated_time` | TIMESTAMPTZ | When entry was integrated into log |
|
||||
| `rekor_log_url` | TEXT | Rekor server URL where submitted |
|
||||
| `rekor_inclusion_proof` | JSONB | RFC 6962 inclusion proof for offline verification |
|
||||
| `rekor_linked_at` | TIMESTAMPTZ | When linkage was recorded locally |
|
||||
|
||||
### Schema Extension
|
||||
|
||||
```sql
|
||||
-- V20260117__vex_rekor_linkage.sql
|
||||
ALTER TABLE excititor.vex_observations
|
||||
ADD COLUMN IF NOT EXISTS rekor_uuid TEXT,
|
||||
ADD COLUMN IF NOT EXISTS rekor_log_index BIGINT,
|
||||
ADD COLUMN IF NOT EXISTS rekor_integrated_time TIMESTAMPTZ,
|
||||
ADD COLUMN IF NOT EXISTS rekor_log_url TEXT,
|
||||
ADD COLUMN IF NOT EXISTS rekor_inclusion_proof JSONB,
|
||||
ADD COLUMN IF NOT EXISTS rekor_linked_at TIMESTAMPTZ;
|
||||
|
||||
-- Indexes for Rekor queries
|
||||
CREATE INDEX idx_vex_observations_rekor_uuid
|
||||
ON excititor.vex_observations(rekor_uuid)
|
||||
WHERE rekor_uuid IS NOT NULL;
|
||||
|
||||
CREATE INDEX idx_vex_observations_pending_rekor
|
||||
ON excititor.vex_observations(created_at)
|
||||
WHERE rekor_uuid IS NULL;
|
||||
```
|
||||
|
||||
### API Endpoints
|
||||
|
||||
| Endpoint | Method | Description |
|
||||
|----------|--------|-------------|
|
||||
| `/attestations/rekor/observations/{id}` | POST | Attest observation to Rekor |
|
||||
| `/attestations/rekor/observations/batch` | POST | Batch attestation |
|
||||
| `/attestations/rekor/observations/{id}/verify` | GET | Verify Rekor linkage |
|
||||
| `/attestations/rekor/pending` | GET | List observations pending attestation |
|
||||
|
||||
### CLI Commands
|
||||
|
||||
```bash
|
||||
# Show observation with Rekor details
|
||||
stella vex observation show <id> --show-rekor
|
||||
|
||||
# Attest an observation to Rekor
|
||||
stella vex observation attest <id> [--rekor-url URL]
|
||||
|
||||
# Verify Rekor linkage
|
||||
stella vex observation verify-rekor <id> [--offline]
|
||||
|
||||
# List pending attestations
|
||||
stella vex observation list-pending
|
||||
```
|
||||
|
||||
### Inclusion Proof Structure
|
||||
|
||||
```jsonc
|
||||
{
|
||||
"treeSize": 1234567,
|
||||
"rootHash": "base64-encoded-root-hash",
|
||||
"logIndex": 12345,
|
||||
"hashes": [
|
||||
"base64-hash-1",
|
||||
"base64-hash-2",
|
||||
"base64-hash-3"
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### Verification Modes
|
||||
|
||||
| Mode | Network | Use Case |
|
||||
|------|---------|----------|
|
||||
| Online | Required | Full verification against live Rekor |
|
||||
| Offline | Not required | Verify using stored inclusion proof |
|
||||
|
||||
Offline mode uses the stored `rekor_inclusion_proof` to verify the Merkle path locally. This is essential for air-gapped environments.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user