279 lines
8.6 KiB
Markdown
279 lines
8.6 KiB
Markdown
# component_architecture_evidence_locker.md - **Stella Ops EvidenceLocker** (2025Q4)
|
|
|
|
> Sealed, immutable storage for vulnerability scan evidence and audit logs.
|
|
|
|
> **Scope.** Implementation-ready architecture for **EvidenceLocker**: tamper-proof evidence chains for compliance and forensic analysis with content-addressable storage and cryptographic sealing.
|
|
|
|
---
|
|
|
|
## 0) Mission & boundaries
|
|
|
|
**Mission.** Provide **immutable, sealed storage** for vulnerability scan evidence, audit logs, and compliance artifacts. Ensure tamper-proof evidence chains with cryptographic verification for forensic analysis and regulatory compliance.
|
|
|
|
**Boundaries.**
|
|
|
|
* EvidenceLocker **stores** evidence; it does not generate verdicts.
|
|
* EvidenceLocker **seals** bundles; signing is delegated to Signer.
|
|
* Evidence is **immutable** once sealed; no modifications or deletions.
|
|
* Supports **offline export** for air-gapped compliance audits.
|
|
|
|
---
|
|
|
|
## 1) Solution & project layout
|
|
|
|
```
|
|
src/EvidenceLocker/StellaOps.EvidenceLocker/
|
|
├─ StellaOps.EvidenceLocker.Core/ # Sealing, verification, chain validation
|
|
│ ├─ Services/
|
|
│ │ ├─ ISealingService.cs # Sealing interface
|
|
│ │ ├─ SealingService.cs # Cryptographic sealing
|
|
│ │ ├─ IVerificationService.cs # Verification interface
|
|
│ │ └─ ChainValidator.cs # Evidence chain validation
|
|
│ └─ Models/
|
|
│ ├─ EvidenceBundle.cs # Bundle model
|
|
│ ├─ EvidenceItem.cs # Individual evidence item
|
|
│ └─ SealManifest.cs # Seal metadata
|
|
│
|
|
├─ StellaOps.EvidenceLocker.Infrastructure/ # Storage adapters, bundle management
|
|
│ ├─ Storage/
|
|
│ │ ├─ IEvidenceStore.cs # Storage interface
|
|
│ │ ├─ FileSystemStore.cs # Local filesystem
|
|
│ │ └─ ObjectStore.cs # S3/RustFS storage
|
|
│ └─ Persistence/
|
|
│ └─ PostgresRepository.cs # Metadata persistence
|
|
│
|
|
├─ StellaOps.EvidenceLocker.WebService/ # HTTP API for submission/retrieval
|
|
│ └─ Program.cs
|
|
│
|
|
├─ StellaOps.EvidenceLocker.Worker/ # Background sealing and archival
|
|
│ └─ SealingWorker.cs
|
|
│
|
|
└─ StellaOps.EvidenceLocker.Tests/ # Unit and integration tests
|
|
```
|
|
|
|
---
|
|
|
|
## 2) External dependencies
|
|
|
|
* **PostgreSQL** - Metadata storage (schema: `evidence_locker`)
|
|
* **RustFS/S3** - Object storage for evidence bundles
|
|
* **Signer** - Cryptographic sealing operations
|
|
* **Authority** - Authentication and authorization
|
|
* **ExportCenter** - Evidence bundle export
|
|
|
|
---
|
|
|
|
## 3) Contracts & data model
|
|
|
|
### 3.1 EvidenceBundle
|
|
|
|
```json
|
|
{
|
|
"bundleId": "eb-2025-01-15-abc123",
|
|
"tenantId": "tenant-xyz",
|
|
"createdAt": "2025-01-15T10:30:00.000000Z",
|
|
"sealedAt": "2025-01-15T10:30:05.000000Z",
|
|
"status": "sealed",
|
|
"items": [
|
|
{
|
|
"itemId": "item-001",
|
|
"type": "sbom",
|
|
"format": "cyclonedx-json",
|
|
"digest": "sha256:abc123...",
|
|
"size": 45678,
|
|
"casUri": "cas://evidence/items/abc123"
|
|
},
|
|
{
|
|
"itemId": "item-002",
|
|
"type": "scan-result",
|
|
"format": "stellaops-findings-v1",
|
|
"digest": "sha256:def456...",
|
|
"size": 12345,
|
|
"casUri": "cas://evidence/items/def456"
|
|
}
|
|
],
|
|
"seal": {
|
|
"algorithm": "sha256",
|
|
"rootHash": "sha256:fedcba...",
|
|
"signature": "base64...",
|
|
"keyId": "sha256:keyabc..."
|
|
},
|
|
"chain": {
|
|
"previousBundleId": "eb-2025-01-14-xyz789",
|
|
"previousRootHash": "sha256:prevhash...",
|
|
"sequenceNumber": 42
|
|
}
|
|
}
|
|
```
|
|
|
|
### 3.2 Evidence Item Types
|
|
|
|
| Type | Format | Description |
|
|
|------|--------|-------------|
|
|
| `sbom` | cyclonedx-json, spdx-json | Software Bill of Materials |
|
|
| `scan-result` | stellaops-findings-v1 | Vulnerability scan findings |
|
|
| `policy-verdict` | stellaops-verdict-v1 | Policy evaluation result |
|
|
| `vex-statement` | openvex-v1 | VEX statement |
|
|
| `audit-log` | ndjson | Audit trail events |
|
|
| `attestation` | dsse-v1 | DSSE attestation envelope |
|
|
|
|
### 3.3 Seal Manifest
|
|
|
|
```csharp
|
|
public sealed record SealManifest
|
|
{
|
|
public required string BundleId { get; init; }
|
|
public required string RootHash { get; init; }
|
|
public required string Algorithm { get; init; }
|
|
public required DateTimeOffset SealedAt { get; init; }
|
|
public required string KeyId { get; init; }
|
|
public required byte[] Signature { get; init; }
|
|
public required IReadOnlyList<string> ItemDigests { get; init; }
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## 4) REST API (EvidenceLocker.WebService)
|
|
|
|
All under `/api/v1/evidence`. Auth: **OpTok**.
|
|
|
|
```
|
|
POST /bundles { items: EvidenceItem[] } → { bundleId, status: "pending" }
|
|
POST /bundles/{id}/items { item: EvidenceItem } → { itemId }
|
|
POST /bundles/{id}/seal → { status: "sealed", seal: SealManifest }
|
|
|
|
GET /bundles/{id} → { bundle: EvidenceBundle }
|
|
GET /bundles/{id}/items/{itemId} → binary content
|
|
GET /bundles/{id}/verify → { valid: bool, details }
|
|
|
|
GET /bundles?tenant={id}&from={date}&to={date} → { bundles: BundleSummary[] }
|
|
|
|
POST /export { bundleIds: string[], format: "zip"|"tar" } → { exportId }
|
|
GET /export/{id} → binary archive
|
|
GET /export/{id}/status → { status, progress }
|
|
|
|
GET /healthz | /readyz | /metrics
|
|
```
|
|
|
|
---
|
|
|
|
## 5) Configuration (YAML)
|
|
|
|
```yaml
|
|
EvidenceLocker:
|
|
Postgres:
|
|
ConnectionString: "Host=postgres;Database=evidence_locker;..."
|
|
|
|
Storage:
|
|
Provider: "rustfs" # or "filesystem", "s3"
|
|
RustFs:
|
|
Endpoint: "http://rustfs:8080"
|
|
Bucket: "stellaops-evidence"
|
|
Filesystem:
|
|
BasePath: "/data/evidence"
|
|
|
|
Sealing:
|
|
Policy: "immediate" # or "batch"
|
|
BatchSize: 100
|
|
BatchIntervalSeconds: 60
|
|
Algorithm: "sha256"
|
|
|
|
Retention:
|
|
DefaultDays: 2555 # 7 years
|
|
ComplianceDays: 3650 # 10 years for regulated
|
|
|
|
Export:
|
|
MaxBundlesPerExport: 1000
|
|
CompressionLevel: 6
|
|
|
|
Authority:
|
|
Issuer: "https://authority.stellaops.local"
|
|
RequiredScopes: ["evidence:read", "evidence:write"]
|
|
```
|
|
|
|
---
|
|
|
|
## 6) Sealing Process
|
|
|
|
### 6.1 Sealing Flow
|
|
|
|
```
|
|
1. Bundle created (status: "pending")
|
|
└─ Items added with content digests
|
|
|
|
2. Sealing triggered (immediate or batch)
|
|
├─ Compute Merkle root from item digests
|
|
├─ Include chain pointer (previous bundle hash)
|
|
└─ Request signature from Signer
|
|
|
|
3. Bundle sealed (status: "sealed")
|
|
└─ Immutable; no further modifications
|
|
```
|
|
|
|
### 6.2 Chain Integrity
|
|
|
|
Evidence chains are linked via Merkle roots:
|
|
|
|
```
|
|
Bundle N-1 Bundle N Bundle N+1
|
|
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
|
|
│ rootHash: H1│◄────────────│ prevHash: H1│◄─────────────│ prevHash: H2│
|
|
│ seq: 41 │ │ rootHash: H2│ │ rootHash: H3│
|
|
└─────────────┘ │ seq: 42 │ │ seq: 43 │
|
|
└─────────────┘ └─────────────┘
|
|
```
|
|
|
|
---
|
|
|
|
## 7) Security & compliance
|
|
|
|
* **Immutability**: Sealed bundles cannot be modified
|
|
* **Tamper detection**: Merkle tree verification for all items
|
|
* **Chain validation**: Linked bundle verification
|
|
* **Encryption at rest**: Optional bundle encryption
|
|
* **Access control**: Tenant-scoped with Authority tokens
|
|
* **Audit trail**: All access logged
|
|
|
|
---
|
|
|
|
## 8) Performance targets
|
|
|
|
* **Item ingestion**: < 100ms P95 per item
|
|
* **Sealing**: < 500ms P95 per bundle (up to 100 items)
|
|
* **Verification**: < 200ms P95 per bundle
|
|
* **Export**: < 5s P95 for 100 bundles
|
|
|
|
---
|
|
|
|
## 9) Observability
|
|
|
|
**Metrics:**
|
|
* `evidence.bundles.created_total{tenant}`
|
|
* `evidence.bundles.sealed_total{tenant}`
|
|
* `evidence.items.ingested_total{type}`
|
|
* `evidence.verification.duration_seconds`
|
|
* `evidence.storage.bytes_total`
|
|
|
|
**Tracing:** Spans for ingestion, sealing, verification, export.
|
|
|
|
---
|
|
|
|
## 10) Testing matrix
|
|
|
|
* **Sealing tests**: Correct Merkle root computation
|
|
* **Chain tests**: Linked bundle verification
|
|
* **Tamper tests**: Detection of modified items
|
|
* **Export tests**: Archive integrity verification
|
|
* **Retention tests**: Policy enforcement
|
|
|
|
---
|
|
|
|
## Related Documentation
|
|
|
|
* Bundle packaging: `./bundle-packaging.md`
|
|
* Attestation contract: `./attestation-contract.md`
|
|
* Evidence bundle spec: `./evidence-bundle-v1.md`
|
|
* ExportCenter: `../export-center/architecture.md`
|
|
* Attestor: `../attestor/architecture.md`
|