Superadmin feature

Backup & CAB Bundle Export

Export a signed, verifiable .ecpbundle.zip of a client workspace. Use it for CAB audits, partner migration, or disaster recovery.

What's in a bundle

An .ecpbundle.zip is a reproducible snapshot of one client organisation. Every file is hashed (SHA-256) and listed in the manifest. The signature file binds the manifest to the bundle, so any tampering is detectable offline — no ECP server needed.

Bundle contents

  • manifest.json — bundle metadata + per-file SHA-256
  • signature.txt — SHA-256 of manifest (Ed25519 reserved)
  • events.jsonl.gz — full append-only event log
  • state/organization.json — frozen org profile
  • state/wiki/*.md — every wiki page at export time
  • state/evidence/metadata.json — evidence catalogue
  • state/assessment/maturity.json — latest maturity scores
  • README-CAB.md — what a CAB auditor should check
  • README-MSP.md — re-import instructions for partners
  • verify.sh / verify.ps1 — offline hash verification

Export a bundle

Only the superadmin can export. Call the API directly with the target organisation's ID:

curl -X POST https://easycyberprotection.com/api/bundle/export/<org_id> \
  -H "Authorization: Bearer <superadmin_jwt>" \
  -o client-bundle.ecpbundle.zip

The filename returned follows {slug}--{shortId}--{YYYY-MM-DD}.ecpbundle.zip. Bundles are generated on demand from the live event log — they're always fresh.

Verify a bundle offline

Anyone with the zip — auditor, regulator, the client — can verify integrity without contacting ECP. Extract and run the script that ships inside the bundle:

# Linux / macOS
unzip client-bundle.ecpbundle.zip -d bundle && cd bundle && bash verify.sh

# Windows PowerShell
Expand-Archive client-bundle.ecpbundle.zip -DestinationPath bundle
cd bundle; pwsh ./verify.ps1

The script recomputes every file's SHA-256, compares to the manifest, and checks that the signature matches the manifest hash. Any mismatch means the bundle was altered after export.

Re-import a bundle

Re-imports target an empty organisation — this is the safety rail that prevents accidentally blending two workspaces. Create a fresh org, then:

# Step 1: validate first (never writes)
curl -X POST https://easycyberprotection.com/api/bundle/verify \
  -H "Authorization: Bearer <jwt>" \
  -F "[email protected]"

# Step 2: import into the empty target org
curl -X POST https://easycyberprotection.com/api/bundle/import/<target_org_id> \
  -H "Authorization: Bearer <jwt>" \
  -F "[email protected]"

Import is two-pass: it validates everything before writing a single row. Events are replayed chronologically through the reactor, so projections (wiki pages, memberships, evidence, maturity) rebuild deterministically to match the source workspace exactly.

The target org must be empty.

If the target already has events, import fails fast. This is deliberate — importing into a non-empty org would corrupt both event streams.

When to export

  • Before a CAB audit — hand the auditor a bundle + README-CAB.md. They verify offline, walk the wiki pages, read the events.
  • Partner migration — the client is switching MSPs. Export, the new partner creates a fresh workspace, re-imports.
  • Disaster recovery — a rolling schedule of exports to long-term storage. If ECP goes down, you still have the workspace.
  • Year-end archive — freeze state for compliance records.
TARS