This Bash script automates the backup and restoration of vaults from 1Password using the 1Password CLI (v2+). It supports both service accounts (for automation) and personal accounts (via interactive signin).
Find a file
2025-05-20 14:28:35 +02:00
.gitignore Version 1.0.0 2025-05-20 14:27:21 +02:00
backup.sh Version 1.0.0 2025-05-20 14:27:21 +02:00
firma.env.template Version 1.0.0 2025-05-20 14:27:21 +02:00
README.md Version 1.0.0 2025-05-20 14:28:35 +02:00

1Password Vault Backup and Restore Script

This Bash script automates the backup and restoration of vaults from 1Password using the 1Password CLI (v2+). It supports both service accounts (for automation) and personal accounts (via interactive signin).


🔧 Requirements

  • op (1Password CLI v2.0 or newer)
  • jq
  • gpg (optional, for encrypted backups)
  • bash

🚀 Usage

Backup Mode

Service Account

./backup.sh --mode service path/to/config.env

Personal Account (interactive)

./backup.sh --mode personal path/to/config.env

Restore Mode

./backup.sh --mode [service|personal] restore "Vault Name" /path/to/backup [config.env]

Note: The same config.env is required in both modes to load VAULT list, BACKUP_BASE, RETENTION_DAYS, GPG_RECIPIENT, etc.


🔐 Configuration File (config.env)

Example:

# Vault prefix
VAULT_PREFIX="vault_"

VAULTS=(
    "Vault A"
    "Vault B"
)

BACKUP_BASE="/home/user/1password_backups"
RETENTION_DAYS=30
GPG_RECIPIENT="backup@example.com"

# Only needed for service account mode:
OP_SERVICE_ACCOUNT_TOKEN="ops_ey...."

📦 Backup Details

  • Each vault is backed up into:

    $BACKUP_BASE/<vault-name>/<YYYY-MM-DD>/
    
  • All items are stored as JSON.

  • All attachments are saved as:

    <sanitized-title>__<item-id>__<filename.ext>
    
  • If GPG_RECIPIENT is defined, a .tar.gz.gpg archive is created and the raw folder is deleted.


🔁 Restore Details

  • Skips items already present (based on item ID).

  • Recreates item using only title, category, and fields (compatible with 1Password CLI input format).

  • If attachments are present in the format:

    <title>__<item-id>__<filename.ext>
    

    they are reattached using op item file edit.

  • Remaining files (non-json, no ID) are added as documents.


📝 Logging

The script logs steps in this format:

[YYYY-MM-DD HH:MM:SS] Message

Example log output:

[2025-05-20 11:00:01] 🔐 Signing in with 1Password...
[2025-05-20 11:00:02] 📦 Backup for Vault: Vault A started
[2025-05-20 11:00:10] ✅ Backup completed: /home/user/1password_backups/Vault A/2025-05-20

🧪 Notes

  • The backup format is designed to work offline.
  • Only supported fields are restored.
  • Items are recreated using their title, category, and fields.
  • Other metadata (like creation date, tags) is not restored due to API limitations.

⚠️ Known Limitations

  • Duplicate entries (same title) are not detected, only item IDs are matched.
  • Personal vaults must be restored using --mode personal, not with a service account.
  • Only items with supported categories (e.g. LOGIN, PASSWORD, SECURE_NOTE, etc.) can be restored correctly.

📄 Example config.env

# Vault prefix
VAULT_PREFIX="vault_"

# List of vaults to back up
VAULTS=(
    "Team Vault"
    "HR Vault"
)

# Where backups are stored
BACKUP_BASE="/var/backups/1password"

# Retention in days before old backups are deleted
RETENTION_DAYS=30

# GPG recipient key for encryption (optional)
GPG_RECIPIENT="backup@example.com"

# Only needed for --mode service
OP_SERVICE_ACCOUNT_TOKEN="ops_ey...."

Example Cronjob

Run backup daily at 2 AM:

0 2 * * * /path/to/backup.sh --mode service /path/to/config.env >> /var/log/1password_backup.log 2>&1

Make sure the cron user has access to op, jq, and gpg in its PATH.


📋 Logging to File

To enable persistent logging, redirect output to a file:

./backup.sh --mode service config.env >> /var/log/1password_backup.log 2>&1

This will append both stdout and stderr to the log file.


🔑 Creating a GPG Key (Optional)

If you want encrypted backups, you'll need to generate a GPG key first.

1. Generate a new GPG key:

gpg --full-generate-key

Follow the prompts and choose RSA 4096 for maximum security. After creation, list your keys with:

gpg --list-keys

Copy the key's email or fingerprint and use it as GPG_RECIPIENT in your config.env.


📂 Decrypt and Extract Backup

If you have a .tar.gz.gpg backup, you can restore it manually as follows:

gpg --decrypt 2025-05-20.tar.gz.gpg > backup.tar.gz
tar -xzf backup.tar.gz

This will extract the plain folder with all item JSONs and files.


🛠 License

MIT License free for commercial and private use.