@sebastienrousseau/dotfiles 0.2.500 → 0.2.502
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 +154 -0
- package/README.md +113 -45
- package/docs/.vitepress/reports/localization-readability-audit.md +4 -0
- package/docs/AI.md +8 -2
- package/docs/CNAME +1 -0
- package/docs/COPYRIGHT +1 -1
- package/docs/NAMING_CONVENTIONS.md +7 -0
- package/docs/README.md +4 -0
- package/docs/_config.yml +59 -0
- package/docs/adr/ADR-001-ci-cd-pipeline.md +17 -0
- package/docs/adr/ADR-002-shell-performance.md +9 -0
- package/docs/adr/ADR-003-security-first.md +18 -0
- package/docs/adr/ADR-004-cli-architecture.md +14 -0
- package/docs/adr/ADR-005-chezmoi-choice.md +10 -0
- package/docs/adr/ADR-006-shell-selection.md +9 -0
- package/docs/adr/ADR-007-multi-shell-parity.md +10 -1
- package/docs/adr/ADR-008-alias-system-architecture.md +10 -0
- package/docs/adr/ADR-009-wallpaper-driven-theming.md +131 -0
- package/docs/adr/ADR-010-starship-transient-prompt.md +144 -0
- package/docs/adr/ADR-011-nushell-tier3-keep.md +144 -0
- package/docs/adr/README.md +7 -0
- package/docs/architecture/ARCHITECTURE.md +4 -0
- package/docs/architecture/INTEROP.md +8 -0
- package/docs/architecture/REPO_LAYOUT.md +5 -1
- package/docs/architecture/WALKTHROUGH.md +4 -0
- package/docs/architecture/fleet-deployment.md +4 -0
- package/docs/archive/EUXIS_2026_REVIEW.md +11 -3
- package/docs/archive/LEGACY_ROADMAP.md +45 -27
- package/docs/archive/MILESTONE_v0.2.493.md +4 -0
- package/docs/archive/PLAN.md +46 -8
- package/docs/archive/REPO_AUDIT.md +8 -0
- package/docs/guides/INSTALL.md +4 -0
- package/docs/guides/NEOVIM_IDE_GUIDE.md +9 -0
- package/docs/guides/THEMING.md +8 -0
- package/docs/guides/TROUBLESHOOTING.md +28 -0
- package/docs/guides/WSL2_NIX_TROUBLESHOOTING.md +70 -1
- package/docs/index.md +6 -2
- package/docs/interop/A2A.md +7 -0
- package/docs/interop/POWERSHELL.md +102 -0
- package/docs/manual/00-introduction.md +5 -1
- package/docs/manual/01-concepts/01-architecture.md +4 -0
- package/docs/manual/01-concepts/02-trust-model.md +6 -2
- package/docs/manual/01-concepts/03-theme-engine.md +4 -0
- package/docs/manual/01-concepts/04-fleet.md +7 -1
- package/docs/manual/01-concepts/05-self-healing.md +8 -1
- package/docs/manual/02-tutorials/01-first-install.md +5 -0
- package/docs/manual/02-tutorials/02-add-wallpaper.md +5 -0
- package/docs/manual/02-tutorials/03-create-profile.md +6 -0
- package/docs/manual/02-tutorials/04-encrypt-secret.md +6 -0
- package/docs/manual/02-tutorials/05-deploy-fleet.md +5 -1
- package/docs/manual/03-reference/01-dot-cli.md +67 -45
- package/docs/manual/03-reference/02-config-files.md +8 -2
- package/docs/manual/03-reference/03-environment.md +4 -0
- package/docs/manual/03-reference/04-templates.md +7 -1
- package/docs/manual/03-reference/05-feature-flags.md +72 -3
- package/docs/manual/04-cookbook/01-recipes.md +4 -0
- package/docs/manual/04-cookbook/02-troubleshooting.md +32 -0
- package/docs/manual/04-cookbook/03-faq.md +8 -0
- package/docs/manual/05-appendices/A-platform-matrix.md +4 -0
- package/docs/manual/05-appendices/B-security-checklist.md +6 -0
- package/docs/manual/05-appendices/C-glossary.md +4 -0
- package/docs/manual/05-appendices/D-bibliography.md +5 -1
- package/docs/manual/05-appendices/E-license.md +4 -0
- package/docs/manual/_toc.yml +1 -1
- package/docs/manual/command-index.md +16 -8
- package/docs/manual/concept-index.md +4 -0
- package/docs/manual/index.md +66 -0
- package/docs/operations/ATTESTATION.md +5 -0
- package/docs/operations/CI_CADENCE.md +107 -0
- package/docs/operations/CI_COMPOSITES.md +156 -0
- package/docs/operations/COMPLETIONS.md +123 -0
- package/docs/operations/COVERAGE.md +182 -0
- package/docs/operations/DRIFT.md +107 -0
- package/docs/operations/HARD_AUDIT_2026.md +631 -0
- package/docs/operations/MAINTENANCE.md +5 -1
- package/docs/operations/MIGRATION.md +14 -6
- package/docs/operations/OPERATIONS.md +24 -0
- package/docs/operations/PERFORMANCE.md +133 -0
- package/docs/operations/REGISTRY.md +89 -0
- package/docs/operations/RELIABILITY.md +6 -0
- package/docs/operations/ROADMAP.md +36 -18
- package/docs/operations/ROADMAP_2026.md +665 -0
- package/docs/operations/TESTING.md +4 -0
- package/docs/operations/TRACEABILITY.md +7 -0
- package/docs/operations/TRUSTED_AGENT_WORKSTATION.md +4 -0
- package/docs/operations/VERSION_SYNC.md +54 -5
- package/docs/reference/ALIASES.md +7 -0
- package/docs/reference/ALIASES_CHEATSHEET.md +5 -1
- package/docs/reference/ALIASES_DEPRECATIONS.md +5 -1
- package/docs/reference/FEATURES.md +4 -0
- package/docs/reference/FONTS.md +4 -0
- package/docs/reference/POWERSHELL_PARITY.md +80 -0
- package/docs/reference/PROFILES.md +4 -0
- package/docs/reference/SCREENSHOTS.md +4 -0
- package/docs/reference/SCRIPTS.md +4 -0
- package/docs/reference/SUPPORT_MATRIX.md +10 -4
- package/docs/reference/THEMES.md +4 -0
- package/docs/reference/TOOLS.md +4 -0
- package/docs/reference/UTILS.md +16 -12
- package/docs/registry.json +6 -0
- package/docs/security/AI_ACT_COMPLIANCE.md +4 -0
- package/docs/security/AUDIT_BYPASS.md +103 -0
- package/docs/security/AUTOMATION_SECRETS.md +4 -0
- package/docs/security/CI_EGRESS_ALLOWLIST.md +127 -0
- package/docs/security/CI_PINNING.md +113 -0
- package/docs/security/COMMIT_SIGNING.md +138 -0
- package/docs/security/COMPLIANCE.md +5 -0
- package/docs/security/DEPS_DEV_EXCEPTIONS.md +86 -0
- package/docs/security/DISCLOSURE.md +130 -0
- package/docs/security/ENCRYPTION.md +5 -0
- package/docs/security/FMEA.md +4 -0
- package/docs/security/HISTORY_FILTERING.md +132 -0
- package/docs/security/INCIDENT_RESPONSE.md +4 -0
- package/docs/security/INSTALL_VERIFICATION.md +122 -0
- package/docs/security/KEYS.md +4 -0
- package/docs/security/KEY_ROTATION.md +85 -1
- package/docs/security/MCP_POLICY.md +9 -0
- package/docs/security/POLICY_RELEASES.md +4 -0
- package/docs/security/README.md +4 -0
- package/docs/security/SCORECARD.md +140 -0
- package/docs/security/SECRETS.md +12 -0
- package/docs/security/SECURITY.md +4 -0
- package/docs/security/SECURITY_CHECKLIST.md +11 -0
- package/docs/security/SHELL_EXEMPTIONS.md +145 -0
- package/docs/security/SOUP_REGISTER.md +4 -0
- package/docs/security/THREAT_MODEL.md +10 -0
- package/docs/security/VERIFICATION_VALIDATION.md +5 -1
- package/docs/security/security-pubkey.asc +15 -0
- package/docs/themes/README.md +4 -0
- package/docs/themes/VISUAL_INTEGRITY_REPORT.md +4 -0
- package/dot_config/ai/identity.md +3 -0
- package/dot_config/ai/patterns/architect.md +2 -0
- package/dot_config/ai/patterns/hardener.md +2 -0
- package/dot_config/ai/patterns/refactor.md +2 -0
- package/dot_config/alacritty/alacritty.toml.tmpl +3 -3
- package/dot_config/atuin/config.toml.tmpl +47 -0
- package/dot_config/dotfiles/agent-card.json +1 -1
- package/dot_config/dotfiles/boot/README.md +2 -0
- package/dot_config/dotfiles/grub/README.md +2 -0
- package/dot_config/dotfiles/lock/README.md +2 -0
- package/dot_config/fish/conf.d/direnv.fish +4 -0
- package/dot_config/fish/conf.d/init.fish.tmpl +21 -0
- package/dot_config/fish/conf.d/mise-activate.fish +5 -0
- package/dot_config/fish/functions/_cached_eval.fish +84 -11
- package/dot_config/fish/functions/_cached_eval_clear.fish +17 -0
- package/dot_config/foot/foot.ini.tmpl +3 -3
- package/dot_config/fuzzel/fuzzel.ini.tmpl +2 -2
- package/dot_config/ghostty/config.tmpl +3 -3
- package/dot_config/git/hooks/executable_commit-msg +146 -0
- package/dot_config/goose/config.yaml +2 -2
- package/dot_config/gtk-3.0/gtk.css.tmpl +2 -2
- package/dot_config/gtk-3.0/settings.ini.tmpl +2 -2
- package/dot_config/gtk-4.0/gtk.css.tmpl +2 -2
- package/dot_config/gtk-4.0/settings.ini.tmpl +2 -2
- package/dot_config/kitty/kitty.conf.tmpl +3 -3
- package/dot_config/mise/config.toml +1 -1
- package/dot_config/niri/config.kdl.tmpl +2 -2
- package/dot_config/nushell/cached_eval.nu +80 -0
- package/dot_config/nushell/env.nu.tmpl +21 -13
- package/dot_config/shell/00-core-paths.sh.tmpl +9 -1
- package/dot_config/shell/05-core-safety.sh +1 -0
- package/dot_config/shell/10-secrets.sh +1 -0
- package/dot_config/shell/40-fzf-defaults.sh.tmpl +1 -0
- package/dot_config/shell/40-ls-colors.sh +1 -0
- package/dot_config/shell/50-logic-functions-core.sh.tmpl +1 -0
- package/dot_config/shell/50-logic-functions.sh.tmpl +1 -0
- package/dot_config/shell/51-logic-functions-extra.sh.tmpl +1 -0
- package/dot_config/shell/90-ux-aliases.sh.tmpl +1 -0
- package/dot_config/shell/91-ux-aliases-lazy.sh.tmpl +1 -0
- package/dot_config/shell/README.md +25 -8
- package/dot_config/starship.toml.tmpl +2 -2
- package/dot_config/tmux/tmux.conf.tmpl +3 -3
- package/dot_config/user-dirs.dirs +1 -0
- package/dot_config/vscode/settings.json.tmpl +2 -2
- package/dot_config/waybar/config.jsonc.tmpl +2 -2
- package/dot_config/waybar/style.css.tmpl +2 -2
- package/dot_config/wezterm/wezterm.lua.tmpl +3 -3
- package/dot_config/zsh/dot_zshrc.tmpl +207 -17
- package/dot_config/zsh/rc.d/00-alias-shims.zsh +28 -6
- package/dot_config/zsh/rc.d/30-options.zsh.tmpl +27 -7
- package/dot_local/bin/executable_bm +2 -0
- package/dot_local/bin/executable_dot +56 -9
- package/dot_local/bin/executable_dot-bootstrap +0 -1
- package/dot_local/bin/executable_dot-load-benchmark +1 -1
- package/dot_local/bin/executable_dot-theme-sync +8 -8
- package/dot_local/bin/executable_notify +2 -0
- package/dot_local/bin/executable_open +2 -0
- package/dot_local/bin/executable_tour +4 -2
- package/dot_local/bin/executable_up +3 -1
- package/dot_local/share/man/man1/dot.1 +1 -1
- package/dot_local/share/zsh/completions/_dot +4 -0
- package/install.sh +53 -38
- package/package.json +1 -1
- package/scripts/ci/check-dangerous-chmod.sh +19 -0
- package/scripts/ci/check-deps-dev.sh +236 -0
- package/scripts/ci/check-insecure-tls.sh +61 -0
- package/scripts/ci/check-regression-traceability.sh +67 -0
- package/scripts/ci/check-shell-preamble.sh +106 -0
- package/scripts/ci/dot-cli-startup-bench.sh +126 -0
- package/scripts/ci/install-chezmoi-verified.sh +4 -1
- package/scripts/ci/lint-reusable-pins.sh +78 -0
- package/scripts/ci/run-coverage.sh +451 -0
- package/scripts/ci/validate-chezmoidata.sh +25 -0
- package/scripts/ci/windows-smoke-test.ps1 +136 -0
- package/scripts/diagnostics/doctor.sh +203 -5
- package/scripts/diagnostics/drift-dashboard.sh +177 -13
- package/scripts/diagnostics/health.sh +21 -4
- package/scripts/diagnostics/perf.sh +304 -77
- package/scripts/diagnostics/workstation-attestation.sh +6 -1
- package/scripts/dot/commands/agent.sh +33 -27
- package/scripts/dot/commands/agents.sh +325 -0
- package/scripts/dot/commands/ai.sh +75 -10
- package/scripts/dot/commands/aliases.sh +10 -8
- package/scripts/dot/commands/core.sh +10 -4
- package/scripts/dot/commands/fleet.sh +278 -3
- package/scripts/dot/commands/init.sh +184 -0
- package/scripts/dot/commands/meta.sh +7 -4
- package/scripts/dot/commands/registry.sh +263 -0
- package/scripts/dot/commands/tools.sh +49 -1
- package/scripts/dot/lib/bento.sh +2 -1
- package/scripts/dot/lib/log.sh +6 -0
- package/scripts/dot/lib/platform.sh +22 -8
- package/scripts/dot/lib/ui.sh +145 -2
- package/scripts/dot/lib/utils.sh +6 -1
- package/scripts/git-hooks/pre-commit-audit.sh +1 -1
- package/scripts/git-hooks/pre-push +66 -3
- package/scripts/lib/secrets_provider.sh +32 -6
- package/scripts/ops/heal-chezmoi.sh +41 -6
- package/scripts/ops/rollback.sh +14 -0
- package/scripts/qa/powershell-contract.ps1 +95 -0
- package/scripts/security/check-disclosure-key-expiry.sh +110 -0
- package/scripts/security/lock-configs.sh +11 -2
- package/scripts/theme/merge-wallpaper.sh +4 -0
- package/scripts/theme/switch.sh +20 -10
- package/scripts/version-sync.sh +3 -0
- package/dot_config/atuin/config.toml +0 -40
- package/dot_local/bin/__pycache__/executable_dot-load-benchmark-ptycpython-312.pyc +0 -0
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
# Encrypted Security Disclosure — Reporter Workflow
|
|
2
|
+
|
|
3
|
+
This document is for **external security researchers** who have found
|
|
4
|
+
an issue in this repository and want to report it without exposing
|
|
5
|
+
sensitive details (PII, exploit chains, internal infrastructure) in
|
|
6
|
+
transit or at rest on third-party servers.
|
|
7
|
+
|
|
8
|
+
If your report doesn't need encryption, please use
|
|
9
|
+
[GitHub Security Advisories](https://github.com/sebastienrousseau/dotfiles/security/advisories)
|
|
10
|
+
instead — it's faster and the GitHub-side audit trail is stronger.
|
|
11
|
+
|
|
12
|
+
## 1. Fetch the maintainer's public key
|
|
13
|
+
|
|
14
|
+
```sh
|
|
15
|
+
# Web Key Directory is the modern recommendation.
|
|
16
|
+
gpg --auto-key-locate clear,wkd \
|
|
17
|
+
--locate-keys security@sebastienrousseau.com
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
If WKD fails (offline keyserver, corporate proxy), download directly:
|
|
21
|
+
|
|
22
|
+
```sh
|
|
23
|
+
curl -fsSL \
|
|
24
|
+
https://sebastienrousseau.com/.well-known/openpgpkey/hu/qpzqfwauiwxnu1xrf5h47bunsho44p6f \
|
|
25
|
+
| gpg --import
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## 2. Verify the fingerprint
|
|
29
|
+
|
|
30
|
+
**Do not skip this step.** A MITM attacker can serve their own key.
|
|
31
|
+
|
|
32
|
+
```sh
|
|
33
|
+
gpg --fingerprint security@sebastienrousseau.com
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
The fingerprint must match the one published in
|
|
37
|
+
[`.github/SECURITY.md`](../../.github/SECURITY.md). Cross-verify
|
|
38
|
+
against the SSH signing key in `dot_config/git/allowed_signers.tmpl`
|
|
39
|
+
— the maintainer signs commits with the same identity, so both
|
|
40
|
+
fingerprints derive from the same identity claim.
|
|
41
|
+
|
|
42
|
+
If the two fingerprints don't match, **stop**. Open a private
|
|
43
|
+
[Security Advisory](https://github.com/sebastienrousseau/dotfiles/security/advisories/new)
|
|
44
|
+
and ask the maintainer to confirm the key out-of-band.
|
|
45
|
+
|
|
46
|
+
## 3. Encrypt your report
|
|
47
|
+
|
|
48
|
+
```sh
|
|
49
|
+
cat <<EOF | gpg --encrypt --armor \
|
|
50
|
+
--recipient security@sebastienrousseau.com \
|
|
51
|
+
--output disclosure.asc
|
|
52
|
+
Subject: <short description of the issue>
|
|
53
|
+
|
|
54
|
+
<full details — repro steps, affected versions, exploit, screenshots
|
|
55
|
+
referenced by base64-encoded attachments, contact info for follow-up>
|
|
56
|
+
EOF
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
Verify the output is an ASCII-armored OpenPGP message before sending:
|
|
60
|
+
|
|
61
|
+
```sh
|
|
62
|
+
head -1 disclosure.asc
|
|
63
|
+
# Expected: -----BEGIN PGP MESSAGE-----
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
## 4. Send
|
|
67
|
+
|
|
68
|
+
Attach `disclosure.asc` to an email to
|
|
69
|
+
**<security@sebastienrousseau.com>**.
|
|
70
|
+
|
|
71
|
+
Subject line: `[dotfiles] <severity>: <short description>` (no
|
|
72
|
+
encryption-sensitive content in the subject; mail relays log
|
|
73
|
+
subjects in plain text).
|
|
74
|
+
|
|
75
|
+
## 5. Acknowledgement
|
|
76
|
+
|
|
77
|
+
You should receive an acknowledgement within the SLA in
|
|
78
|
+
[`.github/SECURITY.md`](../../.github/SECURITY.md):
|
|
79
|
+
|
|
80
|
+
| Severity | Initial response |
|
|
81
|
+
|---|---|
|
|
82
|
+
| Critical | 24 hours |
|
|
83
|
+
| High | 72 hours |
|
|
84
|
+
| Medium | 5 business days |
|
|
85
|
+
| Low | 10 business days |
|
|
86
|
+
|
|
87
|
+
The acknowledgement will be signed with the same key you encrypted
|
|
88
|
+
to. Verify the signature:
|
|
89
|
+
|
|
90
|
+
```sh
|
|
91
|
+
gpg --verify response.asc
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
If you don't receive an acknowledgement in the SLA window, or the
|
|
95
|
+
acknowledgement signature doesn't verify, escalate by:
|
|
96
|
+
|
|
97
|
+
1. Opening a private GitHub Security Advisory.
|
|
98
|
+
2. DM-ing the maintainer on Mastodon: `@sebastienrousseau@hachyderm.io`.
|
|
99
|
+
|
|
100
|
+
## 6. After disclosure
|
|
101
|
+
|
|
102
|
+
The maintainer commits to:
|
|
103
|
+
|
|
104
|
+
- A fix timeline communicated within the SLA.
|
|
105
|
+
- A CVE assignment when severity ≥ Medium and the issue affects
|
|
106
|
+
published releases (npm package, release tarballs).
|
|
107
|
+
- Public credit at fix time in the release notes (unless you
|
|
108
|
+
request anonymity at report time).
|
|
109
|
+
- A backport to any actively-supported release line listed in
|
|
110
|
+
`.github/SECURITY.md`.
|
|
111
|
+
|
|
112
|
+
## What NOT to do
|
|
113
|
+
|
|
114
|
+
- Don't post details in a public issue, even a "I found a bug, ping
|
|
115
|
+
me for details" placeholder — every public reference is a tip-off
|
|
116
|
+
to attackers monitoring the repo.
|
|
117
|
+
- Don't disclose to third parties (other dotfile maintainers,
|
|
118
|
+
security mailing lists, blog posts) before the embargo lifts.
|
|
119
|
+
- Don't access data or systems you don't own.
|
|
120
|
+
- Don't run automated scans against `*.sebastienrousseau.com` that
|
|
121
|
+
exceed normal browser-like traffic.
|
|
122
|
+
|
|
123
|
+
## See also
|
|
124
|
+
|
|
125
|
+
- [`.github/SECURITY.md`](../../.github/SECURITY.md) — policy
|
|
126
|
+
overview + fingerprint.
|
|
127
|
+
- [`docs/security/KEY_ROTATION.md`](KEY_ROTATION.md) — schedule for
|
|
128
|
+
when the disclosure key is rotated.
|
|
129
|
+
- [`docs/security/AUDIT_BYPASS.md`](AUDIT_BYPASS.md) — separate flow
|
|
130
|
+
for the pre-push audit bypass (not for disclosure).
|
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
render_with_liquid: false
|
|
3
|
+
---
|
|
4
|
+
|
|
1
5
|
# Secrets Encryption with SOPS and age
|
|
2
6
|
|
|
3
7
|
## Quick Start
|
|
@@ -30,6 +34,7 @@ sops secrets.sops.yaml
|
|
|
30
34
|
## Recovery
|
|
31
35
|
|
|
32
36
|
If you lose your age private key, follow these steps:
|
|
37
|
+
|
|
33
38
|
1. Create a new key: `age-keygen -o ~/.config/sops/age/keys.txt`
|
|
34
39
|
2. Re-encrypt all secrets with the new public key.
|
|
35
40
|
3. Update `.sops.yaml` with the new public key.
|
package/docs/security/FMEA.md
CHANGED
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
render_with_liquid: false
|
|
3
|
+
---
|
|
4
|
+
|
|
1
5
|
# Failure Mode and Effects Analysis (FMEA)
|
|
2
6
|
|
|
3
7
|
Systematic risk assessment of the chezmoi-managed dotfiles repository per IEC 60812 methodology. Identifies failure modes, quantifies risk priority, and documents mitigations across all configuration management subsystems.
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
---
|
|
2
|
+
render_with_liquid: false
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# Atuin History Filtering
|
|
6
|
+
|
|
7
|
+
This page documents how high-risk command patterns are excluded from
|
|
8
|
+
Atuin shell history, how to extend the list for your machine, and the
|
|
9
|
+
trade-offs of filter design.
|
|
10
|
+
|
|
11
|
+
## Why
|
|
12
|
+
|
|
13
|
+
Atuin syncs shell history across machines and exposes a fuzzy-search UI
|
|
14
|
+
(`Ctrl-R`). Without a filter, every command — including ones that
|
|
15
|
+
contain secrets passed inline (`AWS_SECRET_ACCESS_KEY=...`, `op run`,
|
|
16
|
+
`vault read`, `curl -H 'Authorization: Bearer ...'`) — is captured,
|
|
17
|
+
synced to a remote service, and made grep-able.
|
|
18
|
+
|
|
19
|
+
The `history_filter` array in `~/.config/atuin/config.toml` lists
|
|
20
|
+
regular expressions that, if matched, prevent Atuin from recording the
|
|
21
|
+
command at all (it never enters the local DB, and therefore never
|
|
22
|
+
syncs).
|
|
23
|
+
|
|
24
|
+
## How it ships
|
|
25
|
+
|
|
26
|
+
Patterns are sourced from `.chezmoidata/secrets-patterns.toml` and
|
|
27
|
+
materialised into `~/.config/atuin/config.toml` by the chezmoi template
|
|
28
|
+
at `dot_config/atuin/config.toml.tmpl`.
|
|
29
|
+
|
|
30
|
+
```
|
|
31
|
+
.chezmoidata/secrets-patterns.toml
|
|
32
|
+
└── [atuin.history_filter]
|
|
33
|
+
defaults = [...] # audited baseline (this repo)
|
|
34
|
+
extra = [...] # empty by default; populated per machine
|
|
35
|
+
|
|
36
|
+
dot_config/atuin/config.toml.tmpl
|
|
37
|
+
└── chezmoi apply ─────► ~/.config/atuin/config.toml
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
Run `chezmoi apply ~/.config/atuin/config.toml` after editing the
|
|
41
|
+
defaults; `dot doctor` reports the count of deployed patterns and
|
|
42
|
+
fails loud if the block is missing.
|
|
43
|
+
|
|
44
|
+
## What's filtered by default
|
|
45
|
+
|
|
46
|
+
The audited baseline covers:
|
|
47
|
+
|
|
48
|
+
- Generic env-var exports: `^export (SECRET|TOKEN|PASSWORD|API_KEY|AWS_)`,
|
|
49
|
+
`^PASSWORD=`, `^[A-Z_]+_TOKEN=`, `^[A-Z_]+_KEY=`.
|
|
50
|
+
- Cloud provider auth: `aws ... configure|auth|login`, `gcloud auth ...`,
|
|
51
|
+
`az login`, `kubectl ... --kubeconfig`.
|
|
52
|
+
- AI provider keys: Anthropic, OpenAI, Gemini, Mistral.
|
|
53
|
+
- SaaS secrets: Stripe, GitHub PAT (`GH_TOKEN`, `GITHUB_TOKEN`), `NPM_TOKEN`,
|
|
54
|
+
`CARGO_REGISTRY_TOKEN`.
|
|
55
|
+
- Authorization headers (`curl -H 'Authorization: ...'`).
|
|
56
|
+
- Embedded creds in git URLs (`git clone https://user:pass@...`).
|
|
57
|
+
- Secret managers: `vault`, `op` (1Password), `chamber`.
|
|
58
|
+
- Key material: `ssh-keygen`, `ssh-add`, `gpg --import|--export-secret`,
|
|
59
|
+
`age -d|-e --passphrase`.
|
|
60
|
+
- DB connection strings with inline creds
|
|
61
|
+
(`postgres|mysql|mongodb|redis://user:pass@host`).
|
|
62
|
+
|
|
63
|
+
See `.chezmoidata/secrets-patterns.toml` for the canonical list.
|
|
64
|
+
|
|
65
|
+
## Adding per-host patterns
|
|
66
|
+
|
|
67
|
+
Each contributor or machine can extend the list without editing the
|
|
68
|
+
shared template. In `~/.config/chezmoi/chezmoi.toml`:
|
|
69
|
+
|
|
70
|
+
```toml
|
|
71
|
+
[data.atuin.history_filter]
|
|
72
|
+
extra = [
|
|
73
|
+
"^my-private-tool ",
|
|
74
|
+
"^OUR_CORP_API_KEY=",
|
|
75
|
+
"tailscale up --auth-key=",
|
|
76
|
+
]
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
Then re-apply:
|
|
80
|
+
|
|
81
|
+
```bash
|
|
82
|
+
chezmoi apply ~/.config/atuin/config.toml
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
The `extra` patterns are appended to the defaults in the deployed
|
|
86
|
+
config.
|
|
87
|
+
|
|
88
|
+
## Adding a pattern to the project defaults
|
|
89
|
+
|
|
90
|
+
Edit `.chezmoidata/secrets-patterns.toml` and add a regex to
|
|
91
|
+
`[atuin.history_filter].defaults`. Then:
|
|
92
|
+
|
|
93
|
+
1. Add a fixture command to `tests/unit/secrets/test_atuin_history_filter.sh`
|
|
94
|
+
under `LEAKED_FIXTURES` — your new pattern must catch at least one
|
|
95
|
+
real-shape command.
|
|
96
|
+
2. Run the test: `bash tests/unit/secrets/test_atuin_history_filter.sh`.
|
|
97
|
+
3. Add a benign-fixture if your regex is broad enough to risk false
|
|
98
|
+
positives.
|
|
99
|
+
4. Open a PR; CI runs the same test.
|
|
100
|
+
|
|
101
|
+
## Trade-offs
|
|
102
|
+
|
|
103
|
+
`history_filter` is a deny-list. Two classes of failure to design
|
|
104
|
+
around:
|
|
105
|
+
|
|
106
|
+
- **False positives**: an overly broad regex hides commands the user
|
|
107
|
+
needs to recall. Mitigation: every new pattern must include a
|
|
108
|
+
fixture under `BENIGN_FIXTURES` that the regex correctly does *not*
|
|
109
|
+
match.
|
|
110
|
+
- **False negatives**: a new secret format ships, no pattern matches,
|
|
111
|
+
the secret lands in history. Mitigation: the OpenSSF Scorecard
|
|
112
|
+
workflow (issue #869) and the nightly drift detector (#875) will
|
|
113
|
+
surface new exposure surfaces; review them quarterly.
|
|
114
|
+
|
|
115
|
+
`history_filter` does not replace:
|
|
116
|
+
|
|
117
|
+
- A real secret manager (`age`/`sops`, 1Password, Vault) — see
|
|
118
|
+
`docs/security/ENCRYPTION.md`.
|
|
119
|
+
- Pre-commit `gitleaks` / `detect-secrets` scans — see
|
|
120
|
+
`config/pre-commit-config.yaml`.
|
|
121
|
+
- Server-side audit logging — see `docs/security/COMPLIANCE.md`.
|
|
122
|
+
|
|
123
|
+
It's the last line of defence against accidental command-line capture,
|
|
124
|
+
not the first.
|
|
125
|
+
|
|
126
|
+
## References
|
|
127
|
+
|
|
128
|
+
- Atuin config schema: <https://atuin.sh/docs/config>
|
|
129
|
+
- Chezmoi template data: <https://www.chezmoi.io/reference/templates/>
|
|
130
|
+
- Issue #872 (this hardening)
|
|
131
|
+
- `tests/unit/secrets/test_atuin_history_filter.sh` (pattern-coverage test)
|
|
132
|
+
- `scripts/diagnostics/doctor.sh` — "Atuin History Filter" section
|
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
render_with_liquid: false
|
|
3
|
+
---
|
|
4
|
+
|
|
1
5
|
# Incident Response Plan
|
|
2
6
|
|
|
3
7
|
Incident response procedures for the dotfiles repository. Covers supply chain compromise, secrets exposure, configuration drift, tool tampering, and CI pipeline attacks. Based on NIST SP 800-61 Rev. 2 (Computer Security Incident Handling Guide).
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
---
|
|
2
|
+
render_with_liquid: false
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# Install Verification
|
|
6
|
+
|
|
7
|
+
This page documents what gets verified during `install.sh` execution,
|
|
8
|
+
why those checks matter, and how to obtain the per-release expected
|
|
9
|
+
hashes used by the verified-install path in the README.
|
|
10
|
+
|
|
11
|
+
Managed under
|
|
12
|
+
[#858](https://github.com/sebastienrousseau/dotfiles/issues/858).
|
|
13
|
+
|
|
14
|
+
## What is verified
|
|
15
|
+
|
|
16
|
+
`install.sh` performs three classes of verification before doing
|
|
17
|
+
anything destructive:
|
|
18
|
+
|
|
19
|
+
### 1. The installer itself (verified path)
|
|
20
|
+
|
|
21
|
+
The README's **Verified install** snippet pins to a release tag
|
|
22
|
+
(e.g. `v0.2.501`), downloads the installer, and asks `shasum -a 256
|
|
23
|
+
-c` (or `sha256sum -c`) to check the contents against an expected
|
|
24
|
+
hash. If the hash doesn't match, the verify step exits non-zero and
|
|
25
|
+
the install never starts.
|
|
26
|
+
|
|
27
|
+
### 2. The `chezmoi` binary (always verified when possible)
|
|
28
|
+
|
|
29
|
+
`install.sh` prefers the bundled checksum-verified installer at
|
|
30
|
+
`scripts/ci/install-chezmoi-verified.sh`, which:
|
|
31
|
+
|
|
32
|
+
- Resolves the platform (`uname -s` + `uname -m`).
|
|
33
|
+
- Downloads `chezmoi_<version>_<os>_<arch>.tar.gz` AND the matching
|
|
34
|
+
`chezmoi_<version>_checksums.txt` from the official
|
|
35
|
+
`twpayne/chezmoi` GitHub release.
|
|
36
|
+
- Greps the checksum file for the asset's expected SHA256.
|
|
37
|
+
- Verifies the downloaded tarball against that SHA256 using
|
|
38
|
+
`shasum -a 256 -c` / `sha256sum -c`.
|
|
39
|
+
- Aborts with a clear error if the asset isn't in the checksum file
|
|
40
|
+
or the verification fails.
|
|
41
|
+
|
|
42
|
+
When the verified installer isn't available (e.g. the curl one-liner
|
|
43
|
+
mode where `install.sh` is fetched in isolation), the code falls back
|
|
44
|
+
to `get.chezmoi.io` with two defense-in-depth checks:
|
|
45
|
+
|
|
46
|
+
- The downloaded installer must be smaller than 100 KiB (sanity
|
|
47
|
+
guard against a CDN serving an arbitrary binary).
|
|
48
|
+
- The first line must start with `#!/` (must look like a shell
|
|
49
|
+
script).
|
|
50
|
+
|
|
51
|
+
These are weaker than a SHA256 check, but they catch the obvious
|
|
52
|
+
"installer got replaced with a 50 MB malicious binary" failure mode.
|
|
53
|
+
|
|
54
|
+
### 3. The chezmoi source tree
|
|
55
|
+
|
|
56
|
+
After chezmoi is installed, `install.sh` clones the dotfiles repo
|
|
57
|
+
itself. This isn't currently cryptographically verified beyond Git's
|
|
58
|
+
own object integrity, but commits in the repo are SSH-signed and
|
|
59
|
+
branch protection on `master` requires signed commits (see #853).
|
|
60
|
+
|
|
61
|
+
## How to obtain per-release hashes
|
|
62
|
+
|
|
63
|
+
The verified-install snippet uses the SHA256 of the `install.sh`
|
|
64
|
+
file *as it exists at the release tag*. To regenerate after a release:
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
git switch master
|
|
68
|
+
git pull
|
|
69
|
+
NEW_TAG="v0.2.502" # adjust
|
|
70
|
+
git tag -s "$NEW_TAG" -m "..."
|
|
71
|
+
git push origin "$NEW_TAG"
|
|
72
|
+
|
|
73
|
+
# Compute the hash:
|
|
74
|
+
shasum -a 256 install.sh
|
|
75
|
+
|
|
76
|
+
# Update README.md's verified-install snippet with the new hash + tag.
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
A follow-up automation (tracked at the bottom of this page) will
|
|
80
|
+
publish a `.sha256` sibling next to the install.sh asset in GitHub
|
|
81
|
+
Releases so the README snippet can reference a stable URL instead
|
|
82
|
+
of a hardcoded value.
|
|
83
|
+
|
|
84
|
+
## What to do if the hash doesn't match
|
|
85
|
+
|
|
86
|
+
If you run the verified install and `shasum -a 256 -c` reports
|
|
87
|
+
`FAILED`:
|
|
88
|
+
|
|
89
|
+
1. **Don't run the installer.** The hash mismatch means either the
|
|
90
|
+
release was retagged (rare) or someone is MITM-ing your download.
|
|
91
|
+
2. Check the [Releases page](https://github.com/sebastienrousseau/dotfiles/releases)
|
|
92
|
+
for the matching tag. The per-release `install.sh` SHA is
|
|
93
|
+
embedded in the README at the time of that release; you can also
|
|
94
|
+
recover it from the git history of `README.md`.
|
|
95
|
+
3. If the README hash is stale (release was retagged for legitimate
|
|
96
|
+
reasons), `git log` on `install.sh` will show the change. Inspect
|
|
97
|
+
the diff before trusting a new hash.
|
|
98
|
+
|
|
99
|
+
## What is NOT verified (yet)
|
|
100
|
+
|
|
101
|
+
- **Cosign keyless signature** on `install.sh` — tracked separately
|
|
102
|
+
under #876.
|
|
103
|
+
- **deps.dev attestation lookup** for npm/Python deps used during
|
|
104
|
+
install — tracked under #877.
|
|
105
|
+
- **Reproducible-build guarantee** for the chezmoi binary itself —
|
|
106
|
+
out of scope; rely on the upstream project's release engineering.
|
|
107
|
+
|
|
108
|
+
## Negative-test coverage
|
|
109
|
+
|
|
110
|
+
`tests/unit/install/test_install_chezmoi_verified.sh` exercises the
|
|
111
|
+
verification path with a deliberately tampered checksum to confirm
|
|
112
|
+
the installer aborts. The test ships with the repo and runs on every
|
|
113
|
+
PR.
|
|
114
|
+
|
|
115
|
+
## References
|
|
116
|
+
|
|
117
|
+
- `install.sh` — the entry point.
|
|
118
|
+
- `scripts/ci/install-chezmoi-verified.sh` — the SHA256-pinned
|
|
119
|
+
chezmoi installer.
|
|
120
|
+
- `tests/unit/install/test_install_chezmoi_verified.sh` — the
|
|
121
|
+
negative test.
|
|
122
|
+
- Issue [#858](https://github.com/sebastienrousseau/dotfiles/issues/858).
|
package/docs/security/KEYS.md
CHANGED
|
@@ -1,6 +1,90 @@
|
|
|
1
|
+
---
|
|
2
|
+
render_with_liquid: false
|
|
3
|
+
---
|
|
4
|
+
|
|
1
5
|
# Key Rotation Guide
|
|
2
6
|
|
|
3
|
-
This
|
|
7
|
+
This page tracks two distinct key lifecycles:
|
|
8
|
+
|
|
9
|
+
1. **Disclosure key** — the GPG key reporters use to encrypt vulnerability reports to the maintainer. Single key, public, rotated annually or on compromise. Source of truth for the active fingerprint is `.github/SECURITY.md`.
|
|
10
|
+
2. **Secrets encryption keys** — the Age and SOPS keys that protect encrypted dotfiles in this repo. Multiple keys, per-machine, rotated annually or on personnel / device change.
|
|
11
|
+
|
|
12
|
+
Both sections live here so a single audit can confirm the project's
|
|
13
|
+
posture across encrypted-disclosure-in and encrypted-secrets-at-rest.
|
|
14
|
+
|
|
15
|
+
## Disclosure Key (GPG)
|
|
16
|
+
|
|
17
|
+
Closes the rotation half of [#870](https://github.com/sebastienrousseau/dotfiles/issues/870).
|
|
18
|
+
|
|
19
|
+
### Active key
|
|
20
|
+
|
|
21
|
+
| Field | Value |
|
|
22
|
+
|---|---|
|
|
23
|
+
| Identity | `security@sebastienrousseau.com` |
|
|
24
|
+
| Fingerprint | `55AFAD364FD9DB3819E61F0C8D688FAFA9144693` |
|
|
25
|
+
| Algorithm | ED25519 signing primary + CV25519 encryption subkey |
|
|
26
|
+
| Created | 2026-05-16 |
|
|
27
|
+
| Expires | 2029-05-15 (3 years from creation) |
|
|
28
|
+
| WKD URL | <https://sebastienrousseau.com/.well-known/openpgpkey/hu/qpzqfwauiwxnu1xrf5h47bunsho44p6f> |
|
|
29
|
+
| Cross-reference | matches the SSH signing key in `dot_config/git/allowed_signers.tmpl` |
|
|
30
|
+
|
|
31
|
+
### Rotation triggers
|
|
32
|
+
|
|
33
|
+
| Trigger | Response time | Action |
|
|
34
|
+
|---|---|---|
|
|
35
|
+
| Annual cadence | Within 30 days of expiry | Generate new key, publish, sign transition statement with the old key, archive old key below. |
|
|
36
|
+
| Suspected compromise | Same day | Revoke immediately, publish revocation cert to WKD, replay in-flight encrypted disclosures with the new key. |
|
|
37
|
+
| Algorithm deprecation | Within 90 days of advisory | Generate replacement on a stronger algorithm; follow annual-cadence steps. |
|
|
38
|
+
| Maintainer change | Same day as handover | Old maintainer signs a transition statement; old key revoked 30 days after handover. |
|
|
39
|
+
|
|
40
|
+
### Rotation procedure
|
|
41
|
+
|
|
42
|
+
1. Generate the new key (air-gapped where possible):
|
|
43
|
+
|
|
44
|
+
```sh
|
|
45
|
+
gpg --quick-generate-key \
|
|
46
|
+
"Sebastien Rousseau (Security) <security@sebastienrousseau.com>" \
|
|
47
|
+
ed25519 sign 1y
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
2. Sign a transition statement with the OLD key:
|
|
51
|
+
|
|
52
|
+
```sh
|
|
53
|
+
gpg --clearsign <<EOF
|
|
54
|
+
Transition statement, $(date -u +%Y-%m-%dT%H:%M:%SZ).
|
|
55
|
+
The disclosure key for security@sebastienrousseau.com rotates from:
|
|
56
|
+
OLD: <old-fingerprint>
|
|
57
|
+
NEW: <new-fingerprint>
|
|
58
|
+
Encrypted reports sent to either key during the 30-day overlap
|
|
59
|
+
will be accepted. After <UTC-cutoff>, only the new key is honoured.
|
|
60
|
+
EOF
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
3. Publish the new key to:
|
|
64
|
+
- `sebastienrousseau.com/.well-known/openpgpkey/hu/` (WKD)
|
|
65
|
+
- the maintainer's keyoxide profile if applicable
|
|
66
|
+
|
|
67
|
+
4. Update the "Active key" table above with the new fingerprint and
|
|
68
|
+
move the previous row into the "Historical disclosure keys"
|
|
69
|
+
table below with the actual revocation date.
|
|
70
|
+
|
|
71
|
+
5. Commit, signing with both old and new keys during the overlap:
|
|
72
|
+
|
|
73
|
+
```sh
|
|
74
|
+
git commit -S -m "security(key): rotate disclosure key $(date +%Y-%m)" \
|
|
75
|
+
-m "$(cat transition.asc)"
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
6. After the 30-day overlap, revoke the old key and publish the
|
|
79
|
+
revocation cert to the same WKD endpoint.
|
|
80
|
+
|
|
81
|
+
### Historical disclosure keys
|
|
82
|
+
|
|
83
|
+
| From | Until | Fingerprint | Reason for rotation |
|
|
84
|
+
|---|---|---|---|
|
|
85
|
+
| *(none yet — first key)* | *—* | *—* | *—* |
|
|
86
|
+
|
|
87
|
+
---
|
|
4
88
|
|
|
5
89
|
## Age Key Rotation
|
|
6
90
|
|
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
render_with_liquid: false
|
|
3
|
+
---
|
|
4
|
+
|
|
1
5
|
# MCP Policy
|
|
2
6
|
|
|
3
7
|
MCP is treated as a controlled execution boundary.
|
|
@@ -7,6 +11,7 @@ MCP is treated as a controlled execution boundary.
|
|
|
7
11
|
The tracked default is `strict-local`.
|
|
8
12
|
|
|
9
13
|
Properties:
|
|
14
|
+
|
|
10
15
|
- local-first
|
|
11
16
|
- least privilege
|
|
12
17
|
- no broad filesystem roots
|
|
@@ -21,6 +26,7 @@ Approved package pins live in [mcp-lock.json](/home/seb/.dotfiles/dot_config/dot
|
|
|
21
26
|
Tracked server registry entries live in [mcp-registry.json](/home/seb/.dotfiles/dot_config/dotfiles/mcp-registry.json).
|
|
22
27
|
|
|
23
28
|
Current defaults:
|
|
29
|
+
|
|
24
30
|
- Allowed launchers: `npx`, `node`, `uvx`
|
|
25
31
|
- Trusted transports: `stdio`, `http`
|
|
26
32
|
- Blocked filesystem roots: `/`, `/home`, `/Users`
|
|
@@ -45,6 +51,7 @@ The JSON form is the audit artifact for CI, release validation, and workstation
|
|
|
45
51
|
## Change control
|
|
46
52
|
|
|
47
53
|
Any change to MCP policy requires:
|
|
54
|
+
|
|
48
55
|
1. A signed commit
|
|
49
56
|
2. A matching test update
|
|
50
57
|
3. A release note if the effective trust boundary changes
|
|
@@ -55,11 +62,13 @@ Any change to MCP policy requires:
|
|
|
55
62
|
Phase 2 adds explicit package locking for default MCP servers.
|
|
56
63
|
|
|
57
64
|
Current approved refs:
|
|
65
|
+
|
|
58
66
|
- `mcp-server-git@2025.1.14`
|
|
59
67
|
- `@modelcontextprotocol/server-memory@2025.8.4`
|
|
60
68
|
- `mcp-server-sqlite@2025.1.14`
|
|
61
69
|
|
|
62
70
|
`dot mcp --strict` and `dot mcp -s` now verify that:
|
|
71
|
+
|
|
63
72
|
- package refs are version-pinned
|
|
64
73
|
- the pinned refs match the tracked lock manifest
|
|
65
74
|
- non-approved package refs are rejected in strict mode
|