HiddenGit private Git · Tor v3 · SSH

Backup and recovery drill

A backup is useful only if it can be decrypted, verified, and restored while the recovery identity is still available. HiddenGit therefore separates the public age recipient from its offline secret identity and provides explicit preserve/rotate onion-identity modes.

1. Generate the recovery identity once

./run.sh backup-keygen

Move the generated .agekey file to offline/durable storage. Keep only the public age1... recipient in .env as BACKUP_RECIPIENT.

2. Stop for a consistent snapshot

./run.sh down

The stopped-state design intentionally trades availability for simple, reviewable consistency across Git repositories, SQLite state, SSH identities, and Tor identity.

3. Create and verify the encrypted backup

./run.sh backup
./run.sh verify-backup \
  backups/hidden-git-current-backup-YYYYmmddTHHMMSSZ.tar.age \
  /offline/backup-identity.agekey

Verification checks both the encrypted artifact checksum and the per-file manifest after decryption. It does not restore state.

4. Copy the archive off-host

Store the encrypted archive and checksum sidecar on independent storage. Keep the age secret identity separately; copying encrypted data and its only decryption key to the same failure domain defeats part of the recovery design.

5. Choose recovery identity semantics

preserve restores the prior Tor identity:

./run.sh restore <archive> /offline/backup-identity.agekey preserve

Use it when continuity of the onion hostname is required and the identity is not suspected compromised.

rotate restores application state but deliberately omits the Tor identity:

./run.sh restore <archive> /offline/backup-identity.agekey rotate

On next startup Tor creates a new onion hostname. Use it after identity compromise or when intentional service-address rotation is required.

6. Post-restore checks

./run.sh config check
./run.sh doctor --strict
./run.sh up
./run.sh status

Then verify:

Recovery failure rules