# How the Automatic Backup System for Key Shares Works in mpcium

> Discover how mpcium's automatic backup system safeguards node secret key-shares with encrypted, incremental backups of the BadgerDB store. Learn about AES-256-GCM encryption and versioned file storage.

- Repository: [Fystack Labs/mpcium](https://github.com/fystack/mpcium)
- Tags: internals
- Published: 2026-03-02

---

**mpcium protects node secret key-shares by running a periodic, encrypted, incremental backup job that snapshots the BadgerDB store, encrypts the dump with AES-256-GCM, and writes versioned backup files to disk.**

The `fystack/mpcium` repository implements a threshold-signature scheme where each node holds sensitive key-share material in a local BadgerDB instance. To prevent catastrophic data loss, the automatic backup system for key shares creates encrypted, incremental snapshots at configurable intervals. This article explains the architecture, execution flow, and restoration process based on the actual source code.

## Backup Architecture Overview

The system consists of three tightly-coupled components that handle scheduling, execution, and recovery:

| Component | Responsibility | Key Implementation |
|-----------|----------------|-------------------|
| **Backup starter** | Reads configuration, creates a `time.Ticker`, and calls the store’s `Backup()` method at regular intervals. | `StartPeriodicBackup` in [`cmd/mpcium/main.go`](https://github.com/fystack/mpcium/blob/main/cmd/mpcium/main.go) |
| **Backup executor** | Loads the latest backup version, runs Badger’s incremental `DB.Backup`, skips when nothing changed, encrypts the payload, writes a self-describing file, and updates the version record. | `badgerBackupExecutor` in [`pkg/kvstore/badger_backup.go`](https://github.com/fystack/mpcium/blob/main/pkg/kvstore/badger_backup.go) |
| **Restore logic** | Scans the backup directory, sorts files chronologically, decrypts each one, and loads the data into a fresh Badger instance. | `RestoreAllBackupsEncrypted` / `loadEncryptedBackup` in [`pkg/kvstore/badger_backup.go`](https://github.com/fystack/mpcium/blob/main/pkg/kvstore/badger_backup.go) |

## Starting the Periodic Backup Job

When the node initializes, the CLI parses `backup_enabled` (default `true`) and `backup_period_seconds` from the configuration. If enabled, [`main.go`](https://github.com/fystack/mpcium/blob/main/main.go) invokes:

```go
stopBackup := StartPeriodicBackup(ctx, badgerKV, backupPeriodSeconds)
defer stopBackup()

```

`StartPeriodicBackup` creates a `time.NewTicker` and launches a goroutine that, on every tick, invokes `badgerKV.Backup()`. The returned `stopBackup` function cancels the context, cleanly halting the background job during shutdown.

## Executing an Incremental Backup

`BadgerKVStore.Backup()` delegates to the executor defined in [`pkg/kvstore/badger_backup.go`](https://github.com/fystack/mpcium/blob/main/pkg/kvstore/badger_backup.go). The `badgerBackupExecutor` performs the following steps:

### 1. Version Bookkeeping

`LoadVersionInfo` reads `latest.version` (or creates a default record) to obtain the last `since` offset and version counter.

### 2. Incremental Badger Dump

The executor calls `b.DB.Backup(&plain, since)`, which streams only the changes since the stored offset. Badger returns `nextSince`. If the dump is empty or `nextSince == since`, the backup is skipped to avoid writing redundant files.

### 3. Encryption

The plain dump (`plain.Bytes()`) is encrypted with **AES-256-GCM** via `encryption.EncryptAESGCM`. The encryption key is derived from the same password used for Badger’s on-disk encryption (`appConfig.BadgerPassword`).

### 4. Metadata Creation

A JSON object (`BadgerBackupMeta`) records:
- Algorithm (`AES-256-GCM`)
- Nonce (base64)
- Timestamps
- Input `Since` and output `NextSince` offsets
- Key identifier (`sha256(key)[:16]`)

### 5. File Formatting

The backup file consists of:
- A magic header (`"MPCIUM_BACKUP"`)
- A big-endian `uint32` length of the metadata JSON
- The metadata JSON bytes
- The ciphertext

The filename encodes the node ID, creation time, and version:

```

backup-<nodeID>-<YYYY-MM-DD_HH-MM-SS>-<version>.enc

```

### 6. Persist Version

After a successful write, `SaveVersionInfo` updates `latest.version` with the new counter and `nextSince`.

## Restoring from Backup Files

When a node reconstructs its Badger DB after a crash or during initial sync, the restore logic in [`pkg/kvstore/badger_backup.go`](https://github.com/fystack/mpcium/blob/main/pkg/kvstore/badger_backup.go) executes:

1. **Creates the target directory** for the new database.
2. **Opens a fresh Badger instance** with the original encryption key.
3. **Iterates over all `backup-*.enc` files** in lexical order (`SortedEncryptedBackups`).
4. For each file:
   - Verifies the magic header.
   - Reads the metadata length, unmarshals the JSON, and extracts the nonce.
   - Decrypts the ciphertext with `encryption.DecryptAESGCM`.
   - Calls `db.Load` to stream the plaintext backup into Badger.

If any step fails, the restore aborts and cleans up the partially-loaded DB. Successful completion logs a confirmation message.

## Configuration and Security

### Configuration Knobs

| Flag / Viper key | Description | Default |
|------------------|-------------|---------|
| `backup_enabled` | Enables the periodic job. | `true` |
| `backup_period_seconds` | Interval between successive backups (seconds). | `300` (5 min – defined in [`pkg/config/constants.go`](https://github.com/fystack/mpcium/blob/main/pkg/config/constants.go)) |
| `backup_dir` | Destination directory for encrypted backups. | `./backups` |
| `badger_password` | Password used both for Badger’s on-disk encryption and backup encryption. | **must be supplied** |

These values are read in [`cmd/mpcium/main.go`](https://github.com/fystack/mpcium/blob/main/cmd/mpcium/main.go) via `viper.SetDefault`, `viper.GetBool`, `viper.GetInt`, and `viper.GetString`.

### Security Properties

- **Encryption at rest** – Backups are AES-256-GCM encrypted with the node’s Badger password, guaranteeing confidentiality even if the backup directory is exposed.
- **Integrity** – The GCM authentication tag is bundled in the ciphertext; decryption fails if the data is tampered.
- **Key identification** – The metadata stores a truncated SHA-256 of the encryption key, allowing operators to verify the correct key was used during restore.
- **Incremental efficiency** – Badger’s native incremental backup means each file contains only the delta since the previous snapshot, reducing I/O and storage overhead.

## Code Examples

### Starting a Backup Manually

To trigger a backup outside the periodic schedule (e.g., from a REPL or test):

```go
// Assume kvStore is a *kvstore.BadgerKVStore that was created earlier
if err := kvStore.Backup(); err != nil {
    log.Fatalf("Backup failed: %v", err)
}

```

### Restoring a Node from Backup

To reconstruct a database from the encrypted backup directory:

```go
executor := kvstore.NewBadgerBackupExecutor(
    "my-node",               // node ID
    nil,                     // no DB yet – will be created inside RestoreAllBackupsEncrypted
    []byte("my-secret-key"), // same backup encryption key
    "/var/mpcium/backups",   // directory containing backup-*.enc files
)

if err := executor.RestoreAllBackupsEncrypted("./restored-db", []byte("my-secret-key")); err != nil {
    log.Fatalf("Restore failed: %v", err)
}

```

## Summary

- **Automatic scheduling** – The `StartPeriodicBackup` function in [`cmd/mpcium/main.go`](https://github.com/fystack/mpcium/blob/main/cmd/mpcium/main.go) launches a background ticker that triggers backups at configurable intervals (default 5 minutes).
- **Incremental snapshots** – The `badgerBackupExecutor` in [`pkg/kvstore/badger_backup.go`](https://github.com/fystack/mpcium/blob/main/pkg/kvstore/badger_backup.go) uses Badger’s native `DB.Backup` to capture only changes since the last snapshot, skipping empty cycles.
- **AES-256-GCM encryption** – Every backup file is encrypted with the node’s Badger password, bundled with metadata (nonce, timestamps, version info), and written with a magic header for format verification.
- **Versioned file naming** – Backups follow the pattern `backup-<nodeID>-<timestamp>-<version>.enc`, with an internal `latest.version` tracking the logical offset (`Since`/`NextSince`).
- **Restore capability** – `RestoreAllBackupsEncrypted` scans, decrypts, and loads backup files in chronological order, reconstructing the database state after crashes or migrations.

## Frequently Asked Questions

### How often does mpcium create automatic backups?

By default, mpcium creates a backup every **300 seconds (5 minutes)**. You can adjust this interval via the `backup_period_seconds` configuration key. The ticker logic resides in [`cmd/mpcium/main.go`](https://github.com/fystack/mpcium/blob/main/cmd/mpcium/main.go), and the default value is defined in [`pkg/config/constants.go`](https://github.com/fystack/mpcium/blob/main/pkg/config/constants.go).

### What encryption algorithm protects the backup files?

Backup files are protected with **AES-256-GCM**. The encryption uses the same password configured for BadgerDB (`badger_password`). The implementation in [`pkg/kvstore/badger_backup.go`](https://github.com/fystack/mpcium/blob/main/pkg/kvstore/badger_backup.go) generates a random nonce for each backup, stores it in the JSON metadata, and appends the GCM authentication tag to the ciphertext to ensure integrity.

### Can I restore a node on a different machine using these backups?

Yes. To migrate or recover a node, copy the `backup-*.enc` files to the new host and invoke `RestoreAllBackupsEncrypted` from [`pkg/kvstore/badger_backup.go`](https://github.com/fystack/mpcium/blob/main/pkg/kvstore/badger_backup.go). You must provide the original `badger_password` used during backup creation. The restore process opens a fresh Badger instance and replays the incremental dumps in chronological order to reconstruct the key-share database.