gopass Basics

Essential gopass operations - show, list, find, copy.

Basic Operations

# Show entry (full content)
gopass show path/to/entry

# Show password only (-o = only first line)
gopass show -o path/to/entry

# Copy password to clipboard (45s timeout)
gopass -c path/to/entry

# Copy specific field
gopass show -c path/to/entry username

# List all entries
gopass ls

# List specific path
gopass ls v3/domains/

# Flat list (no tree structure)
gopass ls -f

# Edit entry in $EDITOR
gopass edit path/to/entry

# Sync with git remote
gopass sync

# Force sync (overwrite local)
gopass sync --force

Searching

# Search entry names
gopass find vault
gopass find ise

# Search content (decrypts all entries - slow!)
gopass grep admin

# Case-insensitive search
gopass grep -i PASSWORD

# Fuzzy find with fzf (if installed)
gopass show $(gopass ls -f | fzf)

# Search and copy
gopass show -c $(gopass find vault | fzf)

Password Generation

# Generate and store new password (24 chars)
gopass generate path/to/new 24

# Generate with symbols
gopass generate -s path/to/new 24

# Generate without symbols (alphanumeric only)
gopass generate -n path/to/new 24

# Generate and copy to clipboard
gopass generate -c path/to/new 24

# Generate without storing (just print)
gopass generate --print 32

# Generate for existing entry (overwrites password only)
gopass generate -f path/to/existing 24

# Generate strict (no ambiguous chars like 0/O, 1/l)
gopass generate --strict path/to/new 24

# Custom character set
gopass generate path/to/new 16 -- 'abcdef0123456789'

GOTCHA: generate without -f fails if entry exists. Use -f to overwrite password only.

Create and Delete

# Create new entry (interactive)
gopass insert path/to/new

# Create with multiline content
gopass insert -m path/to/new

# Create from stdin (non-interactive)
echo "mypassword" | gopass insert -f path/to/new

# Create with heredoc (structured)
cat << 'EOF' | gopass insert -f -m v3/servers/myserver
secretpassword123
---
type: linux
connection:
  host: myserver.example.com
  port: 22
credentials:
  username: admin
EOF

# Move entry
gopass mv old/path new/path

# Copy entry (duplicate)
gopass cp source/path dest/path

# Delete entry
gopass rm path/to/entry

# Delete without confirmation
gopass rm -f path/to/entry

# Delete recursively (DANGEROUS)
gopass rm -r path/to/directory

Recipients (Who Can Decrypt)

# List recipients for a store
gopass recipients

# List recipients for specific store
gopass recipients --store v3

# Add recipient (GPG key ID)
gopass recipients add KEYID

# Add by email
gopass recipients add user@example.com

# Remove recipient
gopass recipients remove KEYID

# Re-encrypt all entries for new recipient list
gopass sync
# (sync automatically re-encrypts when recipients change)

KEY CONCEPT: Recipients are stored in .gpg-id file in store root. Adding/removing re-encrypts ALL entries in that store.

Configuration

# Show all config
gopass config

# Get specific setting
gopass config core.autosync

# Set config value
gopass config core.autosync true

# Common settings
gopass config core.cliptimeout 45      # Clipboard clear timeout
gopass config core.autosync true       # Auto git sync
gopass config core.autoclip false      # Don't auto-copy password
gopass config core.showsafecontent true # Hide secrets in output

# Config file locations
cat ~/.config/gopass/config
cat ~/.config/gopass/stores/v3/config

YubiKey / Hardware Key Integration

# Check if YubiKey is detected
gpg --card-status

# List GPG keys (should show key on card)
gpg -K

# Typical setup: GPG subkeys on YubiKey
# - Signing key
# - Encryption key
# - Authentication key

# Test decryption works
gopass show v3/test/entry

# If YubiKey not detected
gpgconf --kill gpg-agent
gpg --card-status

# Force agent restart
gpg-connect-agent reloadagent /bye

# Common issue: udev rules
# Check /etc/udev/rules.d/70-yubikey.rules exists

WORKFLOW: Insert YubiKey → Touch → gopass decrypts

v3/
├── domains/
│   └── d000/                     # Domain identifier
│       ├── infrastructure/
│       │   ├── vault-01
│       │   ├── ise-01
│       │   └── pfsense-01
│       ├── services/
│       │   ├── keycloak
│       │   └── gitea
│       └── endpoints/
│           ├── razer
│           └── aw
├── personal/
│   ├── social/
│   │   ├── github/username
│   │   └── gitlab/username
│   ├── financial/
│   │   └── bank/account
│   └── cloud/
│       ├── aws/
│       └── cloudflare/
└── work/
    └── chla/
        └── accounts/

PATTERN: <scope>/<category>/<service>/<account>

Environment Variables (dsec Pattern)

# Export secrets as environment variables
eval "$(gopass show v3/domains/d000/dev/network.env)"

# dsec wrapper (user's custom tool)
dsec source d000 dev/network      # Loads network.env
dsec source d000 dev/observability # Loads observability.env

# Store .env format
gopass show v3/domains/d000/dev/network.env
# Output:
# export ISE_HOST="ise-01.inside.domusdigitalis.dev"
# export ISE_USER="admin"
# export ISE_PASS="secretpassword"

# Create .env entry
cat << 'EOF' | gopass insert -f -m v3/domains/d000/dev/network.env
export ISE_HOST="ise-01.inside.domusdigitalis.dev"
export ISE_USER="admin"
export ISE_PASS="secretpassword"
export VAULT_ADDR="https://vault-01.inside.domusdigitalis.dev:8200"
export VAULT_TOKEN="hvs.xxxxxxxxxxxxxxxx"
EOF

PATTERN: First line is NOT a password when storing env format. Just use gopass show …​ | source /dev/stdin or eval.

Extensions and Integrations

# gopass-jsonapi (browser integration)
# Enables Firefox/Chrome extension to query gopass

# Install on Arch
sudo pacman -S gopass-jsonapi

# Configure browser
gopass-jsonapi configure

# Verify setup
gopass-jsonapi status

# gopass-summon-provider (HashiCorp Summon)
# For CI/CD secret injection

# gopass-hibp (Have I Been Pwned)
# Check if passwords are compromised
gopass hibp path/to/entry

# Check all entries (slow)
gopass audit hibp

Troubleshooting

# Decryption fails
gpg --card-status        # YubiKey connected?
gpgconf --kill gpg-agent # Restart agent
gpg --list-secret-keys   # Keys available?

# Sync fails
gopass git status
gopass git pull
gopass git push

# Entry not found
gopass ls -f | grep -i keyword
gopass mounts            # Check mount points

# Recipients issue
gopass recipients        # Who can decrypt?
gpg --list-keys KEYID    # Is key valid?
gpg --recv-keys KEYID    # Fetch missing key

# Re-encrypt everything (after adding recipient)
gopass init --path . KEYID1 KEYID2

# Check store health
gopass fsck

# Debug mode
GOPASS_DEBUG=true gopass show path

# Clear caches
gopass config core.exportkeys false

Quick Reference Patterns

# Copy password to clipboard
gopass -c v3/path/entry

# Get password for script
PASS=$(gopass show -o v3/path/entry)

# Get specific field
USER=$(gopass show v3/path/entry | grep username | cut -d: -f2 | tr -d ' ')

# With yq (if YAML after first line)
USER=$(gopass show v3/path/entry | tail -n+2 | yq '.credentials.username')

# Generate and copy
gopass generate -c v3/new/entry 24

# Quick store test
gopass show v3/test/entry && echo "Store works"

# Find and open
gopass edit $(gopass find keyword | head -1)

# Sync all stores
gopass sync

# Backup store
tar czf gopass-backup-$(date +%Y%m%d).tar.gz ~/.local/share/gopass/stores/

Security Best Practices

# Use hardware key (YubiKey)
# - Private key never leaves device
# - Requires physical touch for decrypt

# Clipboard timeout
gopass config core.cliptimeout 30  # 30 seconds

# Audit passwords
gopass audit

# Check for weak passwords
gopass audit --passwords

# Check for duplicate passwords
gopass audit --duplicates

# Check against HIBP (breach database)
gopass audit --hibp

# Safe screen viewing (masks secrets)
gopass config core.showsafecontent true
gopass show path  # Shows "***" for password

# Store permissions
ls -la ~/.local/share/gopass/stores/
# Should be: drwx------ (700)

# GPG agent timeout
echo "default-cache-ttl 600" >> ~/.gnupg/gpg-agent.conf
echo "max-cache-ttl 7200" >> ~/.gnupg/gpg-agent.conf
gpgconf --kill gpg-agent

CRITICAL: Never commit plaintext passwords to git. gopass encrypts before commit.