STD-006: Secrets Handling
Rules governing credential management, secret access, and secure storage across all domus repositories and workstations. Verify presence and accessibility — never content.
Principles
-
Secrets are inviolable. Never decrypt
.agefiles programmatically, read~/.secrets/, executeage -din automation, or surface any credential value. Document paths; never reveal values. -
Presence, not content. Validation checks verify that secrets EXIST and are ACCESSIBLE. They MUST NOT print, log, or display secret values.
-
Each machine owns its keys. Private keys MUST NOT be shared across machines. Each workstation gets its own keypair, its own Vault cert, its own gopass clone.
-
Encrypted at rest. Secrets not actively in use MUST be encrypted. Use gocryptfs for credential vaults, age for file encryption, LUKS for disk encryption.
Requirements
-
Credentials, tokens, API keys, and secret values MUST NOT appear in any
.adocdocument, commit message, or log output. Redact with<REDACTED>. -
gopass store paths and Vault policy names are acceptable to document. Secret values stored within them are not.
-
Private keys (
~/.ssh/id_*,~/.gnupg/,~/.age/identities) MUST NOT be committed to any git repository. -
Each workstation MUST have its own SSH keypair, GPG key, and EAP-TLS certificate. Never copy private keys between machines.
-
gocryptfs vaults MUST be unmounted when not in active use. Sensitive tooling (Claude Code config, gh CLI tokens) SHOULD be symlinked from the mounted vault.
-
After rsync’ing
~/.gnupg/to a new machine, GPG lock files MUST be cleared andgpg-agentrestarted before use. Lock files contain source machine PIDs. -
After gopass bootstrap on a new machine,
gopass configMUST be verified to show the correct root store path. -
SSH config containing hostnames and connection details MUST be age-encrypted before committing:
age -e -R ~/.age/recipients/self.txt.
d001 Sensitive Data Workflow
Work projects store sensitive materials (config snapshots, meeting notes, certificates, vendor configs) under data/d001/projects/<slug>/. Plaintext .adoc files are gitignored — only age-encrypted .age files are tracked.
Standard: d001 open / d001 close
The d001 shell function manages bulk encrypt/decrypt. It fuzzy-matches project directories via fzf.
d001 open okta-to-entra # Decrypt all .adoc.age in matched project
# Edit partials...
d001 close okta-to-entra # Encrypt partials/*.adoc, delete plaintext, stage .age
d001 close scans partials/ only. Non-adoc files in certs/, config-snapshots/, scripts/ require one-off handling.
Single-File Edit
d001 open-file okta-to-entra # Decrypt → $EDITOR → re-encrypt on quit
One-Off (non-adoc files)
For .pem, .xml, .txt files outside partials/:
decrypt-file path/to/file.age # Decrypt
# Edit...
rm path/to/file.age # Delete stale .age FIRST
encrypt-file path/to/file # Re-encrypt
|
Always delete the stale |
Pre-Push Audit
Run before every push to verify no plaintext leaked:
# Check for unencrypted sensitive files in d001
find data/d001 -name '*.adoc' -not -name 'README.adoc' -not -name '*.age' -type f
# Should return zero results. Any match = forgot to d001 close.
Project Directory Standard
See STD-001 § "Sensitive Data Directory" for the required data/d001/projects/<slug>/ structure (README, partials, certs, config-snapshots, scripts, sql, output).
Compliance
| Check | Method | Pass Criterion |
|---|---|---|
No secrets in docs |
|
Zero real credentials |
No private keys in git |
|
Zero private key files tracked |
SSH config encrypted |
|
Only |
gocryptfs vault mountable |
|
Mount succeeds, contents accessible |
gopass accessible |
|
Store listed without error |
Exceptions
None. All requirements apply unconditionally.
Related
-
Secrets Management Patterns — operational patterns for gopass, gocryptfs, pinentry
-
Vault Operations Patterns — Vault cert workflows
-
PKI Patterns — certificate lifecycle management
-
STD-002: Deployment Validation — Domain 7 (Secrets & Credentials) verification