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.Before you start
- Signer version:
signer-recover-toolships with MPC signer 2.24.4 and later. It sits besidesigner-migrate-toolin 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.
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.Prepare the database as for any new signer:
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.- Apply the database migrations with
signer-migrate-tool. - Provision the signer’s database role and grants as usual.
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 If the bucket is encrypted with a KMS key, also grant
s3:ListBucket on the bucket and s3:GetObject on the backups: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 From Azure Blob Storage, pass the container URL the signer was started with (its Choose the database authentication that matches your deployment:
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.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:--l3-backup-azure-container-url), from a pod or VM whose identity has the role from Step 3:- 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 setsslrootcertinPOSTGRES_URL.--s3-regionis independent of the database region. - Microsoft Entra ID: add
--entra-id, as in the Azure example above.
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_sharesholds 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.