# 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": "", "signatures": [{ "keyid": "mirror-root-ed25519-01", "sig": "" }] } ``` **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*