Proton Pass CLI
Manage Proton Pass vaults, items (logins, SSH keys, aliases, notes), passwords, SSH agent integration, and secret injection into applications. Use when working with Proton Pass for password management
Manage Proton Pass vaults, items (logins, SSH keys, aliases, notes), passwords, SSH agent integration, and secret injection into applications. Use when working with Proton Pass for password management
Real data. Real impact.
Emerging
Developers
Per week
Open source
Skills give you superpowers. Install in 30 seconds.
Comprehensive password and secret management via the Proton Pass CLI. Manage vaults, items, SSH keys, share credentials, inject secrets, and integrate with SSH workflows.
macOS/Linux:
curl -fsSL https://proton.me/download/pass-cli/install.sh | bash
Windows:
Invoke-WebRequest -Uri https://proton.me/download/pass-cli/install.ps1 -OutFile install.ps1; .\install.ps1
brew install protonpass/tap/pass-cli
Note: Package manager installations (Homebrew, etc.) do not support
pass-cli update command or track switching.
pass-cli --version
Default authentication method supporting all login flows (SSO, U2F):
pass-cli login # Open the URL displayed in your browser and complete authentication
Terminal-based authentication (supports password + TOTP, but not SSO or U2F):
pass-cli login --interactive user@proton.me
# Credentials as plain text (less secure) export PROTON_PASS_PASSWORD='your-password' export PROTON_PASS_TOTP='123456' export PROTON_PASS_EXTRA_PASSWORD='your-extra-password'Or from files (more secure)
export PROTON_PASS_PASSWORD_FILE='/secure/password.txt' export PROTON_PASS_TOTP_FILE='/secure/totp.txt' export PROTON_PASS_EXTRA_PASSWORD_FILE='/secure/extra-password.txt'
pass-cli login --interactive user@proton.me
pass-cli info # Show session info pass-cli test # Test connection
pass-cli logout # Normal logout pass-cli logout --force # Force local cleanup if remote fails
pass-cli vault list pass-cli vault list --output json
pass-cli vault create --name "Vault Name"
# By share ID pass-cli vault update --share-id "abc123def" --name "New Name"By name
pass-cli vault update --vault-name "Old Name" --name "New Name"
⚠️ Warning: Permanently deletes vault and all items.
# By share ID pass-cli vault delete --share-id "abc123def"By name
pass-cli vault delete --vault-name "Old Vault"
# Share with viewer access (default) pass-cli vault share --share-id "abc123def" colleague@company.comShare with specific role
pass-cli vault share --vault-name "Team Vault" colleague@company.com --role editor
Roles: viewer, editor, manager
# List members pass-cli vault member list --share-id "abc123def" pass-cli vault member list --vault-name "Team Vault" --output jsonUpdate member role
pass-cli vault member update --share-id "abc123def" --member-share-id "member123" --role editor
Remove member
pass-cli vault member remove --share-id "abc123def" --member-share-id "member123"
pass-cli vault transfer --share-id "abc123def" "member_share_id_xyz" pass-cli vault transfer --vault-name "My Vault" "member_share_id_xyz"
# List from specific vault pass-cli item list "Vault Name" pass-cli item list --share-id "abc123def"List with default vault (if configured)
pass-cli item list
# By IDs pass-cli item view --share-id "abc123def" --item-id "item456"By names
pass-cli item view --vault-name "MyVault" --item-title "MyItem"
Using Pass URI
pass-cli item view "pass://abc123def/item456" pass-cli item view "pass://MyVault/MyItem"
View specific field
pass-cli item view "pass://abc123def/item456/password" pass-cli item view --share-id "abc123def" --item-id "item456" --field "username"
Output format
pass-cli item view --share-id "abc123def" --item-id "item456" --output json
# Basic login pass-cli item create login \ --share-id "abc123def" \ --title "GitHub Account" \ --username "myuser" \ --password "mypassword" \ --url "https://github.com"With vault name
pass-cli item create login
--vault-name "Personal"
--title "Account"
--username "user"
--email "user@example.com"
--url "https://example.com"With generated password
pass-cli item create login
--share-id "abc123def"
--title "New Account"
--username "myuser"
--generate-password
--url "https://example.com"Custom password generation: "length,uppercase,symbols"
pass-cli item create login
--vault-name "Work"
--title "Secure Account"
--username "myuser"
--generate-password="20,true,true"
--url "https://example.com"Generate passphrase
pass-cli item create login
--share-id "abc123def"
--title "Account"
--username "user"
--generate-passphrase="5"
--url "https://example.com"
# Get template structure pass-cli item create login --get-template > template.jsonCreate from template
pass-cli item create login --from-template template.json --share-id "abc123def"
Create from stdin
echo '{"title":"Test","username":"user","password":"pass","urls":["https://test.com"]}' |
pass-cli item create login --share-id "abc123def" --from-template -
Template format:
{ "title": "Item Title", "username": "optional_username", "email": "optional_email@example.com", "password": "optional_password", "urls": ["https://example.com", "https://app.example.com"] }
# Generate Ed25519 key (recommended) pass-cli item create ssh-key generate \ --share-id "abc123def" \ --title "GitHub Deploy Key"Using vault name
pass-cli item create ssh-key generate
--vault-name "Development Keys"
--title "GitHub Deploy Key"Generate RSA 4096 key with comment
pass-cli item create ssh-key generate
--share-id "abc123def"
--title "Production Server"
--key-type rsa4096
--comment "prod-server-deploy"Key types: ed25519 (default), rsa2048, rsa4096
With passphrase protection
pass-cli item create ssh-key generate
--share-id "abc123def"
--title "Secure Key"
--passwordPassphrase from environment
PROTON_PASS_SSH_KEY_PASSWORD="my-passphrase"
pass-cli item create ssh-key generate
--share-id "abc123def"
--title "Automated Key"
--password
# Import unencrypted key pass-cli item create ssh-key import \ --from-private-key ~/.ssh/id_ed25519 \ --share-id "abc123def" \ --title "My SSH Key"Import with vault name
pass-cli item create ssh-key import
--from-private-key ~/.ssh/id_rsa
--vault-name "Personal Keys"
--title "Old RSA Key"Import passphrase-protected key (will prompt)
pass-cli item create ssh-key import
--from-private-key ~/.ssh/id_ed25519
--share-id "abc123def"
--title "Protected Key"
--passwordPassphrase from environment
PROTON_PASS_SSH_KEY_PASSWORD="my-key-passphrase"
pass-cli item create ssh-key import
--from-private-key ~/.ssh/id_ed25519
--share-id "abc123def"
--title "Automated Import"
--password
Recommendation: For importing passphrase-protected keys, consider removing the passphrase first since keys will be encrypted in your vault:
# Create unencrypted copy cp ~/.ssh/id_ed25519 /tmp/id_ed25519_temp ssh-keygen -p -f /tmp/id_ed25519_temp -N ""Import
pass-cli item create ssh-key import
--from-private-key /tmp/id_ed25519_temp
--share-id "abc123def"
--title "My SSH Key"Securely delete temp copy
shred -u /tmp/id_ed25519_temp # Linux rm -P /tmp/id_ed25519_temp # macOS
# Create alias pass-cli item alias create --share-id "abc123def" --prefix "newsletter" pass-cli item alias create --vault-name "Personal" --prefix "shopping"With JSON output
pass-cli item alias create --vault-name "Personal" --prefix "temp" --output json
# Update single field pass-cli item update \ --share-id "abc123def" \ --item-id "item456" \ --field "password=newpassword123"By vault name and item title
pass-cli item update
--vault-name "Personal"
--item-title "GitHub Account"
--field "password=newpassword123"Update multiple fields
pass-cli item update
--share-id "abc123def"
--item-id "item456"
--field "username=newusername"
--field "password=newpassword"
--field "email=newemail@example.com"Rename item
pass-cli item update
--vault-name "Work"
--item-title "Old Title"
--field "title=New Title"Create/update custom fields
pass-cli item update
--share-id "abc123def"
--item-id "item456"
--field "api_key=sk_live_abc123"
--field "environment=production"
Note: Item update does not support TOTP or time fields. Use another Proton Pass client for those.
⚠️ Warning: Permanent deletion.
pass-cli item delete --share-id "abc123def" --item-id "item456"
# Share with viewer access (default) pass-cli item share --share-id "abc123def" --item-id "item456" colleague@company.comShare with editor access
pass-cli item share --share-id "abc123def" --item-id "item456" colleague@company.com --role editor
# Generate all TOTPs for an item pass-cli item totp "pass://TOTP vault/WithTOTPs"Specific TOTP field
pass-cli item totp "pass://TOTP vault/WithTOTPs/TOTP 1"
JSON output
pass-cli item totp "pass://TOTP vault/WithTOTPs" --output json
Extract specific value
pass-cli item totp "pass://TOTP vault/WithTOTPs/TOTP 1" --output json | jq -r '.["TOTP 1"]'
# Random password (default settings) pass-cli password generate randomCustom random password
pass-cli password generate random --length 20 --numbers true --uppercase true --symbols true
Simple password without symbols
pass-cli password generate random --length 16 --symbols false
Generate passphrase
pass-cli password generate passphrase
Custom passphrase
pass-cli password generate passphrase --count 5 pass-cli password generate passphrase --count 4 --separator hyphens pass-cli password generate passphrase --count 4 --capitalize true --numbers true
# Score a password pass-cli password score "mypassword123"JSON output
pass-cli password score "MySecureP@ssw0rd*" --output json
Example JSON output:
{ "numeric_score": 51.666666666666664, "password_score": "Vulnerable", "penalties": [ "ContainsCommonPassword", "Consecutive" ] }
Load Proton Pass SSH keys into your existing SSH agent:
# Load all SSH keys pass-cli ssh-agent loadLoad from specific vault
pass-cli ssh-agent load --share-id MY_SHARE_ID pass-cli ssh-agent load --vault-name MySshKeysVault
Prerequisite: Ensure
SSH_AUTH_SOCK environment variable is defined.
Start Proton Pass CLI as a standalone SSH agent:
# Start agent pass-cli ssh-agent startFrom specific vault
pass-cli ssh-agent start --share-id MY_SHARE_ID pass-cli ssh-agent start --vault-name MySshKeysVault
Custom socket path
pass-cli ssh-agent start --socket-path /custom/path/agent.sock
Custom refresh interval (default 3600 seconds)
pass-cli ssh-agent start --refresh-interval 7200 # 2 hours
After starting, export the socket:
export SSH_AUTH_SOCK=/Users/youruser/.ssh/proton-pass-agent.sock
Automatically save SSH keys added via
ssh-add:
# Enable auto-creation pass-cli ssh-agent start --create-new-identities MySshKeysVaultIn another terminal
export SSH_AUTH_SOCK=$HOME/.ssh/proton-pass-agent.sock ssh-add ~/.ssh/my_new_key
Key is now automatically saved to Proton Pass!
Force password authentication:
ssh-copy-id -o PreferredAuthentications=password -o PubkeyAuthentication=no user@server
Reference secrets using the format:
pass://vault/item/field
pass://<vault-identifier>/<item-identifier>/<field-name>
# By names pass://Work/GitHub Account/password pass://Personal/Email Login/usernameBy IDs
pass://AbCdEf123456/XyZ789/password pass://ShareId123/ItemId456/api_key
Mixed (vault by name, item by ID)
pass://Work/XyZ789/password
Custom fields (case-sensitive)
pass://Work/API Keys/api_key pass://Production/Database/connection_string
username - Username/login namepassword - Passwordemail - Email addressurl - Website URLnote - Additional notestotp - TOTP secret (for 2FA)Invalid formats:
pass://vault/item # Missing field name pass://vault/item/ # Trailing slash pass://vault/ # Missing item and field
run)Execute commands with secrets from Proton Pass injected as environment variables.
Synopsis:
pass-cli run [--env-file FILE]... [--no-masking] -- COMMAND [ARGS...]
How it works:
.env filespass:// URIs in variable values--no-masking)Arguments:
--env-file FILE - Load environment variables from dotenv file (can specify multiple, processed in order)--no-masking - Disable automatic masking of secrets in outputCOMMAND [ARGS...] - Command to execute (must come after --)# Set secret reference in environment export DB_PASSWORD='pass://Production/Database/password'Run application with injected secret
pass-cli run -- ./my-app
Create
.env:
DB_HOST=localhost DB_PORT=5432 DB_USERNAME=admin DB_PASSWORD=pass://Production/Database/password API_KEY=pass://Work/External API/api_key
Run:
pass-cli run --env-file .env -- ./my-appMultiple env files (later override earlier)
pass-cli run
--env-file base.env
--env-file secrets.env
--env-file local.env
-- ./my-app
# Mix secrets with plain text DATABASE_URL="postgresql://user:pass://vault/db/password@localhost/db" API_ENDPOINT="https://api.example.com?key=pass://vault/api/key"
Default (masked):
pass-cli run -- ./my-app # If app logs: API_KEY: sk_live_abc123 # Output shows: API_KEY: <concealed by Proton Pass>
Unmasked:
pass-cli run --no-masking -- ./my-app
pass-cli run -- ./my-app --config production --verbose
#!/bin/bash # Load production secrets pass-cli run --env-file .env.production -- ./deploy.sh
inject)Process template files and replace secret references with actual values using handlebars-style syntax.
Synopsis:
pass-cli inject [--in-file FILE] [--out-file FILE] [--force] [--file-mode MODE]
How it works:
--in-file or stdin{{ pass://vault/item/field }} patterns--out-file or stdoutArguments:
--in-file, -i - Path to template file (or stdin)--out-file, -o - Path to write output (or stdout)--force, -f - Overwrite output file without prompting--file-mode - Set file permissions (Unix, default: 0600)Important: Use double braces
{{ }} (unlike run which uses bare pass://)
# config.yaml.template database: host: localhost username: {{ pass://Production/Database/username }} password: {{ pass://Production/Database/password }}api: key: {{ pass://Work/API Keys/api_key }} secret: {{ pass://Work/API Keys/secret }}
This comment with pass://fake/uri is ignored
Only {{ }} wrapped references are processed
pass-cli inject --in-file config.yaml.template
pass-cli inject \ --in-file config.yaml.template \ --out-file config.yamlOverwrite existing
pass-cli inject
--in-file config.yaml.template
--out-file config.yaml
--force
cat template.txt | pass-cli injectOr with heredoc
pass-cli inject << EOF { "database": { "password": "{{ pass://Production/Database/password }}" } } EOF
pass-cli inject \ --in-file template.txt \ --out-file config.txt \ --file-mode 0644
{ "database": { "host": "localhost", "password": "{{ pass://Production/Database/password }}" }, "api": { "key": "{{ pass://Work/API/key }}" } }
Configure persistent preferences:
pass-cli settings view
# By name pass-cli settings set default-vault --vault-name "Personal Vault"By share ID
pass-cli settings set default-vault --share-id "3GqM1RhVZL8uXR_abc123"
Affected commands:
item list, item view, item totp, item create, item update, etc.
pass-cli settings set default-format human pass-cli settings set default-format json
Affected commands:
item list, item view, item totp, vault list, etc.
pass-cli settings unset default-vault pass-cli settings unset default-format
pass-cli share list pass-cli share list --output json
Shows all resources (vaults and items) shared with you and your role.
pass-cli invite list pass-cli invite list --output json
pass-cli invite accept --invite-token "abc123def456"
pass-cli invite reject --invite-token "abc123def456"
pass-cli info
Shows: Release track, User ID, Username, Email.
pass-cli user info pass-cli user info --output json
Shows: Account details, subscription, storage usage.
pass-cli test
Verifies session validity and API connectivity.
Note: Only for manual installations (not package managers).
pass-cli update pass-cli update --yes # Skip confirmation
# Switch to beta pass-cli update --set-track beta pass-cli updateSwitch back to stable
pass-cli update --set-track stable pass-cli update
export PROTON_PASS_NO_UPDATE_CHECK=1
A Share represents the relationship between a user and a resource (vault or item). Defines access and permissions.
A container that organizes items. Items exist in exactly one vault.
Note: Items are identified by Item ID, but this ID is only unique when combined with Share ID (ShareID + ItemID = globally unique).
pass-cli logout in automation cleanupRunning in Docker containers requires filesystem key storage (keyring unavailable):
# 1. Ensure logged out pass-cli logout --force2. Set filesystem key provider
export PROTON_PASS_KEY_PROVIDER=fs
3. Login as normal
pass-cli login
Why filesystem storage?
⚠️ Security note: Key stored side-by-side with encrypted data. Secure your container environment.
# Check session status pass-cli info pass-cli testRe-authenticate
pass-cli logout pass-cli login
pass-cli testpass-cli share listpass-cli invite list"Invalid reference format":
pass://vault/item/field"Secret reference requires a field name":
pass://vault/item/field (not pass://vault/item)"Field not found":
pass-cli item view --share-id <id> --item-id <id>Reference not found:
pass-cli vault listpass-cli item list --share-id <id>pass-cli item view <uri># Levels: trace, debug, info, warn, error, off export PASS_LOG_LEVEL=debug
Note: Logs are sent to
stderr (won't interfere with piping/command integration).
Default locations:
~/Library/Application Support/proton-pass-cli/.session/~/.local/share/proton-pass-cli/.session/Override:
export PROTON_PASS_SESSION_DIR='/custom/path'
Control how encryption keys are stored with
PROTON_PASS_KEY_PROVIDER:
export PROTON_PASS_KEY_PROVIDER=keyring # or unset
Uses OS secure storage:
How it works:
Linux note: Uses kernel keyring (no D-Bus required), works in headless environments. Secrets cleared on reboot.
Docker limitation: Containers cannot access kernel secret service. Use filesystem storage instead.
⚠️ Warning: Less secure - key stored side-by-side with encrypted data.
export PROTON_PASS_KEY_PROVIDER=fs
Stores key in
<session-dir>/local.key with permissions 0600.
Advantages:
When to use:
⚠️ Warning: Key visible to other processes in same session.
export PROTON_PASS_KEY_PROVIDER=env export PROTON_PASS_ENCRYPTION_KEY=your-secret-key
Derives encryption key from
PROTON_PASS_ENCRYPTION_KEY (must be set and non-empty).
Generate safe key:
dd if=/dev/urandom bs=1 count=2048 2>/dev/null | sha256sum | awk '{print $1}'
Advantages:
When to use:
Disable telemetry:
export PROTON_PASS_DISABLE_TELEMETRY=1
Or globally: Account security settings → Disable "Collect usage diagnostics"
What's sent: Anonymized usage data (e.g., "item created of type note") - never personal/sensitive data.
export PROTON_PASS_PASSWORD='password' export PROTON_PASS_PASSWORD_FILE='/path/to/file' export PROTON_PASS_TOTP='123456' export PROTON_PASS_TOTP_FILE='/path/to/file' export PROTON_PASS_EXTRA_PASSWORD='extra-password' export PROTON_PASS_EXTRA_PASSWORD_FILE='/path/to/file'
export PROTON_PASS_SSH_KEY_PASSWORD='passphrase' export PROTON_PASS_SSH_KEY_PASSWORD_FILE='/path/to/file'
export PROTON_PASS_NO_UPDATE_CHECK=1
export PROTON_PASS_CLI_INSTALL_DIR=/custom/path export PROTON_PASS_CLI_INSTALL_CHANNEL=beta
# Create vault pass-cli vault create --name "Project Alpha"List to get share ID
pass-cli vault list
Create login items
pass-cli item create login
--share-id "new_vault_id"
--title "API Key"
--username "api_user"
--generate-password
--url "https://api.example.com"Share with team
pass-cli vault share --share-id "new_vault_id" alice@team.com --role editor
# Import existing key pass-cli item create ssh-key import \ --from-private-key ~/.ssh/id_ed25519 \ --vault-name "SSH Keys" \ --title "GitHub Key"Load into SSH agent
pass-cli ssh-agent load --vault-name "SSH Keys"
Or start Pass as SSH agent
pass-cli ssh-agent start --vault-name "SSH Keys" export SSH_AUTH_SOCK=$HOME/.ssh/proton-pass-agent.sock
#!/bin/bash # Automated login export PROTON_PASS_PASSWORD_FILE="$HOME/.secrets/pass-password" pass-cli login --interactive user@proton.meRetrieve secret
DB_PASSWORD=$(pass-cli item view "pass://Production/Database/password" --output json | jq -r '.password')
Use secret
connect-to-db --password "$DB_PASSWORD"
Cleanup
pass-cli logout
#!/bin/bash # Create .env.production with secret references cat > .env.production << EOF NODE_ENV=production DATABASE_URL=pass://Production/Database/connection_string API_KEY=pass://Production/API/key STRIPE_SECRET=pass://Production/Stripe/secret_key EOFDeploy application with secrets injected
pass-cli run --env-file .env.production -- npm start
Or generate config file from template
pass-cli inject
--in-file config.yaml.template
--out-file config.yaml
--forceThen run app with generated config
./app --config config.yaml
#!/bin/bash # Login with environment variable key storage export PROTON_PASS_KEY_PROVIDER=env export PROTON_PASS_ENCRYPTION_KEY="${CI_PASS_ENCRYPTION_KEY}" export PROTON_PASS_PASSWORD_FILE=/run/secrets/pass-passwordpass-cli login --interactive user@proton.me
Run tests with secrets
pass-cli run --env-file .env.test -- npm test
Deploy with secrets
pass-cli run --env-file .env.production -- ./deploy.sh
Cleanup
pass-cli logout
--refresh-intervalPROTON_PASS_KEY_PROVIDER=fs)run command outputinject requires {{ }} braces, run uses bare pass:// URIsAuthentication:
login, logout, info, testVault:
vault list, vault create, vault update, vault delete, vault share, vault member, vault transferItem:
item list, item view, item create, item update, item delete, item share, item totp, item alias, item attachmentSecret Injection:
run - Execute commands with secrets injected as environment variablesinject - Process template files with secret referencesPassword:
password generate, password scoreSSH:
ssh-agent load, ssh-agent startSettings:
settings view, settings set, settings unsetShare & Invite:
share list, invite list, invite accept, invite rejectUser:
user infoUpdate:
updateNo automatic installation available. Please visit the source repository for installation instructions.
View Installation Instructions1,500+ AI skills, agents & workflows. Install in 30 seconds. Part of the Torly.ai family.
© 2026 Torly.ai. All rights reserved.