Credential Management
Credential lifecycle management across the domus secrets infrastructure.
Credential Architecture
The domus infrastructure uses a layered credential management approach:
Layer 1: gopass — human-accessible password store (GPG-encrypted) Layer 2: HashiCorp Vault — machine-accessible secrets, PKI, SSH CA Layer 3: age — file encryption for dotfiles and configs in git Layer 4: SSH certificates — short-lived, Vault-signed, replace static keys
dsec CLI
The dsec wrapper (domus-secrets-ops) provides unified access across credential stores.
List all credential categories
dsec list
Search across all stores
dsec search "database"
Get a credential — tries gopass first, falls back to Vault
dsec get infra/db/prod
Credential Rotation Workflow
Rotate a database credential — verify before, change, verify after
# Before — confirm current credential works
gopass show -o infra/db/prod | head -1
# Change — generate new password and update
gopass generate infra/db/prod 32
gopass show -o infra/db/prod | head -1
# After — update the service
# (manual step: apply new credential to the service)
Rotate a Vault token
# Before
vault token lookup
# Change
vault token create -policy=admin -ttl=24h
# After
vault token lookup
Environment Variable Patterns
Load secrets into environment — never hardcode in scripts
export DB_PASSWORD="$(gopass show -o infra/db/prod)"
export API_TOKEN="$(vault kv get -field=token kv/infra/api)"
Temporary environment for a single command
DB_PASSWORD="$(gopass show -o infra/db/prod)" psql -h db-host -U admin -d app
Export to .env file — gitignored, ephemeral
cat > .env <<EOF
DB_USER=$(gopass show -f infra/db/prod username)
DB_PASS=$(gopass show -o infra/db/prod)
EOF
chmod 600 .env
Credential Audit
Audit gopass store — weakness, duplicates, age
gopass audit
Check Vault token TTLs — find tokens about to expire
vault token lookup -format=json | jq '{ttl: .data.ttl, policies: .data.policies}'
Find files that might contain secrets — scan a codebase
grep -rn --include='*.py' --include='*.sh' --include='*.yaml' \
-E '(password|secret|token|api_key)\s*=' . | grep -v '<REDACTED>'
Secret Redaction
All documentation uses <REDACTED> for secret values. gopass paths are acceptable.
# Wrong — exposed credential export DB_PASS="s3cret123" # Correct — reference to credential store export DB_PASS="$(gopass show -o infra/db/prod)" # Correct — in documentation The database password is stored at `infra/db/prod` in gopass.
Emergency Credential Rotation
When a credential is suspected compromised:
-
Rotate the credential immediately in the service
-
Update gopass/Vault with the new value
-
Revoke any tokens or certificates associated with the old credential
-
Audit access logs for unauthorized use
-
Document in an INC- report if P1/P2
Vault emergency token revocation
# Revoke all tokens under a prefix
vault token revoke -mode path auth/userpass/login/compromised-user
# Revoke all leases from a secrets engine
vault lease revoke -prefix pki_int/issue/