@sebastienrousseau/dotfiles 0.2.519 → 0.2.521
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +200 -0
- package/LICENSE-APACHE +190 -0
- package/{LICENSE → LICENSE-MIT} +1 -1
- package/README.md +1172 -166
- package/install.sh +77 -11
- package/package.json +8 -8
- package/tools/README.md +49 -0
- package/tools/ci/install-chezmoi-verified.sh +68 -0
- package/docs/.vitepress/reports/localization-readability-audit.md +0 -73
- package/docs/AI.md +0 -179
- package/docs/CNAME +0 -1
- package/docs/CONFIG_STRATEGY.md +0 -124
- package/docs/COPYRIGHT +0 -7
- package/docs/GOVERNANCE.md +0 -98
- package/docs/MAINTAINERS.md +0 -41
- package/docs/NAMING_CONVENTIONS.md +0 -102
- package/docs/OPENCODE.md +0 -127
- package/docs/README.md +0 -84
- package/docs/STRUCTURE.md +0 -102
- package/docs/adr/ADR-001-ci-cd-pipeline.md +0 -118
- package/docs/adr/ADR-002-shell-performance.md +0 -130
- package/docs/adr/ADR-003-security-first.md +0 -158
- package/docs/adr/ADR-004-cli-architecture.md +0 -171
- package/docs/adr/ADR-005-chezmoi-choice.md +0 -99
- package/docs/adr/ADR-006-shell-selection.md +0 -124
- package/docs/adr/ADR-007-multi-shell-parity.md +0 -62
- package/docs/adr/ADR-008-alias-system-architecture.md +0 -95
- package/docs/adr/ADR-009-wallpaper-driven-theming.md +0 -131
- package/docs/adr/ADR-010-starship-transient-prompt.md +0 -144
- package/docs/adr/ADR-011-nushell-tier3-keep.md +0 -144
- package/docs/adr/ADR-012-ai-fleet-local-proxy.md +0 -79
- package/docs/adr/README.md +0 -40
- package/docs/architecture/AI_COST_OPTIMIZATION.md +0 -144
- package/docs/architecture/ARCHITECTURE.md +0 -117
- package/docs/architecture/INTEROP.md +0 -44
- package/docs/architecture/REPO_LAYOUT.md +0 -241
- package/docs/architecture/WALKTHROUGH.md +0 -86
- package/docs/architecture/fleet-deployment.md +0 -77
- package/docs/archive/EUXIS_2026_REVIEW.md +0 -127
- package/docs/archive/LEGACY_ROADMAP.md +0 -6
- package/docs/archive/MILESTONE_v0.2.493.md +0 -47
- package/docs/archive/PLAN.md +0 -199
- package/docs/archive/REPO_AUDIT.md +0 -31
- package/docs/articles/.pages +0 -6
- package/docs/articles/2026-07-05-custom-mkdocs-material-dark-theme.md +0 -216
- package/docs/articles/2026-07-05-fish-startup-abbr.md +0 -153
- package/docs/articles/2026-07-05-master-to-main-rename-runbook.md +0 -128
- package/docs/articles/index.md +0 -36
- package/docs/guides/INSTALL.md +0 -144
- package/docs/guides/NEOVIM_IDE_GUIDE.md +0 -61
- package/docs/guides/THEMING.md +0 -230
- package/docs/guides/TROUBLESHOOTING.md +0 -176
- package/docs/guides/WSL2_NIX_TROUBLESHOOTING.md +0 -792
- package/docs/index.md +0 -132
- package/docs/interop/A2A.md +0 -39
- package/docs/interop/POWERSHELL.md +0 -102
- package/docs/manual/00-introduction.md +0 -89
- package/docs/manual/01-concepts/01-architecture.md +0 -138
- package/docs/manual/01-concepts/02-trust-model.md +0 -183
- package/docs/manual/01-concepts/03-theme-engine.md +0 -186
- package/docs/manual/01-concepts/04-fleet.md +0 -148
- package/docs/manual/01-concepts/05-self-healing.md +0 -204
- package/docs/manual/02-tutorials/01-first-install.md +0 -197
- package/docs/manual/02-tutorials/02-add-wallpaper.md +0 -216
- package/docs/manual/02-tutorials/03-create-profile.md +0 -244
- package/docs/manual/02-tutorials/04-encrypt-secret.md +0 -281
- package/docs/manual/02-tutorials/05-deploy-fleet.md +0 -283
- package/docs/manual/03-reference/01-dot-cli.md +0 -450
- package/docs/manual/03-reference/02-config-files.md +0 -265
- package/docs/manual/03-reference/03-environment.md +0 -124
- package/docs/manual/03-reference/04-templates.md +0 -190
- package/docs/manual/03-reference/05-feature-flags.md +0 -187
- package/docs/manual/04-cookbook/01-recipes.md +0 -285
- package/docs/manual/04-cookbook/02-troubleshooting.md +0 -351
- package/docs/manual/04-cookbook/03-faq.md +0 -175
- package/docs/manual/05-appendices/A-platform-matrix.md +0 -101
- package/docs/manual/05-appendices/B-security-checklist.md +0 -85
- package/docs/manual/05-appendices/C-glossary.md +0 -40
- package/docs/manual/05-appendices/D-bibliography.md +0 -58
- package/docs/manual/05-appendices/E-license.md +0 -38
- package/docs/manual/_toc.yml +0 -58
- package/docs/manual/command-index.md +0 -155
- package/docs/manual/concept-index.md +0 -168
- package/docs/manual/index.md +0 -66
- package/docs/operations/ARCHITECTURE_ROADMAP.md +0 -7
- package/docs/operations/ATTESTATION.md +0 -44
- package/docs/operations/CI_CADENCE.md +0 -107
- package/docs/operations/CI_COMPOSITES.md +0 -156
- package/docs/operations/COMPLETIONS.md +0 -123
- package/docs/operations/COVERAGE.md +0 -204
- package/docs/operations/DRIFT.md +0 -107
- package/docs/operations/HARD_AUDIT_2026.md +0 -631
- package/docs/operations/MAINTENANCE.md +0 -63
- package/docs/operations/MANIFEST.md +0 -127
- package/docs/operations/MIGRATION.md +0 -109
- package/docs/operations/OPERATIONS.md +0 -188
- package/docs/operations/PERFORMANCE.md +0 -133
- package/docs/operations/REGISTRY.md +0 -90
- package/docs/operations/RELEASE_PIPELINE.md +0 -128
- package/docs/operations/RELIABILITY.md +0 -122
- package/docs/operations/RFC_v0_2_503_reorganization.md +0 -280
- package/docs/operations/ROADMAP.md +0 -10
- package/docs/operations/ROADMAP_2026.md +0 -7
- package/docs/operations/ROADMAP_V0_2_503.md +0 -10
- package/docs/operations/TESTING.md +0 -216
- package/docs/operations/TRACEABILITY.md +0 -43
- package/docs/operations/TRUSTED_AGENT_WORKSTATION.md +0 -65
- package/docs/operations/VERSION_SYNC.md +0 -393
- package/docs/reference/ALIASES.md +0 -131
- package/docs/reference/ALIASES_CHEATSHEET.md +0 -32
- package/docs/reference/ALIASES_DEPRECATIONS.md +0 -13
- package/docs/reference/FEATURES.md +0 -66
- package/docs/reference/FONTS.md +0 -112
- package/docs/reference/POWERSHELL_PARITY.md +0 -82
- package/docs/reference/PROFILES.md +0 -69
- package/docs/reference/SCREENSHOTS.md +0 -121
- package/docs/reference/SCRIPTS.md +0 -71
- package/docs/reference/SUPPORT_MATRIX.md +0 -80
- package/docs/reference/THEMES.md +0 -117
- package/docs/reference/TOOLS.md +0 -110
- package/docs/reference/UTILS.md +0 -242
- package/docs/registry.json +0 -6
- package/docs/schema/dot-env-v1.json +0 -110
- package/docs/schema/dot-registry-v1.json +0 -33
- package/docs/security/AI_ACT_COMPLIANCE.md +0 -94
- package/docs/security/AUDIT_BYPASS.md +0 -103
- package/docs/security/AUTOMATION_SECRETS.md +0 -26
- package/docs/security/CI_EGRESS_ALLOWLIST.md +0 -127
- package/docs/security/CI_PINNING.md +0 -129
- package/docs/security/COMMIT_SIGNING.md +0 -138
- package/docs/security/COMPLIANCE.md +0 -458
- package/docs/security/DEPS_DEV_EXCEPTIONS.md +0 -86
- package/docs/security/DISCLOSURE.md +0 -130
- package/docs/security/ENCRYPTION.md +0 -57
- package/docs/security/FMEA.md +0 -159
- package/docs/security/FUZZING.md +0 -114
- package/docs/security/HISTORY_FILTERING.md +0 -132
- package/docs/security/INCIDENT_RESPONSE.md +0 -579
- package/docs/security/INSTALL_VERIFICATION.md +0 -122
- package/docs/security/KEYS.md +0 -49
- package/docs/security/KEY_ROTATION.md +0 -303
- package/docs/security/MCP_POLICY.md +0 -78
- package/docs/security/POLICY_RELEASES.md +0 -37
- package/docs/security/README.md +0 -28
- package/docs/security/SCORECARD.md +0 -195
- package/docs/security/SECRETS.md +0 -158
- package/docs/security/SECURITY.md +0 -45
- package/docs/security/SECURITY_CHECKLIST.md +0 -55
- package/docs/security/SHELL_EXEMPTIONS.md +0 -145
- package/docs/security/SOUP_REGISTER.md +0 -36
- package/docs/security/THREAT_MODEL.md +0 -130
- package/docs/security/VERIFICATION_VALIDATION.md +0 -228
- package/docs/security/VERIFY_RELEASE.md +0 -201
- package/docs/security/security-pubkey.asc +0 -15
- package/docs/stylesheets/extra.css +0 -444
- package/docs/themes/README.md +0 -10
- package/docs/themes/VISUAL_INTEGRITY_REPORT.md +0 -30
- package/docs/themes/hero-shot.svg +0 -78
- package/scripts/README.md +0 -123
- package/scripts/ci/check-copyright-headers.sh +0 -8
- package/scripts/ci/check-shell-preamble.sh +0 -8
- package/scripts/ci/guard-gitleaks-checkout.sh +0 -8
- package/scripts/demo/record.sh +0 -43
- package/scripts/diagnostics/a2a-conformance.sh +0 -163
- package/scripts/diagnostics/alias-governance.sh +0 -138
- package/scripts/diagnostics/aliases-cheatsheet.sh +0 -74
- package/scripts/diagnostics/aliases-manifest.sh +0 -77
- package/scripts/diagnostics/benchmark.sh +0 -408
- package/scripts/diagnostics/conflicts.sh +0 -73
- package/scripts/diagnostics/doctor-unified.sh +0 -39
- package/scripts/diagnostics/doctor.sh +0 -751
- package/scripts/diagnostics/drift-dashboard.sh +0 -202
- package/scripts/diagnostics/health.sh +0 -623
- package/scripts/diagnostics/history-analysis.sh +0 -86
- package/scripts/diagnostics/mcp-doctor.sh +0 -582
- package/scripts/diagnostics/perf.sh +0 -453
- package/scripts/diagnostics/scorecard.sh +0 -119
- package/scripts/diagnostics/secret-governance.sh +0 -65
- package/scripts/diagnostics/security-score.sh +0 -467
- package/scripts/diagnostics/smoke-test.sh +0 -88
- package/scripts/diagnostics/snapshot.sh +0 -90
- package/scripts/diagnostics/verify.sh +0 -108
- package/scripts/diagnostics/verify_state.sh +0 -73
- package/scripts/diagnostics/version-locks.sh +0 -94
- package/scripts/diagnostics/workstation-attestation.sh +0 -187
- package/scripts/dot/commands/agent.sh +0 -485
- package/scripts/dot/commands/agents.sh +0 -336
- package/scripts/dot/commands/ai.sh +0 -587
- package/scripts/dot/commands/aliases.sh +0 -277
- package/scripts/dot/commands/appearance.sh +0 -110
- package/scripts/dot/commands/completion.sh +0 -134
- package/scripts/dot/commands/core.sh +0 -217
- package/scripts/dot/commands/diagnostics.sh +0 -265
- package/scripts/dot/commands/env-emit.sh +0 -203
- package/scripts/dot/commands/fleet.sh +0 -688
- package/scripts/dot/commands/init.sh +0 -185
- package/scripts/dot/commands/lint.sh +0 -208
- package/scripts/dot/commands/manual.sh +0 -169
- package/scripts/dot/commands/meta.sh +0 -333
- package/scripts/dot/commands/patterns.sh +0 -55
- package/scripts/dot/commands/registry.sh +0 -419
- package/scripts/dot/commands/restore.sh +0 -232
- package/scripts/dot/commands/secrets.sh +0 -296
- package/scripts/dot/commands/security.sh +0 -102
- package/scripts/dot/commands/tools.sh +0 -556
- package/scripts/dot/data/alias-deprecations.tsv +0 -2
- package/scripts/dot/powershell/Dot.psm1 +0 -319
- package/scripts/fonts/install-nerd-fonts.sh +0 -75
- package/scripts/fonts/patch-fonts.sh +0 -36
- package/scripts/git-hooks/install.sh +0 -12
- package/scripts/git-hooks/pre-commit +0 -12
- package/scripts/git-hooks/pre-commit-audit.sh +0 -146
- package/scripts/git-hooks/pre-push +0 -105
- package/scripts/git-hooks/prepare-commit-msg +0 -29
- package/scripts/lib/secrets_provider.sh +0 -185
- package/scripts/ops/ai-setup.sh +0 -71
- package/scripts/ops/bundle.sh +0 -104
- package/scripts/ops/chaos.sh +0 -50
- package/scripts/ops/chezmoi-apply.sh +0 -333
- package/scripts/ops/chezmoi-diff.sh +0 -16
- package/scripts/ops/chezmoi-remove.sh +0 -46
- package/scripts/ops/chezmoi-update.sh +0 -63
- package/scripts/ops/heal-chezmoi.sh +0 -87
- package/scripts/ops/heal-system.sh +0 -129
- package/scripts/ops/heal-tools.sh +0 -297
- package/scripts/ops/heal.sh +0 -223
- package/scripts/ops/post-apply-repair.sh +0 -107
- package/scripts/ops/prewarm.sh +0 -128
- package/scripts/ops/release.sh +0 -262
- package/scripts/ops/rollback.sh +0 -604
- package/scripts/ops/setup.sh +0 -138
- package/scripts/ops/teleport.sh +0 -34
- package/scripts/qa/check-version-consistency.sh +0 -124
- package/scripts/qa/coverage-baseline.sh +0 -61
- package/scripts/qa/docs-coverage.sh +0 -112
- package/scripts/qa/examples-coverage.sh +0 -94
- package/scripts/qa/powershell-contract.ps1 +0 -95
- package/scripts/qa/reliability-audit.sh +0 -139
- package/scripts/qa/scorecard-snapshot.sh +0 -128
- package/scripts/qa/traceability-coverage.sh +0 -117
- package/scripts/qa/validate-examples.sh +0 -27
- package/scripts/qa/wsl-contract.sh +0 -12
- package/scripts/secrets/age-init.sh +0 -82
- package/scripts/secrets/create-secrets-file.sh +0 -46
- package/scripts/secrets/encrypt-ssh-key.sh +0 -44
- package/scripts/security/backup.sh +0 -58
- package/scripts/security/check-disclosure-key-expiry.sh +0 -111
- package/scripts/security/dns-doh.sh +0 -52
- package/scripts/security/encryption-check.sh +0 -55
- package/scripts/security/enforce-policies.sh +0 -335
- package/scripts/security/firewall.sh +0 -91
- package/scripts/security/lock-configs.sh +0 -67
- package/scripts/security/lock-screen.sh +0 -56
- package/scripts/security/manage-secrets.sh +0 -429
- package/scripts/security/ssh-cert.sh +0 -204
- package/scripts/security/telemetry-kill.sh +0 -51
- package/scripts/security/usb-safety.sh +0 -52
- package/scripts/theme/apply-gnome-theme.sh +0 -333
- package/scripts/theme/extract-heic-frames.sh +0 -115
- package/scripts/theme/extract-theme.py +0 -742
- package/scripts/theme/install-boot-logo.sh +0 -63
- package/scripts/theme/install-catppuccin-themes.sh +0 -371
- package/scripts/theme/install-cursors.sh +0 -26
- package/scripts/theme/install-file-icons.sh +0 -27
- package/scripts/theme/install-grub-theme.sh +0 -62
- package/scripts/theme/install-lock-icon.sh +0 -31
- package/scripts/theme/merge-wallpaper.sh +0 -146
- package/scripts/theme/rebuild-themes.sh +0 -544
- package/scripts/theme/switch.sh +0 -449
- package/scripts/theme/wallpaper-rotate.sh +0 -137
- package/scripts/theme/wallpaper-sync.sh +0 -690
- package/scripts/tools/cmatrix.sh +0 -22
- package/scripts/tools/detect-collisions.py +0 -103
- package/scripts/tools/emoji-picker.sh +0 -49
- package/scripts/tools/figlet-banner.sh +0 -19
- package/scripts/tools/log-rotate.sh +0 -31
- package/scripts/tools/lolcat-wrap.sh +0 -20
- package/scripts/tools/pipes.sh +0 -49
- package/scripts/tuning/linux.sh +0 -186
- package/scripts/tuning/macos.sh +0 -56
- package/scripts/uninstall.sh +0 -86
- package/scripts/version-sync.sh +0 -654
- package/templates/chezmoi-data/geekom-a9.toml.example +0 -21
- package/templates/chezmoi-data/mac-m1.toml.example +0 -16
- package/templates/chezmoi-data/mac-t2-linux.toml.example +0 -21
- package/templates/chezmoi-data/surface-pro-7p.toml.example +0 -21
- package/templates/projects/go/.github/workflows/ci.yml +0 -31
- package/templates/projects/go/README.md +0 -7
- package/templates/projects/go/cmd/__PROJECT_NAME__/main.go +0 -8
- package/templates/projects/go/go.mod +0 -3
- package/templates/projects/go/go.sum +0 -0
- package/templates/projects/molecule/README.md +0 -7
- package/templates/projects/molecule/converge.yml +0 -7
- package/templates/projects/molecule/molecule.yml +0 -16
- package/templates/projects/node/.github/workflows/ci.yml +0 -30
- package/templates/projects/node/README.md +0 -7
- package/templates/projects/node/package-lock.json +0 -12
- package/templates/projects/node/package.json +0 -10
- package/templates/projects/node/src/index.js +0 -3
- package/templates/projects/packer/README.md +0 -15
- package/templates/projects/packer/main.pkr.hcl +0 -15
- package/templates/projects/python/.github/workflows/ci.yml +0 -34
- package/templates/projects/python/README.md +0 -7
- package/templates/projects/python/pyproject.toml +0 -25
- package/templates/projects/python/src/__PROJECT_NAME__/__init__.py +0 -2
- package/templates/projects/python/tests/test_basic.py +0 -3
|
@@ -1,281 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
render_with_liquid: false
|
|
3
|
-
---
|
|
4
|
-
{% raw %}
|
|
5
|
-
|
|
6
|
-
# Tutorial: Encrypt a Secret
|
|
7
|
-
|
|
8
|
-
How to store an API key (or any secret) encrypted in the repository using Age and SOPS — decrypted automatically on `dot apply`.
|
|
9
|
-
|
|
10
|
-
## The Threat Model
|
|
11
|
-
|
|
12
|
-
Secrets in plaintext config files are:
|
|
13
|
-
|
|
14
|
-
- Committed to Git history (permanent record)
|
|
15
|
-
- Visible to every process on the machine
|
|
16
|
-
- Included in backup archives
|
|
17
|
-
|
|
18
|
-
Secrets encrypted with Age:
|
|
19
|
-
|
|
20
|
-
- Cipher text committed to Git is useless without the private key
|
|
21
|
-
- Private key (`~/.config/age/keys.txt`) never leaves the user's machine
|
|
22
|
-
- Per-machine policy: only authorized hosts hold keys for their share of secrets
|
|
23
|
-
|
|
24
|
-
## Step 1: Generate an Age Key (First Time Only)
|
|
25
|
-
|
|
26
|
-
```sh
|
|
27
|
-
age-keygen -o ~/.config/age/keys.txt
|
|
28
|
-
chmod 600 ~/.config/age/keys.txt
|
|
29
|
-
```
|
|
30
|
-
|
|
31
|
-
The public key is embedded in the file:
|
|
32
|
-
|
|
33
|
-
```sh
|
|
34
|
-
cat ~/.config/age/keys.txt
|
|
35
|
-
# created: 2026-04-16T09:00:00Z
|
|
36
|
-
# public key: age1qy90l...xyz
|
|
37
|
-
AGE-SECRET-KEY-1A...
|
|
38
|
-
```
|
|
39
|
-
|
|
40
|
-
Copy the public key — you'll reference it when encrypting.
|
|
41
|
-
|
|
42
|
-
## Step 2: Choose Encryption Method
|
|
43
|
-
|
|
44
|
-
Two approaches are supported:
|
|
45
|
-
|
|
46
|
-
| Method | Best For | Filename |
|
|
47
|
-
|:---|:---|:---|
|
|
48
|
-
| **Chezmoi encrypt** | Individual files (API tokens, config snippets) | `dot_config/token.age` |
|
|
49
|
-
| **SOPS** | YAML/JSON with multiple secrets, selective field encryption | `dot_config/creds.sops.yaml` |
|
|
50
|
-
|
|
51
|
-
## Step 3A: Chezmoi-Encrypted File
|
|
52
|
-
|
|
53
|
-
Create an unencrypted source file:
|
|
54
|
-
|
|
55
|
-
```sh
|
|
56
|
-
mkdir -p ~/tmp
|
|
57
|
-
echo "sk_live_abc123" > ~/tmp/stripe-key.txt
|
|
58
|
-
```
|
|
59
|
-
|
|
60
|
-
Import it as encrypted:
|
|
61
|
-
|
|
62
|
-
```sh
|
|
63
|
-
chezmoi add --encrypt ~/tmp/stripe-key.txt
|
|
64
|
-
```
|
|
65
|
-
|
|
66
|
-
This:
|
|
67
|
-
|
|
68
|
-
1. Reads `~/tmp/stripe-key.txt`
|
|
69
|
-
2. Encrypts with your Age public key
|
|
70
|
-
3. Stores encrypted content at `~/.dotfiles/dot_tmp/stripe-key.txt.age`
|
|
71
|
-
4. Template reads encrypted content at apply time and decrypts to target
|
|
72
|
-
|
|
73
|
-
Delete the plaintext source:
|
|
74
|
-
|
|
75
|
-
```sh
|
|
76
|
-
rm ~/tmp/stripe-key.txt
|
|
77
|
-
```
|
|
78
|
-
|
|
79
|
-
On `dot apply`, chezmoi decrypts and writes to `~/tmp/stripe-key.txt`. If someone lacks the private key, they see only the encrypted `.age` file in Git.
|
|
80
|
-
|
|
81
|
-
## Step 3B: SOPS-Encrypted YAML
|
|
82
|
-
|
|
83
|
-
SOPS encrypts **values** in YAML/JSON while preserving the structure. Useful when you want:
|
|
84
|
-
|
|
85
|
-
- Multiple secrets in one file
|
|
86
|
-
- Encryption of only sensitive fields (leaving metadata readable)
|
|
87
|
-
- Multi-recipient (e.g. the work laptop AND the backup laptop can decrypt)
|
|
88
|
-
|
|
89
|
-
Configure SOPS once:
|
|
90
|
-
|
|
91
|
-
```yaml
|
|
92
|
-
# .sops.yaml (at repo root)
|
|
93
|
-
creation_rules:
|
|
94
|
-
- path_regex: \.sops\.yaml$
|
|
95
|
-
age: age1qy90l...xyz
|
|
96
|
-
```
|
|
97
|
-
|
|
98
|
-
Create a secrets file:
|
|
99
|
-
|
|
100
|
-
```yaml
|
|
101
|
-
# dot_config/credentials.sops.yaml
|
|
102
|
-
database:
|
|
103
|
-
host: db.prod.example.com
|
|
104
|
-
user: app
|
|
105
|
-
password: supersecret
|
|
106
|
-
api_keys:
|
|
107
|
-
stripe: sk_live_abc
|
|
108
|
-
sendgrid: SG.xyz
|
|
109
|
-
```
|
|
110
|
-
|
|
111
|
-
Encrypt it:
|
|
112
|
-
|
|
113
|
-
```sh
|
|
114
|
-
sops --encrypt --in-place dot_config/credentials.sops.yaml
|
|
115
|
-
```
|
|
116
|
-
|
|
117
|
-
The file now contains ciphertext blobs where plaintext values were:
|
|
118
|
-
|
|
119
|
-
```yaml
|
|
120
|
-
database:
|
|
121
|
-
host: ENC[AES256_GCM,data:...]
|
|
122
|
-
user: ENC[AES256_GCM,data:...]
|
|
123
|
-
password: ENC[AES256_GCM,data:...]
|
|
124
|
-
api_keys:
|
|
125
|
-
stripe: ENC[AES256_GCM,data:...]
|
|
126
|
-
sendgrid: ENC[AES256_GCM,data:...]
|
|
127
|
-
sops:
|
|
128
|
-
age:
|
|
129
|
-
- recipient: age1qy90l...xyz
|
|
130
|
-
enc: |
|
|
131
|
-
-----BEGIN AGE ENCRYPTED FILE-----
|
|
132
|
-
...
|
|
133
|
-
```
|
|
134
|
-
|
|
135
|
-
To edit the encrypted file:
|
|
136
|
-
|
|
137
|
-
```sh
|
|
138
|
-
sops dot_config/credentials.sops.yaml
|
|
139
|
-
# Opens in $EDITOR with decrypted content; re-encrypts on save
|
|
140
|
-
```
|
|
141
|
-
|
|
142
|
-
## Step 4: Reference the Secret in a Template
|
|
143
|
-
|
|
144
|
-
Chezmoi has a built-in `decrypt` helper:
|
|
145
|
-
|
|
146
|
-
```go
|
|
147
|
-
# dot_bashrc.tmpl
|
|
148
|
-
export STRIPE_KEY="{{ include "dot_tmp/stripe-key.txt.age" | decrypt | trim }}"
|
|
149
|
-
```
|
|
150
|
-
|
|
151
|
-
For SOPS:
|
|
152
|
-
|
|
153
|
-
```go
|
|
154
|
-
# Use the sopsDecrypt template function
|
|
155
|
-
{{- $creds := dict -}}
|
|
156
|
-
{{- $creds = sopsDecrypt "dot_config/credentials.sops.yaml" | fromYaml }}
|
|
157
|
-
export DB_PASSWORD="{{ $creds.database.password }}"
|
|
158
|
-
```
|
|
159
|
-
|
|
160
|
-
## Step 5: Commit and Verify
|
|
161
|
-
|
|
162
|
-
```sh
|
|
163
|
-
cd ~/.dotfiles
|
|
164
|
-
git add .sops.yaml dot_config/credentials.sops.yaml dot_tmp/stripe-key.txt.age
|
|
165
|
-
git commit -sS -m "feat(secrets): add stripe and database credentials"
|
|
166
|
-
git push
|
|
167
|
-
```
|
|
168
|
-
|
|
169
|
-
Verify the commit doesn't leak secrets:
|
|
170
|
-
|
|
171
|
-
```sh
|
|
172
|
-
git log -p HEAD~1..HEAD | grep -v ENC | grep -iE 'password|secret|key' || echo "Clean"
|
|
173
|
-
```
|
|
174
|
-
|
|
175
|
-
On the next machine:
|
|
176
|
-
|
|
177
|
-
```sh
|
|
178
|
-
dot update
|
|
179
|
-
# Chezmoi decrypts using that machine's Age key
|
|
180
|
-
# If decryption fails, the template errors with a clear message
|
|
181
|
-
```
|
|
182
|
-
|
|
183
|
-
## Step 6: Multi-Recipient (Fleet)
|
|
184
|
-
|
|
185
|
-
To allow multiple hosts to decrypt the same secret, add more recipients:
|
|
186
|
-
|
|
187
|
-
```yaml
|
|
188
|
-
# .sops.yaml
|
|
189
|
-
creation_rules:
|
|
190
|
-
- path_regex: \.sops\.yaml$
|
|
191
|
-
age: >-
|
|
192
|
-
age1qy90l...xyz,
|
|
193
|
-
age1z2x33...abc,
|
|
194
|
-
age1mm0kk...def
|
|
195
|
-
```
|
|
196
|
-
|
|
197
|
-
Re-encrypt the affected files:
|
|
198
|
-
|
|
199
|
-
```sh
|
|
200
|
-
sops updatekeys dot_config/credentials.sops.yaml
|
|
201
|
-
```
|
|
202
|
-
|
|
203
|
-
Now any host with one of those three private keys can decrypt. Hosts without any matching key see the encrypted file but cannot read it.
|
|
204
|
-
|
|
205
|
-
## Step 7: Rotate a Compromised Key
|
|
206
|
-
|
|
207
|
-
```sh
|
|
208
|
-
# 1. Generate a new Age key on the affected host
|
|
209
|
-
age-keygen -o ~/.config/age/keys.txt.new
|
|
210
|
-
mv ~/.config/age/keys.txt.new ~/.config/age/keys.txt
|
|
211
|
-
|
|
212
|
-
# 2. Update .sops.yaml with the new public key
|
|
213
|
-
|
|
214
|
-
# 3. Re-encrypt all SOPS files with the new recipient list
|
|
215
|
-
find . -name '*.sops.yaml' -exec sops updatekeys {} \;
|
|
216
|
-
|
|
217
|
-
# 4. Commit and push
|
|
218
|
-
git add .sops.yaml dot_config/*.sops.yaml
|
|
219
|
-
git commit -sS -m "chore(secrets): rotate Age key"
|
|
220
|
-
|
|
221
|
-
# 5. On other fleet hosts
|
|
222
|
-
dot update
|
|
223
|
-
```
|
|
224
|
-
|
|
225
|
-
Old key still works for existing ciphertext, but new secrets use the new key. To force deprecation, delete the old key from `.sops.yaml` and `sops updatekeys` all files.
|
|
226
|
-
|
|
227
|
-
## Verifying No Plaintext Leaks
|
|
228
|
-
|
|
229
|
-
CI runs three secret scanners (`gitleaks`, `detect-secrets`, `trufflehog`) on every commit. You can run them locally:
|
|
230
|
-
|
|
231
|
-
```sh
|
|
232
|
-
gitleaks detect --redact --source .
|
|
233
|
-
detect-secrets scan --update .secrets.baseline
|
|
234
|
-
trufflehog git file://. --only-verified
|
|
235
|
-
```
|
|
236
|
-
|
|
237
|
-
If any scanner finds a potential leak, the commit is blocked.
|
|
238
|
-
|
|
239
|
-
## Operational Rules
|
|
240
|
-
|
|
241
|
-
1. **Never commit plaintext secrets** — use chezmoi encrypt or SOPS
|
|
242
|
-
2. **Never commit `~/.config/age/keys.txt`** — it's gitignored; double-check before pushing
|
|
243
|
-
3. **Age keys are per-host** — don't copy them via Git; use secure channels (1Password, Bitwarden, physical USB)
|
|
244
|
-
4. **Rotate on team membership changes** — when someone leaves, update recipients and rotate all shared secrets
|
|
245
|
-
5. **Audit with `dot verify --security`** — runs gitleaks + signature + policy hash checks
|
|
246
|
-
|
|
247
|
-
## Troubleshooting
|
|
248
|
-
|
|
249
|
-
### "Could not decrypt: no age key found"
|
|
250
|
-
|
|
251
|
-
`~/.config/age/keys.txt` is missing or unreadable:
|
|
252
|
-
|
|
253
|
-
```sh
|
|
254
|
-
chmod 600 ~/.config/age/keys.txt
|
|
255
|
-
ls -la ~/.config/age/keys.txt
|
|
256
|
-
# -rw------- 1 user user 189 Apr 16 09:00 keys.txt
|
|
257
|
-
```
|
|
258
|
-
|
|
259
|
-
### "sops: file encrypted with outdated recipients"
|
|
260
|
-
|
|
261
|
-
A secret file has an old recipient list. Fix:
|
|
262
|
-
|
|
263
|
-
```sh
|
|
264
|
-
sops updatekeys path/to/file.sops.yaml
|
|
265
|
-
```
|
|
266
|
-
|
|
267
|
-
### Secrets Not Applying After Apply
|
|
268
|
-
|
|
269
|
-
Check that `dot_tmp/stripe-key.txt.age` is committed. Run:
|
|
270
|
-
|
|
271
|
-
```sh
|
|
272
|
-
chezmoi apply --verbose dot_tmp/stripe-key.txt
|
|
273
|
-
# Will show decrypt attempts and errors
|
|
274
|
-
```
|
|
275
|
-
|
|
276
|
-
## Next
|
|
277
|
-
|
|
278
|
-
- [Concept: Trust Model](../01-concepts/02-trust-model.md) — the security architecture
|
|
279
|
-
- [Reference: Secret operations](../03-reference/01-dot-cli.md#secrets)
|
|
280
|
-
- [Security: Secret management](../../security/SECRETS.md)
|
|
281
|
-
{% endraw %}
|
|
@@ -1,283 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
render_with_liquid: false
|
|
3
|
-
---
|
|
4
|
-
|
|
5
|
-
# Tutorial: Deploy to a Fleet
|
|
6
|
-
|
|
7
|
-
Roll out `.dotfiles` across multiple workstations and verify they're in sync.
|
|
8
|
-
|
|
9
|
-
## Scenario
|
|
10
|
-
|
|
11
|
-
You have three hosts:
|
|
12
|
-
|
|
13
|
-
- **macbook-t2** — your MacBook (current host, already installed)
|
|
14
|
-
- **surface-pro** — your Linux laptop (new install)
|
|
15
|
-
- **geekom-a9** — your desktop NUC (new install)
|
|
16
|
-
|
|
17
|
-
Goal: all three running identical `.dotfiles` with per-host customization, with auditable cross-host attestation.
|
|
18
|
-
|
|
19
|
-
## Step 1: Per-Host Install
|
|
20
|
-
|
|
21
|
-
On each new host:
|
|
22
|
-
|
|
23
|
-
```sh
|
|
24
|
-
bash -c "$(curl -fsSL https://raw.githubusercontent.com/sebastienrousseau/dotfiles/main/install.sh)"
|
|
25
|
-
```
|
|
26
|
-
|
|
27
|
-
During `chezmoi init`, answer with the host's preset:
|
|
28
|
-
|
|
29
|
-
- Surface Pro → `machine = "surface-pro"`
|
|
30
|
-
- Geekom A9 → `machine = "geekom-a9"`
|
|
31
|
-
|
|
32
|
-
## Step 2: Exchange Signing Keys
|
|
33
|
-
|
|
34
|
-
Each host has its own SSH ED25519 key. To verify commits and attestations across the fleet, publish each host's public key to every other host.
|
|
35
|
-
|
|
36
|
-
**On each host, copy the public key:**
|
|
37
|
-
|
|
38
|
-
```sh
|
|
39
|
-
cat ~/.ssh/id_ed25519.pub
|
|
40
|
-
# ssh-ed25519 AAAAC3N...jkl5 user@macbook-t2
|
|
41
|
-
```
|
|
42
|
-
|
|
43
|
-
**Collect all three keys. Append them to `~/.ssh/allowed_signers` on every host:**
|
|
44
|
-
|
|
45
|
-
```
|
|
46
|
-
user@macbook-t2 ssh-ed25519 AAAAC3N...jkl5
|
|
47
|
-
user@surface-pro ssh-ed25519 AAAAC3N...abc7
|
|
48
|
-
user@geekom-a9 ssh-ed25519 AAAAC3N...def9
|
|
49
|
-
```
|
|
50
|
-
|
|
51
|
-
Optionally commit `allowed_signers` as a template so all hosts receive updates via `dot update`:
|
|
52
|
-
|
|
53
|
-
```sh
|
|
54
|
-
# On macbook-t2
|
|
55
|
-
chezmoi add ~/.ssh/allowed_signers
|
|
56
|
-
git add -A && git commit -sS -m "feat(ssh): add fleet signing keys"
|
|
57
|
-
git push
|
|
58
|
-
```
|
|
59
|
-
|
|
60
|
-
Now every other host gets the updated list on `dot update`.
|
|
61
|
-
|
|
62
|
-
## Step 3: Share the Age Key (for Shared Secrets)
|
|
63
|
-
|
|
64
|
-
If you want shared secrets decrypted on all three hosts, each host must have an Age key recipient in `.sops.yaml`.
|
|
65
|
-
|
|
66
|
-
Option A: Share one key across all hosts (simpler, less granular).
|
|
67
|
-
Option B: Each host has its own key; all three are listed as recipients (better operational security).
|
|
68
|
-
|
|
69
|
-
For Option B:
|
|
70
|
-
|
|
71
|
-
```sh
|
|
72
|
-
# On macbook-t2 (already set up)
|
|
73
|
-
grep "public key:" ~/.config/age/keys.txt
|
|
74
|
-
|
|
75
|
-
# On surface-pro
|
|
76
|
-
age-keygen -o ~/.config/age/keys.txt
|
|
77
|
-
grep "public key:" ~/.config/age/keys.txt
|
|
78
|
-
|
|
79
|
-
# On geekom-a9
|
|
80
|
-
age-keygen -o ~/.config/age/keys.txt
|
|
81
|
-
grep "public key:" ~/.config/age/keys.txt
|
|
82
|
-
```
|
|
83
|
-
|
|
84
|
-
Add all three public keys to `.sops.yaml`:
|
|
85
|
-
|
|
86
|
-
```yaml
|
|
87
|
-
creation_rules:
|
|
88
|
-
- path_regex: \.sops\.yaml$
|
|
89
|
-
age: >-
|
|
90
|
-
age1aaa...111, # macbook-t2
|
|
91
|
-
age1bbb...222, # surface-pro
|
|
92
|
-
age1ccc...333 # geekom-a9
|
|
93
|
-
```
|
|
94
|
-
|
|
95
|
-
Re-encrypt existing secrets for the new recipients:
|
|
96
|
-
|
|
97
|
-
```sh
|
|
98
|
-
# On macbook-t2
|
|
99
|
-
find . -name '*.sops.yaml' -exec sops updatekeys {} \;
|
|
100
|
-
git add .sops.yaml dot_config/*.sops.yaml
|
|
101
|
-
git commit -sS -m "chore(secrets): add fleet recipients"
|
|
102
|
-
git push
|
|
103
|
-
```
|
|
104
|
-
|
|
105
|
-
Other hosts on `dot update` decrypt with their own private key automatically.
|
|
106
|
-
|
|
107
|
-
## Step 4: Verify Fleet Alignment
|
|
108
|
-
|
|
109
|
-
From any host:
|
|
110
|
-
|
|
111
|
-
```sh
|
|
112
|
-
dot fleet attest
|
|
113
|
-
```
|
|
114
|
-
|
|
115
|
-
Expected output:
|
|
116
|
-
|
|
117
|
-
```
|
|
118
|
-
Fleet Attestation — v0.2.501
|
|
119
|
-
|
|
120
|
-
Host Git SHA Policy Tools OK Drift Verified
|
|
121
|
-
-------------- ---------- --------- ---------- ------- --------
|
|
122
|
-
macbook-t2 abc123d 0x7f2a… ✓ 0 ✓
|
|
123
|
-
surface-pro abc123d 0x7f2a… ✓ 0 ✓
|
|
124
|
-
geekom-a9 abc123d 0x7f2a… ✓ 0 ✓
|
|
125
|
-
-------------- ---------- --------- ---------- ------- --------
|
|
126
|
-
FLEET STATUS: 3/3 aligned
|
|
127
|
-
```
|
|
128
|
-
|
|
129
|
-
If any row shows drift or missing verification:
|
|
130
|
-
|
|
131
|
-
```sh
|
|
132
|
-
# Check which host is out of sync
|
|
133
|
-
dot fleet diff
|
|
134
|
-
|
|
135
|
-
# SSH into the affected host and fix
|
|
136
|
-
ssh surface-pro
|
|
137
|
-
dot doctor && dot heal
|
|
138
|
-
dot update
|
|
139
|
-
```
|
|
140
|
-
|
|
141
|
-
## Step 5: Per-Host Customization
|
|
142
|
-
|
|
143
|
-
Each host has its own `~/.config/chezmoi/chezmoi.toml` — use it for things that shouldn't propagate:
|
|
144
|
-
|
|
145
|
-
```toml
|
|
146
|
-
# surface-pro's chezmoi.toml
|
|
147
|
-
[data]
|
|
148
|
-
machine = "surface-pro"
|
|
149
|
-
theme = "monterey-dark" # per-host default
|
|
150
|
-
default_shell = "fish"
|
|
151
|
-
terminal_font_size = 11 # smaller for HiDPI
|
|
152
|
-
```
|
|
153
|
-
|
|
154
|
-
```toml
|
|
155
|
-
# geekom-a9's chezmoi.toml
|
|
156
|
-
[data]
|
|
157
|
-
machine = "geekom-a9"
|
|
158
|
-
theme = "valley-dark" # different default
|
|
159
|
-
default_shell = "zsh"
|
|
160
|
-
terminal_font_size = 14 # larger for external 1440p
|
|
161
|
-
```
|
|
162
|
-
|
|
163
|
-
Both hosts render from the same templates, producing correct platform-appropriate output.
|
|
164
|
-
|
|
165
|
-
## Step 6: Fleet-Wide Updates
|
|
166
|
-
|
|
167
|
-
When you push a commit to main, each host pulls independently:
|
|
168
|
-
|
|
169
|
-
```sh
|
|
170
|
-
# On each host
|
|
171
|
-
dot update
|
|
172
|
-
```
|
|
173
|
-
|
|
174
|
-
`dot update` does:
|
|
175
|
-
|
|
176
|
-
1. `git pull --rebase --autostash` in `~/.dotfiles`
|
|
177
|
-
2. `chezmoi apply` with progress output
|
|
178
|
-
3. `dot heal` if apply detected drift
|
|
179
|
-
4. Reports changes applied
|
|
180
|
-
|
|
181
|
-
For simultaneous update across the fleet (requires SSH):
|
|
182
|
-
|
|
183
|
-
```sh
|
|
184
|
-
dot fleet sync
|
|
185
|
-
# Connects to each host in parallel
|
|
186
|
-
# Runs `dot update` via SSH
|
|
187
|
-
# Collects outcomes
|
|
188
|
-
```
|
|
189
|
-
|
|
190
|
-
## Step 7: Secrets Rotation
|
|
191
|
-
|
|
192
|
-
When a secret is compromised (or as part of routine rotation):
|
|
193
|
-
|
|
194
|
-
```sh
|
|
195
|
-
# 1. Edit the secret on any host
|
|
196
|
-
sops dot_config/credentials.sops.yaml
|
|
197
|
-
# Change the compromised value, save
|
|
198
|
-
|
|
199
|
-
# 2. Commit and push
|
|
200
|
-
git commit -sS -am "chore(secrets): rotate stripe key"
|
|
201
|
-
git push
|
|
202
|
-
|
|
203
|
-
# 3. All fleet hosts pick up the new value on next update
|
|
204
|
-
# On each host:
|
|
205
|
-
dot update
|
|
206
|
-
```
|
|
207
|
-
|
|
208
|
-
Since hosts all have the Age private key for themselves, decryption is automatic.
|
|
209
|
-
|
|
210
|
-
## Step 8: Decommission a Host
|
|
211
|
-
|
|
212
|
-
When retiring a host:
|
|
213
|
-
|
|
214
|
-
```sh
|
|
215
|
-
# 1. Remove the host's public key from allowed_signers
|
|
216
|
-
# Edit dot_ssh/allowed_signers.tmpl (on any host)
|
|
217
|
-
|
|
218
|
-
# 2. Remove the host's Age public key from .sops.yaml
|
|
219
|
-
|
|
220
|
-
# 3. Re-encrypt all SOPS files (remove the decommissioned recipient)
|
|
221
|
-
find . -name '*.sops.yaml' -exec sops updatekeys {} \;
|
|
222
|
-
|
|
223
|
-
# 4. Commit
|
|
224
|
-
git commit -sS -am "chore(fleet): decommission geekom-a9"
|
|
225
|
-
git push
|
|
226
|
-
|
|
227
|
-
# 5. On the decommissioned host: wipe the dotfiles state
|
|
228
|
-
rm -rf ~/.dotfiles ~/.local/bin/dot ~/.config/chezmoi ~/.config/age
|
|
229
|
-
```
|
|
230
|
-
|
|
231
|
-
## Troubleshooting
|
|
232
|
-
|
|
233
|
-
### "Fleet host unreachable"
|
|
234
|
-
|
|
235
|
-
`dot fleet` couldn't SSH to a host. Check:
|
|
236
|
-
|
|
237
|
-
```sh
|
|
238
|
-
ssh surface-pro 'dot version'
|
|
239
|
-
# If this fails, fix SSH connectivity first
|
|
240
|
-
```
|
|
241
|
-
|
|
242
|
-
### Drift on One Host
|
|
243
|
-
|
|
244
|
-
Run `dot heal` on that host:
|
|
245
|
-
|
|
246
|
-
```sh
|
|
247
|
-
ssh surface-pro 'dot heal'
|
|
248
|
-
```
|
|
249
|
-
|
|
250
|
-
If drift persists:
|
|
251
|
-
|
|
252
|
-
```sh
|
|
253
|
-
ssh surface-pro 'chezmoi diff | head -50'
|
|
254
|
-
# Inspect what's different
|
|
255
|
-
```
|
|
256
|
-
|
|
257
|
-
### Policy Hash Mismatch
|
|
258
|
-
|
|
259
|
-
One host has an older policy than the others. Usually means that host missed an update:
|
|
260
|
-
|
|
261
|
-
```sh
|
|
262
|
-
ssh surface-pro 'dot update'
|
|
263
|
-
```
|
|
264
|
-
|
|
265
|
-
### Attestation Signature Failed
|
|
266
|
-
|
|
267
|
-
The host's SSH key isn't in `~/.ssh/allowed_signers` on the verifying host. Fix by redistributing `allowed_signers`.
|
|
268
|
-
|
|
269
|
-
## Summary
|
|
270
|
-
|
|
271
|
-
A three-host fleet:
|
|
272
|
-
|
|
273
|
-
- Installs from one repository
|
|
274
|
-
- Has independent signing keys (each host verifies commits from others)
|
|
275
|
-
- Can share secrets across specific hosts via SOPS recipients
|
|
276
|
-
- Is auditable via `dot fleet attest`
|
|
277
|
-
- Updates independently with `dot update` (or in parallel with `dot fleet sync`)
|
|
278
|
-
|
|
279
|
-
## Next
|
|
280
|
-
|
|
281
|
-
- [Concept: Fleet Architecture](../01-concepts/04-fleet.md)
|
|
282
|
-
- [Reference: Fleet Commands](../03-reference/01-dot-cli.md#fleet)
|
|
283
|
-
- [Operations: Fleet Deployment](../../architecture/fleet-deployment.md)
|