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.com
# Share 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 json
# Update 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.json
# Create 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" \
--password
# Passphrase 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" \
--password
# Passphrase 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.com
# Share 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 random
# Custom 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 load
# Load 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 start
# From 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 MySshKeysVault
# In 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/username
# By 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-app
# Multiple 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.yaml
# Overwrite existing
pass-cli inject \
--in-file config.yaml.template \
--out-file config.yaml \
--force
cat template.txt | pass-cli inject
# Or 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 update
# Switch 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 --force
# 2. 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 test
# Re-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 --item-id Reference not found:
pass-cli vault listpass-cli item list --share-id pass-cli item view # 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 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.me
# Retrieve 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
EOF
# Deploy 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 \
--force
# Then 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-password
pass-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:
update共 1 个版本