Skip to main content
Restore a self-hosted MPC signer that was lost along with its key-share database, when point-in-time recovery (PITR) and database snapshots cannot bring the database back. You rebuild the signer and restore its key shares from the Layer 3 backup with signer-recover-tool. This applies to self-hosted deployments where you run the signer’s database and backup storage. On DFNS Cloud, DFNS handles recovery for you.

What Layer 3 is

Each time a signer creates a key share, it writes the same encrypted bytes to two places: its database and your Layer 3 backup, in an S3 bucket or an Azure Blob Storage container. The backup is an exact copy of the encrypted shares. Recovery copies those shares back into a fresh database. They stay encrypted throughout: the tool never decrypts, re-encrypts, or reassembles private keys, so no key material is ever exposed.
The backup holds the encrypted shares, not the key that decrypts them. That key is in the signer’s Core Keys Pack, stored separately from the database in your secret store (AWS Secrets Manager or Azure Key Vault).If the Core Keys Pack is also lost, restore it from its backup first. Without it the shares cannot be decrypted, and you must recover through Layer 4 instead.

Before you start

  • Signer version: signer-recover-tool ships with MPC signer 2.24.4 and later. It sits beside signer-migrate-tool in the standard signer container, the Nitro host bundle, and the Linux release archives.
  • Trusted backups only: point the tool only at your original Layer 3 backups. It cannot authenticate the ciphertext or check that it belongs to the selected signer.
  • One signer at a time: recover each signer’s backup prefix separately, with that signer’s own database login.
The tool restores the key_shares table only. It does not recover provision state, presignatures, core secrets, Layer 4 backups, or the informational key_shares_metadata table, which the signer does not read.

Recovery procedure

1

Confirm the Core Keys Pack is intact

The signer needs its Core Keys Pack to decrypt the restored shares. Confirm the secret still exists before you start.On AWS Secrets Manager:
On Azure Key Vault:
If it is present, continue. You do not need to open or export it, only confirm it exists.If it is gone, restore it from backup first. If you have no backup, use Layer 4 instead.
2

Redeploy the signer and prepare its database

Redeploy the missing signer using your normal MPC signer deployment process, on version 2.24.4 or later. Contact our if you need help with this step.
The new signer must reuse the original Core Keys Pack: point it at the same core-keys secret as before (Step 1), so it loads its original identity and keys instead of generating new ones. Keep the original Layer 3 backup settings too, including the same --l3-backup-prefix.
Prepare the database as for any new signer:
  1. Apply the database migrations with signer-migrate-tool.
  2. Provision the signer’s database role and grants as usual.
Keep the signer stopped until the restore is complete. The recovery tool checks the schema version and refuses to run against a database without the current migrations.
3

Grant temporary read access to the backup

The backup is write-only for the signer. Grant the identity that runs the recovery read access for the restore.On S3, the identity needs s3:ListBucket on the bucket and s3:GetObject on the backups:
If the bucket is encrypted with a KMS key, also grant kms:Decrypt on that key.On Azure Blob Storage, the identity needs the Storage Blob Data Reader role on the backup container. The tool authenticates with workload identity when AZURE_FEDERATED_TOKEN_FILE is set, and with managed identity otherwise, so run it from a pod or VM that has one of these identities:
4

Run a dry run

Run signer-recover-tool with --dry-run first. It downloads every selected backup, performs the inserts and conflict checks in one transaction, then rolls everything back.
Connect as the signer’s own database role, not an administrator. Each share is stored with owner = current_user and row-level security hides other owners’ rows, so restoring as any other role leaves the signer unable to see its shares.
Set --prefix to the exact prefix the signer wrote its backups with, its --l3-backup-prefix value. The tool strips the prefix from each object name to get the key ID: with prefix signer1/, object signer1/key-abc restores key ID key-abc. The prefix is not a glob. If your backups have no prefix, pass --prefix ''.From S3, run the tool as the signer container’s entrypoint, with POSTGRES_URL and the AWS credentials set in your environment:
From Azure Blob Storage, pass the container URL the signer was started with (its --l3-backup-azure-container-url), from a pod or VM whose identity has the role from Step 3:
Choose the database authentication that matches your deployment:
  • Password: put the password in POSTGRES_URL (or --url). This is the default.
  • AWS RDS IAM: add --rds-iam --aws-region <database-region>. Mount the RDS CA bundle and set sslrootcert in POSTGRES_URL. --s3-region is independent of the database region.
  • Microsoft Entra ID: add --entra-id, as in the Azure example above.
RDS IAM and Entra ID both force verified TLS. The dry run needs the same write permissions as a real run and holds the same locks.The tool ends with a summary such as Dry run rolled back: 1200 shares inserted, 0 identical shares already present. It never prints ciphertext or key material. Check that the inserted count matches the number of backups for this signer.
If the recovery host cannot reach the backup storage directly, copy the backups to a directory, keeping their original names, and run the tool with --directory <path> instead of the S3 or Azure flags. If the copy already stripped the prefix and the files are named by key ID, omit --prefix. The container runs as UID 65532, which must be able to read the mounted files.
5

Run the recovery

Run the same command without --dry-run to commit. The summary now starts with Recovery committed.The run is all or nothing. The tool downloads every backup before it writes anything, then inserts them in a single transaction. Any read, insert, or conflict failure rolls the whole run back and exits with a nonzero code. Shares already present with identical bytes are accepted, and a share with different bytes is an error and is never overwritten, so you can safely run the recovery again.
6

Remove the temporary read access

With the shares restored, remove the read access so the backup is write-only again.On S3:
On Azure Blob Storage:
7

Start the signer and confirm signing resumes

Start the signer. Confirm it signs with a test signature (see Validation). If signing does not resume, contact our .

Validation

  • Share count: the inserted count in the tool’s summary matches the number of backups under the signer’s prefix, and key_shares holds that many rows for the signer’s role:
  • Test signature: sign with a recovered key on a testnet and confirm it broadcasts. A recovered key controls the same address on every chain, so use a testnet so no real assets move.
Last modified on October 23, 2026