pass-ssh-unpack
[!IMPORTANT] This tool is still in the PROTOTYPE phase. Expect breaking changes. It is not recommended for use in production environments.
A utility for unpacking proton's pass-cli ssh keys into usable ssh and rclone configurations.
Features
- Cross-platform: Works on Linux, macOS, and Windows
- Automatic SSH config generation: Creates host entries with aliases
- Machine-specific keys: Filter keys by hostname suffix (e.g.,
github/my-laptop) - Incremental updates: Only processes changed items by default
- Rclone integration: Automatically creates SFTP remotes for each SSH host
- Wildcard filtering: Filter vaults and items using glob patterns
- Progress indicators: Visual feedback with spinners and progress bars
- Encrypted rclone config: Supports encrypted rclone configs with password from Proton Pass
Requirements
- Proton Pass CLI (
pass-cli) - OpenSSH (
ssh-keygen) - rclone (optional, for SFTP remote sync)
Installation
From crates.io
From source
Clone Repository
# Binary will be at ./target/release/pass-ssh-unpack
Add to PATH
# Linux/macOS
# Or symlink
Usage
# Generates SSH key files, config, and rclone remotes from all vaults
# ..from specific vault(s)
# ..for specific items
# Full regeneration (clear and rebuild)
# Only process SSH keys (skip rclone)
# Only process rclone remotes (skip SSH)
# Remove all managed SSH key files, config, and rclone remotes
# Quiet mode (suppress output)
# Dry run (show what would be done)
CLI Options
CLI options override corresponding config file settings.
| Option | Short | Description |
|---|---|---|
--vault <PATTERN> |
-v |
Vault(s) to process (repeatable, supports wildcards) |
--item <PATTERN> |
-i |
Item title pattern(s) (repeatable, supports wildcards) |
--full |
-f |
Full regeneration (clear config first) |
--dry-run |
Show what would be done without making changes | |
--quiet |
-q |
Suppress output |
--ssh |
Only process SSH keys (skip rclone sync) | |
--rclone |
Only process rclone remotes (skip SSH extraction) | |
--purge |
Remove all managed SSH keys and rclone remotes | |
--config <PATH> |
-c |
Custom config file path |
--output-dir <PATH> |
-o |
Override SSH output directory |
--sync-public-key <MODE> |
Override public key sync mode (never/if-empty/always) | |
--rclone-password-path <PATH> |
Override rclone password path in Proton Pass | |
--always-encrypt |
Force rclone config encryption after operations | |
--help |
-h |
Show help |
--version |
-V |
Show version |
Configuration
On first run, a default config file is created at ~/.config/pass-ssh-unpack/config.toml:
# pass-ssh-unpack configuration file
# This file is auto-generated on first run. All fields are optional.
# Directory where SSH keys and config are written
# Supports ~ for home directory
# Default: ~/.ssh/proton-pass
= "~/.ssh/proton-pass"
# Default vault filter(s) - applied when no --vault flag is given
# Supports wildcards: "Personal", "Work*", etc.
# Default: [] (all vaults)
= []
# Default item filter(s) - applied when no --item flag is given
# Supports wildcards: "github/*", "*-prod", etc.
# Default: [] (all items)
= []
# When to sync generated public keys back to Proton Pass
# Options: "never", "if_empty" (default), "always"
# never - Never update public keys in Proton Pass
# if_empty - Only update if the public key field is empty (default)
# always - Always overwrite the public key in Proton Pass
= "if_empty"
[]
# Enable rclone SFTP remote sync
# Default: true
= true
# Path in Proton Pass to rclone config password (if encrypted)
# This is optional if RCLONE_CONFIG_PASS is already set in your environment.
# If both are set, this value takes precedence.
# Leave empty to rely on environment variable or unencrypted config.
# Example: "pass://Personal/rclone/password"
# Default: ""
= ""
# Always ensure rclone config is encrypted after operations
# If true and a password is available (via password_path or RCLONE_CONFIG_PASS),
# the rclone config will be re-encrypted even if it wasn't encrypted before.
# Default: false
= false
Proton Pass Item Structure
SSH key items in Proton Pass should have the following fields:
| Field | Required | Description |
|---|---|---|
| Title | Yes | Item name. Use title/hostname format for machine-specific keys |
| Private Key | Yes | The private key |
| Host | Yes | The SSH host (IP or hostname) |
| Username | No | SSH username |
| Aliases | No | Comma-separated host aliases |
| Jump | No | Jump host for SSH config (ProxyJump directive) |
| SSH | No | Custom SSH binary/command for rclone (ssh option) |
| Server Command | No | SFTP server command for rclone (server_command option) |
Jump Hosts and Custom SSH Commands
Jump is used for SSH config's ProxyJump directive - specify just the jump host:
- Example:
Jump = bastion.example.com - Generated SSH config:
ProxyJump bastion.example.com - This field only affects SSH config, not rclone.
SSH is used for rclone's ssh option - specify the full SSH command:
- Example:
SSH = tsh ssh --proxy=example.com --user=username(for Teleport) - Example:
SSH = ssh -J bastion.example.com(for jump host support in rclone) - Generated rclone config:
ssh = tsh ssh --proxy=example.com --user=username - This field only affects rclone, not SSH config.
Server Command is used for rclone's server_command option - specify the SFTP server path:
- Example:
Server Command = /usr/lib/openssh/sftp-server - Generated rclone config:
server_command = /usr/lib/openssh/sftp-server - This is useful when using custom SSH commands that don't support the SFTP subsystem.
Note: These fields are independent. Use Jump for standard SSH jump hosts, SSH when rclone needs a custom SSH binary or options, and Server Command when rclone needs to explicitly invoke the SFTP server.
Machine-Specific Keys
If an item title contains a /, the part after the last / is treated as a hostname filter. The key will only be extracted on machines with a matching hostname (case-insensitive).
Examples:
github/my-laptop- Only extracted on machine with hostnamemy-laptopwork-server- Extracted on all machines
macOS Hostname Detection
On macOS, the tool uses the LocalHostName (Bonjour name) rather than the dynamic DHCP hostname, which can change based on network configuration. This provides stable machine identification.
To check your LocalHostName:
To set it (if needed):
On Linux and Windows, the system hostname is used directly.
How It Works
- Authenticate: Checks that you're logged into Proton Pass CLI
- Extract keys: For each SSH key item:
- Writes private key to
~/.ssh/proton-pass/<vault>/<item> - Generates public key using
ssh-keygen - Saves public key back to Proton Pass if missing and
sync-public-keyis enabled
- Writes private key to
- Generate SSH config: Creates
~/.ssh/proton-pass/config(or at your configuredssh_output_dir) with host entries that you can include in your own ssh config file. - Sync rclone remotes: Syncs SFTP remotes named after the first alias
SSH Config Integration
Add this line to your ~/.ssh/config:
Include ~/.ssh/proton-pass/config
Note: If you used a custom ssh_output_dir, include config from there.
License
MIT License - see LICENSE for details.