3.8 KiB
AirGap Importer
The AirGap Importer verifies and ingests offline bundles (mirror, bootstrap, evidence kits) into a sealed or constrained deployment. It fails closed by default: imports are rejected when verification fails, and failures are diagnosable offline.
This document describes importer behavior and its key building blocks. For bundle formats and operational workflow, see docs/modules/airgap/guides/offline-bundle-format.md, docs/modules/airgap/guides/mirror-bundles.md, and docs/modules/airgap/guides/operations.md.
Responsibilities
- Verify bundle integrity and authenticity (DSSE signatures; optional TUF metadata where applicable).
- Enforce monotonicity (prevent version rollback unless explicitly force-activated with a recorded reason).
- Stage verified content into deterministic layouts (catalog + item repository + object-store paths).
- Quarantine failed bundles for forensic analysis with deterministic logs and metadata.
- Emit an audit trail for every dry-run and import attempt (success or failure).
Verification pipeline (conceptual)
- Plan: build an ordered list of validation/ingest steps for the bundle (
BundleImportPlanner). - Validate signatures: verify DSSE envelopes and trusted key fingerprints.
- Validate metadata (when present): verify TUF root/snapshot/timestamp consistency against trust roots.
- Compute deterministic roots: compute a Merkle root over staged bundle items (stable ordering).
- Check monotonicity: ensure the incoming bundle version is newer than the currently active version.
- Quarantine on failure: preserve the bundle + verification log and emit a stable failure reason code.
- Commit: write catalog/item entries and activation record; emit audit/timeline events.
The step order must remain stable; if steps change, treat it as a contract change and update CLI/UI guidance.
Quarantine
When verification fails, the importer quarantines the bundle with enough information to debug offline.
Typical structure:
/updates/quarantine/<tenantId>/<timestamp>-<reason>-<id>/bundle.tar.zst(original)manifest.json(if extracted)verification.log(deterministic, no machine-specific paths)failure-reason.txt(human-readable)quarantine.json(structured metadata: tenant, reason, timestamps, sizes, hashes)
Operational expectations:
- Quarantine is bounded: enforce per-tenant quota + TTL cleanup.
- Listing is deterministic: sort by
quarantined_atthenquarantine_id(ordinal).
Version monotonicity
Rollback resistance is enforced via:
- A per-tenant version store (
IBundleVersionStore) backed by Postgres in production. - A monotonicity checker (
IVersionMonotonicityChecker) that compares incoming bundle versions to the active version. - Optional force-activate path requiring a human reason, stored alongside the activation record.
Storage model
The importer writes deterministic metadata that other components can query:
- Bundle catalog: (tenant, bundle_id, digest, imported_at_utc, content paths).
- Bundle items: (tenant, bundle_id, path, digest, size).
For the logical schema and deterministic ordering rules, see docs/modules/airgap/guides/bundle-repositories.md.
Telemetry and auditing
Minimum signals:
- Counters: imports attempted/succeeded/failed, dry-runs, quarantines created, monotonicity failures, force-activations.
- Structured logs with stable reason codes (e.g.,
dsse_signature_invalid,tuf_root_invalid,merkle_mismatch,version_rollback_blocked). - Audit emission: include tenant, bundle_id, digest, operator identity, and whether sealed mode was active.
References
docs/modules/airgap/guides/offline-bundle-format.mddocs/modules/airgap/guides/mirror-bundles.mddocs/modules/airgap/guides/bundle-repositories.mddocs/modules/airgap/guides/operations.mddocs/modules/airgap/guides/controller.md