Files
git.stella-ops.org/docs/modules/export-center/prep/2025-11-20-export-airgap-57-001-prep.md
master d519782a8f
Some checks failed
Docs CI / lint-and-preview (push) Has been cancelled
prep docs and service updates
2025-11-21 06:56:36 +00:00

4.7 KiB
Raw Blame History

Export AirGap Prep — PREP-EXPORT-AIRGAP-57-001

Status: Ready for implementation (2025-11-20) Owners: Exporter Service Guild · Evidence Locker Guild Scope: Portable evidence export mode (air-gap) that reuses EvidenceLocker sealed/portable bundles and packages them for ExportCenter delivery.

Dependencies (must remain green before coding)

  • EvidenceLocker packaging contract (sealed + portable): docs/modules/evidence-locker/bundle-packaging.md, docs/airgap/portable-evidence.md.
  • Upstream sealed bundle export readiness (56-001) and bootstrap pack alignment (56-002) — inputs are reused verbatim, no re-signing.
  • Orchestrator/Notifications envelopes for emission events remain pending; not required to start packaging but block notification wiring.

Contract for EXPORT-AIRGAP-57-001

  1. Input: bundle id (bundleId) that is already sealed. Export service fetches the portable archive portable-bundle-v1.tgz via the EvidenceLocker portable endpoint (write-once cache).

  2. Packaging: create deterministic gzip/tar (export-portable-bundle-v1.tgz) with fixed mtime 2025-01-01T00:00:00Z, PAX headers, and sorted entries:

    export-portable-bundle-v1.tgz
    ├── export.json          # Export job metadata (bundleId, exportId, tenant, createdAtUtc, rootHash, sourceUri, portableVersion)
    ├── portable-bundle-v1.tgz  # Bit-for-bit copy from EvidenceLocker (no re-signing)
    ├── checksums.txt        # SHA256 for all files (portable bundle included) + Merkle root
    ├── verify-export.sh     # POSIX script: checksum portable bundle, call `stella evidence verify --bundle portable-bundle-v1.tgz`
    └── README.md            # Operator instructions (ingress/egress steps, expected headers, schema links)
    
    • Gzip header mtime and tar mtimes are pinned; permissions 0644; owner/group 0.
    • checksums.txt lists files in lexical order; first line root <sha256(export-portable-bundle-v1.tgz)>.
    • verify-export.sh uses only tar + sha256sum/shasum; no network calls.
  3. API surface (ExportCenter)

    • POST /v1/exports/airgap/evidence/{bundleId}: stages the export; responds 202 Accepted with exportId and link to poll.
    • GET /v1/exports/airgap/evidence/{exportId}: returns status + download link when ready; includes rootHash, portableVersion, bundleId.
    • GET /v1/exports/airgap/evidence/{exportId}/download: application/gzip, filename export-portable-bundle-v1.tgz, ETag = SHA256.
    • Auth: export:read for GET, export:write for POST; support tenant scoping identical to EvidenceLocker.
  4. Determinism & observability

    • No wall-clock usage beyond the already fixed createdAtUtc written once per export job.
    • Emit structured log {exportId,bundleId,portableVersion,rootHash} on completion.
    • Metrics: counter export.airgap.portable.completed, histogram export.airgap.portable.duration_ms, gauge export.airgap.portable.queue_depth.
  5. Error handling

    • If bundle not sealed → 409 SealedRequired with retryAfter.
    • If portable artefact missing → trigger fetch from EvidenceLocker; return 202 with pendingReason=PortableMaterialising.
    • Verification failures of copied bundle (hash mismatch) → mark export FAILED and keep artefact; require operator acknowledgement.

Acceptance criteria

  • Deterministic archive bytes for a given (bundleId, exportId) across reruns; gzip/tar timestamps and ordering pinned.
  • Export archive contains the unmodified EvidenceLocker portable bundle and top-level instructions for offline operators.
  • CLI verification path documented in README and script; succeeds with no network access using current stella evidence verify.
  • Status/Download endpoints documented and cover 202/404/409/500 cases; ETag and Last-Modified set.

Implementation notes for developers

  • Reuse EvidenceLockers PortableBundleVersion constant to avoid drift; do not unzip/repack the inner portable archive.
  • Populate export.json using UTC ISO-8601; include sourceUri referencing the original EvidenceLocker portable endpoint used.
  • Store artefacts under object key exports/{tenant}/{bundleId}/{exportId}/export-portable-bundle-v1.tgz with write-once semantics.
  • Mirror logging/metrics naming with 56-001/56-002 to ease dashboard reuse.

Open items / risks

  • Notifications/timeline emission remains pending on Wave 150/140 envelope drop; add once schemas land (tracked separately).
  • If portable bundle version bumps to v2, archive filename and portableVersion must be updated in tandem.

Handoff

  • This prep artefact is ready to implement in src/ExportCenter/StellaOps.ExportCenter.WebService job + StellaOps.ExportCenter.Worker for queue processing.
  • Link back to this document from Sprint 0162 Delivery Tracker entry P4.