Restore Bundle

Backup-bundle reader — verify the manifest signature, list bundle contents without decrypting, and cherry-pick a restore subset to a staging directory the caller atomically swaps into place.

The mirror of b.backupBundle. b.restoreBundle.inspect reads manifest.json and returns the parsed object — useful for dashboards and pre-flight UI that want to list files, sizes, timestamps, and kinds before prompting the operator for the passphrase. b.restoreBundle.extract decrypts each per-file blob via b.backup/crypto, verifies the SHA3-512 plaintext checksum against the manifest, and writes the recovered files into a fresh stagingDir. The bundle directory itself stays read-only throughout.

extract always recovers the wrapped vault key (decrypted JSON returned on vaultKeyJson) so the operator can unseal columns from a partial restore. The filter predicate lets the caller pull a subset — only the DB, only TLS keys, only the consent log — without producing every blob.

Defense surface:

- Wrong passphrase / tampered blob → AEAD tag failure → restore-bundle/decrypt-failed (no plaintext leak, no staging left behind) - Pre-decrypt encryptedSize mismatch → restore-bundle/ size-mismatch - Post-decrypt SHA3-512 ≠ manifest checksum → restore-bundle/checksum-mismatch - Missing blob file → restore-bundle/missing-blob - Bad manifest signature → restore-bundle/bad-signature; requireSignature: true upgrades a missing signature to restore-bundle/missing-signature - On any failure the partially-built stagingDir is removed so a subsequent retry is not blocked by a stale directory

b.restoreBundle.extract(opts) #

stable0.5.0
{
  bundleDir:           string,                   // read-only bundle dir (required)
  stagingDir:          string,                   // fresh output dir (required, must not exist)
  passphrase:          Buffer | string,          // unwrap key (required)
  filter:              function (entry): boolean,// subset predicate
  progressCallback:    function (ev): void,      // phase events: read_manifest / decrypt / done
  verifySignature:     boolean,                  // default: true
  requireSignature:    boolean,                  // fail-closed on missing signature
  expectedFingerprint: string,                   // pin specific signing key
}

Decrypt every blob the manifest references (or the subset opts.filter accepts), verify each plaintext's checksum, and write the recovered files into opts.stagingDir. Returns { manifest, vaultKeyJson, fileCount, totalBytes, stagingDir, durationMs }.

stagingDir MUST NOT exist — extract refuses to merge into an existing directory so a half-finished prior restore can never get silently overlaid. On any failure the partial stagingDir is removed.

Signature handling: when the manifest carries a signature it is verified with b.backup/manifest's public-key check. Pass verifySignature: false for cold restores from an org whose audit-sign keypair the framework cannot reach; pass requireSignature: true to fail-closed on bundles missing a signature; pass expectedFingerprint to pin a specific signing key.

try {
  var report = await b.restoreBundle.extract({
    bundleDir:        "/srv/backups/2026-04-27.bundle",
    stagingDir:       "/srv/restore/data.staging",
    passphrase:       Buffer.from("operator-passphrase"),
    requireSignature: true,
    filter:           function (entry) { return entry.kind === "db"; },
  });
  report.fileCount;            // → 1
  typeof report.vaultKeyJson;  // → "string"
} catch (e) {
  e.code; // → "restore-bundle/decrypt-failed"
}

b.restoreBundle.inspect(opts) #

stable0.5.0
{
  bundleDir: string,   // bundle directory (required, must exist)
}

Read manifest.json from opts.bundleDir and return the parsed object — files, sizes, timestamps, kinds, signature presence — without prompting for the passphrase or decrypting anything. Useful for dashboards, pre-flight UI, and "what's in this bundle?" checks before kicking off a long extract.

Throws RestoreBundleError("restore-bundle/no-bundle") when bundleDir is missing, and RestoreBundleError("restore-bundle/missing-manifest") when the directory exists but has no manifest.json (the bundle is incomplete or not a blamejs bundle).

try {
  var manifest = b.restoreBundle.inspect({
    bundleDir: "/srv/backups/2026-04-27.bundle",
  });
  manifest.files.length;    // → 12
  typeof manifest.signature; // → "string"
} catch (e) {
  e.code; // → "restore-bundle/missing-manifest"
}

Last updated 2026-08-08T16:39:49.652Z by seeder.