This commit is contained in:
StellaOps Bot
2025-11-29 02:19:50 +02:00
parent 2548abc56f
commit b34f13dc03
86 changed files with 9625 additions and 640 deletions

View File

@@ -0,0 +1,427 @@
# Mirror and Offline Kit Strategy
**Version:** 1.0
**Date:** 2025-11-29
**Status:** Canonical
This advisory defines the product rationale, data contracts, and implementation strategy for the Mirror module, covering deterministic thin-bundle assembly, DSSE/TUF signing, time anchoring, and air-gapped distribution.
---
## 1. Executive Summary
The Mirror module enables **air-gapped deployments** by producing deterministic, cryptographically signed bundles containing advisories, VEX documents, and policy packs. Key capabilities:
- **Thin Bundle Assembly** - Deterministic tar.gz with sorted entries and fixed timestamps
- **DSSE/TUF Signing** - Ed25519 signatures with TUF metadata for key rotation
- **Time Anchoring** - Roughtime/RFC3161 tokens for clock-independent freshness
- **OCI Distribution** - Registry-compatible layout for container-native workflows
- **Offline Verification** - Complete verification without network connectivity
---
## 2. Market Drivers
### 2.1 Target Segments
| Segment | Offline Requirements | Use Case |
|---------|---------------------|----------|
| **Defense/Intelligence** | Complete air-gap | Classified networks without internet |
| **Critical Infrastructure** | OT network isolation | ICS/SCADA vulnerability management |
| **Financial Services** | DMZ-only connectivity | Regulated trading floor systems |
| **Healthcare** | Network segmentation | Medical device security scanning |
### 2.2 Competitive Positioning
Most vulnerability databases require constant connectivity. Stella Ops differentiates with:
- **Cryptographically verifiable offline data** (DSSE + TUF)
- **Deterministic bundles** for reproducible deployments
- **Time-anchor freshness** without NTP dependency
- **OCI-native distribution** for registry mirroring
---
## 3. Technical Architecture
### 3.1 Thin Bundle Layout (v1)
```
mirror-thin-v1.tar.gz
├── manifest.json # Bundle metadata, file inventory, hashes
├── layers/
│ ├── observations.ndjson # Advisory observations
│ ├── time-anchor.json # Time token + verification metadata
│ └── policies.tar.gz # Policy pack bundle (optional)
├── indexes/
│ └── observations.index # Linkage index
└── oci/ # OCI layout (optional)
├── index.json
├── oci-layout
└── blobs/sha256/...
```
### 3.2 Determinism Rules
All thin bundles must be **bit-for-bit reproducible**:
| Property | Rule |
|----------|------|
| **Tar format** | POSIX with `--sort=name` |
| **Owner/Group** | `--owner=0 --group=0` |
| **mtime** | `--mtime='1970-01-01'` |
| **Gzip** | `--no-name` flag |
| **JSON** | Sorted keys, indent=2, trailing newline |
| **Hashes** | Lower-case hex, SHA-256 |
| **Timestamps** | UTC ISO-8601 (RFC3339) |
| **Symlinks** | Not allowed |
### 3.3 Manifest Structure
```json
{
"version": "1.0.0",
"created": "2025-11-29T00:00:00Z",
"bundleId": "mirror-thin-v1-20251129",
"generation": 42,
"layers": [
{
"path": "layers/observations.ndjson",
"size": 1048576,
"digest": "sha256:abc123..."
}
],
"indexes": [
{
"name": "observations.index",
"digest": "sha256:def456..."
}
],
"hashes": {
"tarball_sha256": "sha256:...",
"manifest_sha256": "sha256:..."
},
"timeAnchor": {
"generatedAt": "2025-11-29T00:00:00Z",
"source": "roughtime",
"tokenDigest": "sha256:..."
}
}
```
---
## 4. DSSE/TUF Signing Profile
### 4.1 DSSE Envelope
**Payload Type:** `application/vnd.stellaops.mirror+json;version=1`
**Structure:**
```json
{
"payloadType": "application/vnd.stellaops.mirror+json;version=1",
"payload": "<base64(manifest.json)>",
"signatures": [{
"keyid": "mirror-root-ed25519-01",
"sig": "<base64(Ed25519 signature)>"
}]
}
```
**Header Claims:**
- `issuer` - Signing authority identifier
- `keyid` - Key reference for verification
- `created` - UTC timestamp of signing
- `purpose` - Must be `mirror-bundle`
### 4.2 TUF Metadata Layout
```
tuf/
├── root.json # Trust root (long-lived)
├── snapshot.json # Metadata versions
├── targets.json # Target file mappings
├── timestamp.json # Freshness timestamp
└── keys/
└── mirror-root-ed25519-01.pub
```
**Targets Mapping:**
```json
{
"targets": {
"mirror-thin-v1.tar.gz": {
"length": 10485760,
"hashes": {
"sha256": "abc123..."
}
},
"mirror-thin-v1.manifest.json": {
"length": 2048,
"hashes": {
"sha256": "def456..."
}
}
}
}
```
### 4.3 Key Management
| Key Type | Lifetime | Storage | Rotation |
|----------|----------|---------|----------|
| **Root** | 1 year | HSM/offline | Ceremony required |
| **Snapshot** | 90 days | Online | Automated |
| **Targets** | 90 days | Online | Automated |
| **Timestamp** | 1 day | Online | Continuous |
---
## 5. Time Anchoring
### 5.1 Time-Anchor Schema
```json
{
"anchorTime": "2025-11-29T00:00:00Z",
"source": "roughtime",
"format": "roughtime-v1",
"tokenDigest": "sha256:...",
"signatureFingerprint": "abc123...",
"verification": {
"status": "passed",
"reason": null
},
"generatedAt": "2025-11-29T00:00:00Z",
"sourceClock": "ntp:chrony",
"validForSeconds": 86400
}
```
### 5.2 Staleness Calculation
```
stalenessSeconds = now_utc - generatedAt
isStale = stalenessSeconds > (validForSeconds + 5s_tolerance)
```
**Default validity:** 24 hours (86400 seconds)
### 5.3 Trust Roots
Trust roots for time verification stored in offline-friendly bundle:
```json
{
"roughtime": [
{
"name": "cloudflare",
"publicKey": "...",
"address": "roughtime.cloudflare.com:2002"
}
],
"rfc3161": [
{
"name": "digicert",
"url": "http://timestamp.digicert.com",
"certificate": "..."
}
]
}
```
---
## 6. Implementation Strategy
### 6.1 Phase 1: Thin Bundle Assembly (Complete)
- [x] Deterministic tarball assembler (`make-thin-v1.sh`)
- [x] Manifest generation with sorted keys
- [x] OCI layout generation
- [x] Verification scripts (`verify_thin_bundle.py`)
### 6.2 Phase 2: DSSE/TUF Signing (In Progress)
- [x] DSSE envelope generation with Ed25519
- [x] TUF metadata structure
- [ ] Production key provisioning (blocked on CI secret)
- [ ] Automated rotation pipeline
### 6.3 Phase 3: Time Anchoring (In Progress)
- [x] Time-anchor schema definition
- [x] Contract for `generatedAt`, `validForSeconds` fields
- [ ] Production Roughtime/RFC3161 integration
- [ ] Trust roots provisioning
### 6.4 Phase 4: Distribution Integration (Planned)
- [ ] Export Center mirror profile automation
- [ ] Orchestrator `mirror.ready` event emission
- [ ] CLI `stella mirror create|verify|status` commands
- [ ] OCI registry push/pull workflows
---
## 7. API Surface
### 7.1 Mirror APIs
| Endpoint | Method | Scope | Description |
|----------|--------|-------|-------------|
| `/mirror/bundles` | GET | `mirror:read` | List mirror bundles |
| `/mirror/bundles/{id}` | GET | `mirror:read` | Get bundle metadata |
| `/mirror/bundles/{id}/download` | GET | `mirror:read` | Download thin bundle |
| `/mirror/bundles` | POST | `mirror:create` | Create new mirror bundle |
| `/mirror/verify` | POST | `mirror:read` | Verify bundle integrity |
### 7.2 Orchestrator Events
**Event:** `mirror.ready`
```json
{
"bundleId": "mirror-thin-v1-20251129",
"generation": 42,
"generatedAt": "2025-11-29T00:00:00Z",
"manifestDigest": "sha256:...",
"dsseDigest": "sha256:...",
"location": "s3://mirrors/thin/v1/...",
"rekorUUID": "..."
}
```
**Semantics:** At-least-once delivery; consumers de-dup by `(bundleId, generation)`.
### 7.3 CLI Commands
```bash
# Create mirror bundle
stella mirror create --output mirror-thin-v1.tar.gz
# Verify bundle integrity
stella mirror verify mirror-thin-v1.tar.gz
# Check bundle status
stella mirror status --bundle-id mirror-thin-v1-20251129
# Import bundle into air-gapped installation
stella airgap import mirror-thin-v1.tar.gz --describe
```
---
## 8. Offline Kit Integration
### 8.1 Offline Kit Structure
```
offline-kit/
├── mirrors/
│ ├── mirror-thin-v1.tar.gz # Advisory/VEX data
│ ├── mirror-thin-v1.manifest.json
│ └── mirror-thin-v1.dsse.json
├── evidence/
│ └── evidence-bundle-*.tar.gz # Evidence bundles
├── policies/
│ └── policy-pack-*.tar.gz # Policy packs
├── trust/
│ ├── tuf/ # TUF metadata
│ └── time-anchors.json # Time trust roots
└── MANIFEST.json # Kit manifest with hashes
```
### 8.2 Import Workflow
1. **Verify MANIFEST.json** signature against bundled TUF root
2. **Validate each artifact** hash matches manifest
3. **Check time anchor freshness** against configured tolerance
4. **Import to local stores** (Concelier, Excititor, Evidence Locker)
5. **Record import event** with provenance in Timeline
---
## 9. Verification Workflow
### 9.1 Online Verification
1. Fetch bundle from registry/export center
2. Verify DSSE signature against JWKS
3. Validate TUF metadata chain
4. Check Rekor transparency log (if present)
5. Verify time anchor freshness
### 9.2 Offline Verification
1. Extract bundle and TUF metadata
2. Verify DSSE signature against bundled public key
3. Validate all file hashes match manifest
4. Check time anchor against local clock + tolerance
5. Record verification result in local audit log
---
## 10. Security Considerations
### 10.1 Key Protection
- Root keys stored in HSM or offline cold storage
- Online keys rotated automatically per TUF policy
- Key ceremonies documented and audited
### 10.2 Rollback Protection
- TUF timestamp/snapshot prevent rollback attacks
- Generation numbers monotonically increasing
- Stale bundles rejected based on time anchor
### 10.3 Tampering Detection
- DSSE signature covers entire manifest
- Each file has individual hash verification
- Merkle tree optional for large bundles
---
## 11. Related Documentation
| Resource | Location |
|----------|----------|
| Mirror module docs | `docs/modules/mirror/` |
| DSSE/TUF profile | `docs/modules/mirror/dsse-tuf-profile.md` |
| Thin bundle spec | `docs/modules/mirror/thin-bundle-assembler.md` |
| Time-anchor schema | `docs/airgap/time-anchor-schema.json` |
| Signing runbook | `docs/modules/mirror/signing-runbook.md` |
---
## 12. Sprint Mapping
- **Primary Sprint:** SPRINT_0125_0001_0001 (Mirror Bundles)
- **Coordination:** SPRINT_0150_0001_0001 (DSSE/Time Anchors)
**Key Task IDs:**
- `MIRROR-CRT-56-001` - Deterministic assembler (DONE)
- `MIRROR-CRT-56-002` - DSSE/TUF signing (BLOCKED - CI key needed)
- `MIRROR-CRT-57-001` - OCI layout generation (DONE)
- `MIRROR-CRT-57-002` - Time-anchor embedding (PARTIAL)
- `CLI-AIRGAP-56-001` - CLI mirror commands (BLOCKED)
---
## 13. Success Metrics
| Metric | Target |
|--------|--------|
| Bundle hash reproducibility | 100% (bit-identical) |
| DSSE verification success | 100% for valid bundles |
| Time anchor freshness | < 24 hours default |
| Offline import success | Works without network |
| TUF metadata validation | Full chain verified |
---
*Last updated: 2025-11-29*