gopass Insert

Adding, editing, and generating secrets.

Basic Insert Operations

# Interactive insert (prompts for password)
gopass insert path/to/entry

# Multiline insert (opens editor)
gopass insert -m path/to/entry

# Force overwrite existing
gopass insert -f path/to/entry

# Insert from stdin
echo "mypassword" | gopass insert -f path/to/entry

# Insert from file
cat password.txt | gopass insert -f path/to/entry

# Multiline from stdin
cat << 'EOF' | gopass insert -f -m path/to/entry
password123
additional: content
EOF

KEY: First line is ALWAYS the password. Everything after is metadata.

Entry Structure Convention

<password>
---
type: <entry-type>
connection:
  host: <hostname-or-ip>
  port: <port>
credentials:
  username: <username>
meta:
  created: <date>
  modified: <date>
  notes: <optional-notes>

CONVENTION: YAML after --- separator. Not enforced but makes parsing easy.

Infrastructure Entry Templates

# Linux Server
cat << 'EOF' | gopass insert -f -m v3/domains/d000/infrastructure/vault-01
GENERATED_PASSWORD_HERE
---
type: linux
connection:
  host: vault-01.inside.domusdigitalis.dev
  ip: 10.50.1.60
  port: 22
credentials:
  username: admin
  method: ssh-key
meta:
  os: Rocky Linux 9
  role: Vault PKI + SSH CA
  created: 2026-02-01
EOF

# Network Device
cat << 'EOF' | gopass insert -f -m v3/domains/d000/infrastructure/pfsense-01
ADMIN_PASSWORD_HERE
---
type: firewall
connection:
  host: pfsense-01.inside.domusdigitalis.dev
  ip: 10.50.1.1
  port: 443
  protocol: https
credentials:
  username: admin
meta:
  vendor: Netgate
  model: pfSense 2.7
  role: Primary firewall/router
  created: 2026-02-01
EOF

# Cisco ISE
cat << 'EOF' | gopass insert -f -m v3/domains/d000/infrastructure/ise-01
ISE_ADMIN_PASSWORD
---
type: ise
connection:
  host: ise-01.inside.domusdigitalis.dev
  ip: 10.50.1.20
  ports:
    admin: 443
    ers: 9060
    mnt: 443
credentials:
  username: admin
  ers_enabled: true
api:
  ers_base: https://ise-01.inside.domusdigitalis.dev:9060/ers/config
  openapi_base: https://ise-01.inside.domusdigitalis.dev/api/v1
meta:
  version: "3.4"
  roles: PAN,MnT,PSN
  created: 2026-02-01
EOF

Service Account Templates

# Database
cat << 'EOF' | gopass insert -f -m v3/domains/d000/services/postgres-app
DB_PASSWORD_HERE
---
type: database
connection:
  host: postgres.inside.domusdigitalis.dev
  port: 5432
  database: myapp
credentials:
  username: app_user
  role: readwrite
meta:
  engine: PostgreSQL 16
  created: 2026-02-01
EOF

# API Token
cat << 'EOF' | gopass insert -f -m v3/domains/d000/services/vault-token
hvs.VAULT_TOKEN_HERE
---
type: api-token
connection:
  host: vault-01.inside.domusdigitalis.dev
  port: 8200
credentials:
  token_type: service
  policies:
    - pki-issuer
    - kv-reader
meta:
  ttl: 768h
  renewable: true
  created: 2026-02-01
EOF

# Keycloak Client
cat << 'EOF' | gopass insert -f -m v3/domains/d000/services/keycloak-ise-client
CLIENT_SECRET_HERE
---
type: oidc-client
connection:
  host: keycloak-01.inside.domusdigitalis.dev
  port: 443
  realm: domus
credentials:
  client_id: ise-admin
  grant_types:
    - client_credentials
    - authorization_code
meta:
  purpose: ISE SAML/OIDC integration
  created: 2026-02-01
EOF

Environment File Pattern

# For dsec/source pattern - exportable env vars
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="ise_password_here"
export PFSENSE_HOST="pfsense-01.inside.domusdigitalis.dev"
export PFSENSE_USER="admin"
export PFSENSE_PASS="pfsense_password_here"
export WLC_HOST="9800-wlc-01.inside.domusdigitalis.dev"
export WLC_USER="admin"
export WLC_PASS="wlc_password_here"
EOF

# Observability env
cat << 'EOF' | gopass insert -f -m v3/domains/d000/dev/observability.env
export WAZUH_API_URL="https://10.50.1.134:55000"
export WAZUH_API_USER="wazuh"
export WAZUH_API_PASSWORD="wazuh_api_password"
export WAZUH_INDEXER_URL="https://10.50.1.131:9200"
export WAZUH_INDEXER_USER="admin"
export WAZUH_INDEXER_PASSWORD="indexer_password"
export GRAFANA_USER="admin"
export GRAFANA_PASSWORD="grafana_password"
EOF

# Usage
dsec source d000 dev/network
# OR
eval "$(gopass show v3/domains/d000/dev/network.env)"

PATTERN: No YAML separator - just export statements. Source directly.

Personal Account Templates

# Website Login
cat << 'EOF' | gopass insert -f -m v3/personal/social/github/username
GITHUB_PASSWORD_OR_PAT
---
type: website
url: https://github.com
credentials:
  username: username
  email: user@example.com
security:
  2fa: true
  2fa_type: totp
  recovery_codes: v3/personal/social/github/username-recovery
meta:
  created: 2026-02-01
EOF

# Cloud Provider
cat << 'EOF' | gopass insert -f -m v3/personal/cloud/aws/main-account
AWS_ACCESS_KEY_SECRET
---
type: aws
credentials:
  access_key_id: AKIAXXXXXXXXXXXXXXXX
  account_id: "123456789012"
  region: us-west-2
security:
  2fa: true
  root_email: aws-root@example.com
meta:
  created: 2026-02-01
EOF

# SSH Key Passphrase
cat << 'EOF' | gopass insert -f -m v3/personal/ssh/id_ed25519
PASSPHRASE_FOR_KEY
---
type: ssh-key
key_file: ~/.ssh/id_ed25519
key_type: ed25519
fingerprint: SHA256:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
created: 2026-02-01
EOF

Certificate and PKI Templates

# Certificate + Private Key
cat << 'EOF' | gopass insert -f -m v3/domains/d000/pki/server-cert
-----BEGIN EC PRIVATE KEY-----
MIGkAgEBBDxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
-----END EC PRIVATE KEY-----
---
type: certificate
subject: server.inside.domusdigitalis.dev
issuer: DOMUS-ISSUING-CA
valid_from: 2026-02-01
valid_to: 2027-02-01
serial: "12:34:56:78:9A:BC:DE:F0"
usage:
  - serverAuth
  - clientAuth
san:
  - DNS:server.inside.domusdigitalis.dev
  - IP:10.50.1.100
cert_file: /etc/ssl/certs/server.pem
key_file: /etc/ssl/private/server.key
EOF

# CA Certificate (public, no key)
cat << 'EOF' | gopass insert -f -m v3/domains/d000/pki/ca-chain
-----BEGIN CERTIFICATE-----
MIIFxxx... (CA cert content)
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIFyyy... (Root cert content)
-----END CERTIFICATE-----
---
type: ca-chain
root: DOMUS-ROOT-CA
intermediate: DOMUS-ISSUING-CA
purpose: EAP-TLS trust anchor
location: /etc/ssl/certs/domus-ca-chain.pem
EOF

Bulk Insert Patterns

# From CSV file
while IFS=',' read -r name user pass host; do
    cat << EOF | gopass insert -f -m "v3/import/$name"
$pass
---
type: imported
credentials:
  username: $user
connection:
  host: $host
EOF
done < accounts.csv

# From JSON (with jq)
cat accounts.json | jq -r '.[] | "\(.name)|\(.user)|\(.pass)|\(.host)"' | \
while IFS='|' read -r name user pass host; do
    cat << EOF | gopass insert -f -m "v3/import/$name"
$pass
---
type: imported
credentials:
  username: $user
connection:
  host: $host
EOF
done

# Generate multiple entries
for i in {01..10}; do
    pass=$(gopass generate --print 24)
    cat << EOF | gopass insert -f -m "v3/generated/service-$i"
$pass
---
type: generated
created: $(date +%Y-%m-%d)
EOF
done

Update Existing Entries

# Edit in $EDITOR (best for structured updates)
gopass edit v3/path/entry

# Replace just the password (keep metadata)
NEW_PASS=$(gopass generate --print 24)
{
    echo "$NEW_PASS"
    gopass show v3/path/entry | tail -n+2  # Everything after first line
} | gopass insert -f -m v3/path/entry

# Append to metadata
CURRENT=$(gopass show v3/path/entry)
{
    echo "$CURRENT"
    echo "modified: $(date +%Y-%m-%d)"
} | gopass insert -f -m v3/path/entry

# Change specific field (with yq)
gopass show v3/path/entry | {
    head -1  # Password
    tail -n+2 | yq '.meta.modified = "2026-02-27"'
} | gopass insert -f -m v3/path/entry

Extract Fields from Entries

# Password only
gopass show -o v3/path/entry

# Specific line
gopass show v3/path/entry | sed -n '3p'

# YAML field (after --- separator)
gopass show v3/path/entry | tail -n+2 | yq '.credentials.username'

# grep pattern
gopass show v3/path/entry | grep 'host:' | awk '{print $2}'

# Multiple fields
gopass show v3/path/entry | tail -n+2 | yq '[.credentials.username, .connection.host] | @csv'

# JSON output
gopass show v3/path/entry | tail -n+2 | yq -o=json

# All entries matching pattern
for entry in $(gopass ls -f v3/infrastructure/); do
    host=$(gopass show "$entry" | grep 'host:' | awk '{print $2}')
    echo "$entry: $host"
done

Common Gotchas

# WRONG: Forgetting -m for multiline
echo "pass" | gopass insert path  # Only stores "pass"
cat config.txt | gopass insert path  # Only stores first line!

# CORRECT: Always use -m for structured content
cat config.txt | gopass insert -m path
cat << 'EOF' | gopass insert -f -m path
password
---
metadata: here
EOF

# WRONG: Not quoting heredoc delimiter
cat << EOF | gopass insert -m path
$VARIABLE  # Gets expanded!
EOF

# CORRECT: Quote heredoc delimiter for literal content
cat << 'EOF' | gopass insert -m path
$VARIABLE  # Stored literally as $VARIABLE
EOF

# WRONG: Expecting YAML validation
# gopass doesn't validate YAML - it just stores text

# CORRECT: Validate before insert if needed
yq '.' metadata.yaml && cat metadata.yaml | gopass insert -m path

# WRONG: Assuming fields are accessible
gopass show path username  # Doesn't work for YAML

# CORRECT: Parse YAML yourself
gopass show path | tail -n+2 | yq '.username'

Quick Templates

# Linux Server
gopass_linux() {
    local path="$1" host="$2" user="${3:-admin}"
    local pass=$(gopass generate --print 24)
    cat << EOF | gopass insert -f -m "$path"
$pass
---
type: linux
connection:
  host: $host
  port: 22
credentials:
  username: $user
meta:
  created: $(date +%Y-%m-%d)
EOF
}
# Usage: gopass_linux v3/servers/newhost newhost.example.com admin

# API Token
gopass_token() {
    local path="$1" token="$2" service="$3"
    cat << EOF | gopass insert -f -m "$path"
$token
---
type: api-token
service: $service
meta:
  created: $(date +%Y-%m-%d)
EOF
}
# Usage: gopass_token v3/tokens/github "ghp_xxxx" "GitHub"

# Website
gopass_web() {
    local path="$1" url="$2" user="$3"
    local pass=$(gopass generate --print 20)
    cat << EOF | gopass insert -f -m "$path"
$pass
---
type: website
url: $url
credentials:
  username: $user
meta:
  created: $(date +%Y-%m-%d)
EOF
}
# Usage: gopass_web v3/personal/social/site "https://site.com" "myuser"