Add op-backup mise task for encrypted 1Password disaster recovery #136

Merged
eblume merged 2 commits from feature/op-backup into main 2026-02-09 20:37:40 -08:00
Owner

Summary

  • Adds mise run op-backup task that encrypts a 1Password .1pux export with age using the master password + secret key as passphrase, SCPs to indri for borgmatic pickup, then deletes the plaintext
  • Adds age to the Brewfile
  • Borgmatic already backs up /Users/erichblume/Documents on indri, which covers the 1password-backup/ subdirectory — no config change needed

Disaster recovery

  1. Restore borgmatic archive to retrieve the .age file
  2. Open Emergency Kit from safety deposit box
  3. age --decrypt <file>.age > export.1pux (passphrase: {master_password}:{secret_key})
  4. Open .1pux with 1Password or unzip to inspect

Usage

# Export all vaults from 1Password desktop app as .1pux, then:
mise run op-backup ~/Documents/1Password-export.1pux

# Or run without args for interactive prompt:
mise run op-backup

Test plan

  • brew install age
  • Export a test vault from 1Password as .1pux
  • Run mise run op-backup with the export path
  • Verify encrypted file appears on indri at ~/Documents/1password-backup/
  • Verify plaintext .1pux is deleted from gilbert
  • Test decryption: age --decrypt <file>.age > test.1pux with password:secret_key
  • Verify decrypted .1pux can be opened/unzipped

🤖 Generated with Claude Code

## Summary - Adds `mise run op-backup` task that encrypts a 1Password .1pux export with `age` using the master password + secret key as passphrase, SCPs to indri for borgmatic pickup, then deletes the plaintext - Adds `age` to the Brewfile - Borgmatic already backs up `/Users/erichblume/Documents` on indri, which covers the `1password-backup/` subdirectory — no config change needed ## Disaster recovery 1. Restore borgmatic archive to retrieve the `.age` file 2. Open Emergency Kit from safety deposit box 3. `age --decrypt <file>.age > export.1pux` (passphrase: `{master_password}:{secret_key}`) 4. Open `.1pux` with 1Password or unzip to inspect ## Usage ``` # Export all vaults from 1Password desktop app as .1pux, then: mise run op-backup ~/Documents/1Password-export.1pux # Or run without args for interactive prompt: mise run op-backup ``` ## Test plan - [ ] `brew install age` - [ ] Export a test vault from 1Password as .1pux - [ ] Run `mise run op-backup` with the export path - [ ] Verify encrypted file appears on indri at `~/Documents/1password-backup/` - [ ] Verify plaintext .1pux is deleted from gilbert - [ ] Test decryption: `age --decrypt <file>.age > test.1pux` with password:secret_key - [ ] Verify decrypted .1pux can be opened/unzipped 🤖 Generated with [Claude Code](https://claude.com/claude-code)
Encrypts a .1pux export from the 1Password desktop app with age using the
master password + secret key as the passphrase, then SCPs to indri where
borgmatic picks it up. Provides double encryption (age + borg repokey) and
recovery requires only the Emergency Kit from the safety deposit box.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace the pty-based age passphrase approach (which hung in non-tty
contexts) with a two-layer scheme: age-keygen generates a fresh key pair,
age encrypts the .1pux with the public key (non-interactive), then openssl
encrypts the age private key with the 1Password credentials passed via
fd (never exposed in env vars or ps output).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
eblume merged commit a5765f9cf2 into main 2026-02-09 20:37:40 -08:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
eblume/blumeops!136
No description provided.