11 KiB
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
{
"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:
{
"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 identifierkeyid- Key reference for verificationcreated- UTC timestamp of signingpurpose- Must bemirror-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:
{
"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
{
"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:
{
"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)
- Deterministic tarball assembler (
make-thin-v1.sh) - Manifest generation with sorted keys
- OCI layout generation
- Verification scripts (
verify_thin_bundle.py)
6.2 Phase 2: DSSE/TUF Signing (In Progress)
- DSSE envelope generation with Ed25519
- TUF metadata structure
- Production key provisioning (blocked on CI secret)
- Automated rotation pipeline
6.3 Phase 3: Time Anchoring (In Progress)
- Time-anchor schema definition
- Contract for
generatedAt,validForSecondsfields - Production Roughtime/RFC3161 integration
- Trust roots provisioning
6.4 Phase 4: Distribution Integration (Planned)
- Export Center mirror profile automation
- Orchestrator
mirror.readyevent emission - CLI
stella mirror create|verify|statuscommands - 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
{
"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
# 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
- Verify MANIFEST.json signature against bundled TUF root
- Validate each artifact hash matches manifest
- Check time anchor freshness against configured tolerance
- Import to local stores (Concelier, Excititor, Evidence Locker)
- Record import event with provenance in Timeline
9. Verification Workflow
9.1 Online Verification
- Fetch bundle from registry/export center
- Verify DSSE signature against JWKS
- Validate TUF metadata chain
- Check Rekor transparency log (if present)
- Verify time anchor freshness
9.2 Offline Verification
- Extract bundle and TUF metadata
- Verify DSSE signature against bundled public key
- Validate all file hashes match manifest
- Check time anchor against local clock + tolerance
- 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