@sebastienrousseau/dotfiles 0.2.520 → 0.2.522
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 +52 -0
- package/LICENSE-APACHE +190 -0
- package/LICENSE-MIT +21 -0
- package/README.md +43 -37
- package/install.sh +76 -10
- package/package.json +7 -7
- 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/ARCHITECTURE.md +0 -117
- package/docs/CNAME +0 -1
- package/docs/CONFIG_STRATEGY.md +0 -124
- package/docs/COPYRIGHT +0 -7
- package/docs/ECOSYSTEM.md +0 -220
- package/docs/GOLD-STANDARD-AUDIT.md +0 -352
- package/docs/GOVERNANCE.md +0 -98
- package/docs/MAINTAINERS.md +0 -41
- package/docs/MINIMUM-TOOLCHAIN.md +0 -100
- 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 -20
- 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/MACOS_ICLOUD_SYMLINKS.md +0 -121
- 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 -475
- 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 -175
- package/docs/manual/concept-index.md +0 -170
- package/docs/manual/index.md +0 -66
- package/docs/migration/README.md +0 -81
- package/docs/migration/from-bare-git-repo.md +0 -156
- package/docs/migration/from-gnu-stow.md +0 -165
- package/docs/migration/from-plain-chezmoi.md +0 -148
- package/docs/migration/from-yadm.md +0 -187
- 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/PERFORMANCE_BUDGETS.md +0 -196
- 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 -44
- package/docs/operations/TRUSTED_AGENT_WORKSTATION.md +0 -65
- package/docs/operations/VERSION_SYNC.md +0 -393
- package/docs/packaging.md +0 -222
- 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/FEATURE-MATRIX.md +0 -646
- 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 -243
- 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 -209
- 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 -165
- package/scripts/diagnostics/aliases-cheatsheet.sh +0 -74
- package/scripts/diagnostics/aliases-manifest.sh +0 -77
- package/scripts/diagnostics/attest-verify.sh +0 -147
- package/scripts/diagnostics/benchmark.sh +0 -408
- package/scripts/diagnostics/conflicts.sh +0 -73
- package/scripts/diagnostics/doctor-unified.sh +0 -43
- package/scripts/diagnostics/doctor.sh +0 -797
- package/scripts/diagnostics/drift-dashboard.sh +0 -203
- package/scripts/diagnostics/health.sh +0 -656
- 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 -120
- 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 -212
- package/scripts/dot/commands/agent.sh +0 -535
- package/scripts/dot/commands/agents.sh +0 -352
- package/scripts/dot/commands/ai.sh +0 -600
- package/scripts/dot/commands/aliases.sh +0 -277
- package/scripts/dot/commands/appearance.sh +0 -110
- package/scripts/dot/commands/completion.sh +0 -171
- 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 -711
- 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 -438
- package/scripts/dot/commands/patterns.sh +0 -55
- package/scripts/dot/commands/registry.sh +0 -455
- 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 -570
- 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 -200
- package/scripts/nvim/headless-upgrade.lua +0 -81
- 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 -67
- 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 -613
- package/scripts/ops/setup.sh +0 -138
- package/scripts/ops/teleport.sh +0 -34
- package/scripts/qa/check-feature-matrix.sh +0 -296
- package/scripts/qa/check-version-consistency.sh +0 -12
- package/scripts/qa/coverage-baseline.sh +0 -61
- package/scripts/qa/docs-coverage.sh +0 -118
- 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 -124
- package/scripts/qa/validate-examples.sh +0 -90
- 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 -552
- 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 -1020
- 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 -603
- package/scripts/theme/switch.sh +0 -476
- 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/verify-release-versions +0 -156
- package/scripts/version-sync.sh +0 -714
- 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
package/docs/security/KEYS.md
DELETED
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
render_with_liquid: false
|
|
3
|
-
---
|
|
4
|
-
|
|
5
|
-
# Keybindings
|
|
6
|
-
|
|
7
|
-
This is the single source of truth for navigation and muscle-memory shortcuts
|
|
8
|
-
across the dotfiles stack. Keep it concise and consistent.
|
|
9
|
-
|
|
10
|
-
## Zsh
|
|
11
|
-
|
|
12
|
-
- `Ctrl+R`: History search (`fzf`/`atuin` if enabled)
|
|
13
|
-
- `Ctrl+P` / `Ctrl+N`: History prefix search (up/down)
|
|
14
|
-
|
|
15
|
-
## Tmux (prefix = `Ctrl-a`)
|
|
16
|
-
|
|
17
|
-
- `Prefix + r`: Reload config
|
|
18
|
-
- `Prefix + N`: New window
|
|
19
|
-
- `Prefix + a` / `Tab`: Last window
|
|
20
|
-
- `Prefix + %`: Split vertical (current path)
|
|
21
|
-
- `Prefix + "`: Split horizontal (current path)
|
|
22
|
-
- `Prefix + \`: Split vertical (alt)
|
|
23
|
-
- `Prefix + |`: Split horizontal (alt)
|
|
24
|
-
- `Prefix + h/j/k/l`: Move between panes (vim-style)
|
|
25
|
-
- `Prefix + z`: Toggle zoom pane
|
|
26
|
-
- `Prefix + H/J/K/L`: Resize pane (left/down/up/right)
|
|
27
|
-
|
|
28
|
-
## Neovim (leader = `Space`)
|
|
29
|
-
|
|
30
|
-
- `Ctrl-h/j/k/l`: Move between splits
|
|
31
|
-
- `Ctrl-s`: Save file
|
|
32
|
-
- `Leader + ff`: Find files (Telescope)
|
|
33
|
-
- `Leader + fg`: Live grep (Telescope)
|
|
34
|
-
- `Leader + q`: Quit
|
|
35
|
-
|
|
36
|
-
## Shell Tools
|
|
37
|
-
|
|
38
|
-
- `z <dir>`: Jump to a directory (`zoxide`)
|
|
39
|
-
- `lg`: Open `lazygit`
|
|
40
|
-
|
|
41
|
-
## Terminal
|
|
42
|
-
|
|
43
|
-
- `Ctrl+Shift+C`: Copy
|
|
44
|
-
- `Ctrl+Shift+V`: Paste
|
|
45
|
-
|
|
46
|
-
---
|
|
47
|
-
|
|
48
|
-
Update this file when bindings change. If you add a new tool, add its shortcuts
|
|
49
|
-
here and keep them aligned with the global conventions.
|
|
@@ -1,303 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
render_with_liquid: false
|
|
3
|
-
---
|
|
4
|
-
|
|
5
|
-
# Key Rotation Guide
|
|
6
|
-
|
|
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 `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
|
-
---
|
|
88
|
-
|
|
89
|
-
## Age Key Rotation
|
|
90
|
-
|
|
91
|
-
### When to Rotate
|
|
92
|
-
|
|
93
|
-
- **Annually**: As a preventive measure
|
|
94
|
-
- **After compromise**: If you suspect key exposure
|
|
95
|
-
- **Personnel change**: When team members leave
|
|
96
|
-
- **Device loss**: If a device with the key is lost/stolen
|
|
97
|
-
|
|
98
|
-
### Rotation Procedure
|
|
99
|
-
|
|
100
|
-
#### 1. Generate New Key
|
|
101
|
-
|
|
102
|
-
```bash
|
|
103
|
-
# Create new age key
|
|
104
|
-
age-keygen -o ~/.config/chezmoi/key-new.txt
|
|
105
|
-
|
|
106
|
-
# Note the public key (starts with "age1...")
|
|
107
|
-
cat ~/.config/chezmoi/key-new.txt | grep "public key"
|
|
108
|
-
```
|
|
109
|
-
|
|
110
|
-
#### 2. Re-encrypt All Secrets
|
|
111
|
-
|
|
112
|
-
```bash
|
|
113
|
-
# List all encrypted files
|
|
114
|
-
chezmoi managed --include=encrypted
|
|
115
|
-
|
|
116
|
-
# For each encrypted file, decrypt with old key and re-encrypt with new
|
|
117
|
-
for file in $(chezmoi managed --include=encrypted); do
|
|
118
|
-
# Decrypt with old key
|
|
119
|
-
chezmoi cat "$file" > "/tmp/$(basename $file).dec"
|
|
120
|
-
|
|
121
|
-
# Re-encrypt with new key (update chezmoi config first)
|
|
122
|
-
# See step 3
|
|
123
|
-
done
|
|
124
|
-
```
|
|
125
|
-
|
|
126
|
-
#### 3. Update Chezmoi Configuration
|
|
127
|
-
|
|
128
|
-
Edit `~/.config/chezmoi/chezmoi.toml`:
|
|
129
|
-
|
|
130
|
-
```toml
|
|
131
|
-
[age]
|
|
132
|
-
identity = "~/.config/chezmoi/key-new.txt"
|
|
133
|
-
recipient = "age1your_new_public_key_here"
|
|
134
|
-
```
|
|
135
|
-
|
|
136
|
-
#### 4. Re-add Encrypted Files
|
|
137
|
-
|
|
138
|
-
```bash
|
|
139
|
-
# Re-add each secret with new encryption
|
|
140
|
-
chezmoi add --encrypt ~/.ssh/id_ed25519
|
|
141
|
-
chezmoi add --encrypt ~/.config/secrets/api-keys.env
|
|
142
|
-
```
|
|
143
|
-
|
|
144
|
-
#### 5. Verify and Clean Up
|
|
145
|
-
|
|
146
|
-
```bash
|
|
147
|
-
# Verify decryption works
|
|
148
|
-
chezmoi cat ~/.ssh/id_ed25519
|
|
149
|
-
|
|
150
|
-
# Archive old key (store securely offline)
|
|
151
|
-
mv ~/.config/chezmoi/key.txt ~/.config/chezmoi/key-$(date +%Y%m%d)-archived.txt
|
|
152
|
-
|
|
153
|
-
# Rename new key
|
|
154
|
-
mv ~/.config/chezmoi/key-new.txt ~/.config/chezmoi/key.txt
|
|
155
|
-
|
|
156
|
-
# Commit changes
|
|
157
|
-
cd ~/.dotfiles
|
|
158
|
-
git add -A
|
|
159
|
-
git commit -m "chore(secrets): rotate age encryption key"
|
|
160
|
-
```
|
|
161
|
-
|
|
162
|
-
### Emergency Rotation (Compromised Key)
|
|
163
|
-
|
|
164
|
-
```bash
|
|
165
|
-
# 1. Immediately generate new key
|
|
166
|
-
age-keygen -o ~/.config/chezmoi/key-emergency.txt
|
|
167
|
-
|
|
168
|
-
# 2. Re-encrypt ALL secrets (prioritize most sensitive)
|
|
169
|
-
# 3. Revoke/rotate any API keys, tokens that were encrypted
|
|
170
|
-
# 4. Update any shared secrets with team members
|
|
171
|
-
# 5. Document the incident
|
|
172
|
-
```
|
|
173
|
-
|
|
174
|
-
---
|
|
175
|
-
|
|
176
|
-
## SOPS Key Rotation
|
|
177
|
-
|
|
178
|
-
### Overview
|
|
179
|
-
|
|
180
|
-
SOPS supports multiple key types. This covers Age keys (recommended) and GPG keys.
|
|
181
|
-
|
|
182
|
-
### SOPS with Age Keys
|
|
183
|
-
|
|
184
|
-
#### Generate New Key
|
|
185
|
-
|
|
186
|
-
```bash
|
|
187
|
-
age-keygen -o ~/.config/sops/age/keys-new.txt
|
|
188
|
-
```
|
|
189
|
-
|
|
190
|
-
#### Update .sops.yaml
|
|
191
|
-
|
|
192
|
-
```yaml
|
|
193
|
-
creation_rules:
|
|
194
|
-
- path_regex: \.env$
|
|
195
|
-
age: >-
|
|
196
|
-
age1new_key_here,
|
|
197
|
-
age1old_key_here # Keep old key temporarily for decryption
|
|
198
|
-
```
|
|
199
|
-
|
|
200
|
-
#### Re-encrypt Files
|
|
201
|
-
|
|
202
|
-
```bash
|
|
203
|
-
# Rotate key for a single file
|
|
204
|
-
sops updatekeys secrets.env
|
|
205
|
-
|
|
206
|
-
# Or re-encrypt entirely
|
|
207
|
-
sops -d secrets.env | sops -e /dev/stdin > secrets.env.new
|
|
208
|
-
mv secrets.env.new secrets.env
|
|
209
|
-
```
|
|
210
|
-
|
|
211
|
-
#### Remove Old Key
|
|
212
|
-
|
|
213
|
-
After confirming all files are re-encrypted:
|
|
214
|
-
|
|
215
|
-
1. Remove old key from `.sops.yaml`
|
|
216
|
-
2. Archive old key securely
|
|
217
|
-
3. Commit changes
|
|
218
|
-
|
|
219
|
-
### SOPS with GPG Keys
|
|
220
|
-
|
|
221
|
-
```bash
|
|
222
|
-
# Generate new GPG key
|
|
223
|
-
gpg --full-generate-key
|
|
224
|
-
|
|
225
|
-
# Export fingerprint
|
|
226
|
-
gpg --list-keys --keyid-format LONG
|
|
227
|
-
|
|
228
|
-
# Update .sops.yaml with new fingerprint
|
|
229
|
-
# Re-encrypt files
|
|
230
|
-
sops updatekeys <file>
|
|
231
|
-
```
|
|
232
|
-
|
|
233
|
-
---
|
|
234
|
-
|
|
235
|
-
## Automation Scripts
|
|
236
|
-
|
|
237
|
-
### Check Key Age
|
|
238
|
-
|
|
239
|
-
```bash
|
|
240
|
-
#!/usr/bin/env bash
|
|
241
|
-
# check-key-age.sh - Alert if keys are older than 365 days
|
|
242
|
-
|
|
243
|
-
KEY_FILE="${HOME}/.config/chezmoi/key.txt"
|
|
244
|
-
MAX_AGE_DAYS=365
|
|
245
|
-
|
|
246
|
-
if [[ -f "$KEY_FILE" ]]; then
|
|
247
|
-
key_age=$(( ($(date +%s) - $(stat -c %Y "$KEY_FILE")) / 86400 ))
|
|
248
|
-
|
|
249
|
-
if [[ $key_age -gt $MAX_AGE_DAYS ]]; then
|
|
250
|
-
echo "⚠️ Age key is ${key_age} days old. Consider rotation."
|
|
251
|
-
exit 1
|
|
252
|
-
else
|
|
253
|
-
echo "✓ Age key is ${key_age} days old (limit: ${MAX_AGE_DAYS})"
|
|
254
|
-
fi
|
|
255
|
-
fi
|
|
256
|
-
```
|
|
257
|
-
|
|
258
|
-
### Automated Backup Before Rotation
|
|
259
|
-
|
|
260
|
-
```bash
|
|
261
|
-
#!/usr/bin/env bash
|
|
262
|
-
# backup-before-rotation.sh
|
|
263
|
-
|
|
264
|
-
BACKUP_DIR="${HOME}/.local/share/dotfiles/key-backups"
|
|
265
|
-
mkdir -p "$BACKUP_DIR"
|
|
266
|
-
|
|
267
|
-
# Backup current key
|
|
268
|
-
cp ~/.config/chezmoi/key.txt "$BACKUP_DIR/key-$(date +%Y%m%d_%H%M%S).txt"
|
|
269
|
-
|
|
270
|
-
# Encrypt backup with passphrase
|
|
271
|
-
gpg --symmetric --cipher-algo AES256 "$BACKUP_DIR/key-$(date +%Y%m%d_%H%M%S).txt"
|
|
272
|
-
|
|
273
|
-
# Remove unencrypted backup
|
|
274
|
-
rm "$BACKUP_DIR/key-$(date +%Y%m%d_%H%M%S).txt"
|
|
275
|
-
|
|
276
|
-
echo "Key backed up to $BACKUP_DIR (encrypted)"
|
|
277
|
-
```
|
|
278
|
-
|
|
279
|
-
---
|
|
280
|
-
|
|
281
|
-
## Best Practices
|
|
282
|
-
|
|
283
|
-
1. **Never commit unencrypted keys** - Use `.gitignore` properly
|
|
284
|
-
2. **Store backups offline** - USB drive in secure location
|
|
285
|
-
3. **Use hardware keys when possible** - YubiKey with age-plugin-yubikey
|
|
286
|
-
4. **Document rotation dates** - Keep a log of when keys were rotated
|
|
287
|
-
5. **Test decryption** - Always verify after rotation
|
|
288
|
-
6. **Notify team members** - If using shared secrets
|
|
289
|
-
|
|
290
|
-
## Recovery Procedures
|
|
291
|
-
|
|
292
|
-
If you lose access to your key:
|
|
293
|
-
|
|
294
|
-
1. **Check backups** - Offline storage, password manager
|
|
295
|
-
2. **Check other machines** - Key may exist on another device
|
|
296
|
-
3. **Re-create secrets** - As last resort, regenerate API keys, tokens, etc.
|
|
297
|
-
|
|
298
|
-
## Related Documentation
|
|
299
|
-
|
|
300
|
-
- [SECRETS.md](SECRETS.md) - Secrets management overview
|
|
301
|
-
- [SECURITY.md](SECURITY.md) - Security hardening guide
|
|
302
|
-
- [Age documentation](https://github.com/FiloSottile/age)
|
|
303
|
-
- [SOPS documentation](https://github.com/getsops/sops)
|
|
@@ -1,78 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
render_with_liquid: false
|
|
3
|
-
---
|
|
4
|
-
|
|
5
|
-
# MCP Policy
|
|
6
|
-
|
|
7
|
-
MCP is treated as a controlled execution boundary.
|
|
8
|
-
|
|
9
|
-
## Default posture
|
|
10
|
-
|
|
11
|
-
The tracked default is `strict-local`.
|
|
12
|
-
|
|
13
|
-
Properties:
|
|
14
|
-
|
|
15
|
-
- local-first
|
|
16
|
-
- least privilege
|
|
17
|
-
- no broad filesystem roots
|
|
18
|
-
- no wildcard or unsafe flags
|
|
19
|
-
- no network-facing MCP servers enabled by default
|
|
20
|
-
- machine-readable validation output
|
|
21
|
-
|
|
22
|
-
## Policy artifact
|
|
23
|
-
|
|
24
|
-
The source of truth lives in [mcp-policy.json](https://github.com/sebastienrousseau/dotfiles/blob/main/defaults/dot_config/dotfiles/mcp-policy.json).
|
|
25
|
-
Approved package pins live in [mcp-lock.json](https://github.com/sebastienrousseau/dotfiles/blob/main/defaults/dot_config/dotfiles/mcp-lock.json).
|
|
26
|
-
Tracked server registry entries live in [mcp-registry.json](https://github.com/sebastienrousseau/dotfiles/blob/main/defaults/dot_config/dotfiles/mcp-registry.json).
|
|
27
|
-
|
|
28
|
-
Current defaults:
|
|
29
|
-
|
|
30
|
-
- Allowed launchers: `npx`, `node`, `uvx`
|
|
31
|
-
- Trusted transports: `stdio`, `http`
|
|
32
|
-
- Blocked filesystem roots: `/`, `/home`, `/Users`
|
|
33
|
-
- Blocked argument patterns: `^--allow-.*`, `^--unsafe$`, `^\\*$`
|
|
34
|
-
- Network-facing servers disabled by default: `github`, `brave-search`, `fetch`, `puppeteer`, `filesystem`
|
|
35
|
-
- Approved packages must resolve through the tracked MCP lock manifest
|
|
36
|
-
- Every active server must match the tracked MCP registry
|
|
37
|
-
- HTTP transports must use `https://` and registry-declared OAuth2
|
|
38
|
-
|
|
39
|
-
## Validation
|
|
40
|
-
|
|
41
|
-
Run:
|
|
42
|
-
|
|
43
|
-
```bash
|
|
44
|
-
dot mcp --strict
|
|
45
|
-
dot mcp -s -j
|
|
46
|
-
dot mcp registry
|
|
47
|
-
```
|
|
48
|
-
|
|
49
|
-
The JSON form is the audit artifact for CI, release validation, and workstation attestation.
|
|
50
|
-
|
|
51
|
-
## Change control
|
|
52
|
-
|
|
53
|
-
Any change to MCP policy requires:
|
|
54
|
-
|
|
55
|
-
1. A signed commit
|
|
56
|
-
2. A matching test update
|
|
57
|
-
3. A release note if the effective trust boundary changes
|
|
58
|
-
4. A policy bundle review when enterprise defaults change
|
|
59
|
-
|
|
60
|
-
## Supply-chain controls
|
|
61
|
-
|
|
62
|
-
Phase 2 adds explicit package locking for default MCP servers.
|
|
63
|
-
|
|
64
|
-
Current approved refs:
|
|
65
|
-
|
|
66
|
-
- `mcp-server-git@2025.1.14`
|
|
67
|
-
- `@modelcontextprotocol/server-memory@2025.8.4`
|
|
68
|
-
- `mcp-server-sqlite@2025.1.14`
|
|
69
|
-
|
|
70
|
-
`dot mcp --strict` and `dot mcp -s` now verify that:
|
|
71
|
-
|
|
72
|
-
- package refs are version-pinned
|
|
73
|
-
- the pinned refs match the tracked lock manifest
|
|
74
|
-
- non-approved package refs are rejected in strict mode
|
|
75
|
-
- active servers match the tracked registry entries
|
|
76
|
-
- remote HTTP transports are HTTPS and OAuth-backed
|
|
77
|
-
|
|
78
|
-
Policy bundle baselines live in [policy-bundles.json](https://github.com/sebastienrousseau/dotfiles/blob/main/defaults/dot_config/dotfiles/policy-bundles.json).
|
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
render_with_liquid: false
|
|
3
|
-
---
|
|
4
|
-
|
|
5
|
-
# Policy Bundle Releases
|
|
6
|
-
|
|
7
|
-
Policy bundles are released as tracked governance artifacts.
|
|
8
|
-
|
|
9
|
-
They include:
|
|
10
|
-
|
|
11
|
-
- policy bundles
|
|
12
|
-
- model registry
|
|
13
|
-
- prompt registry
|
|
14
|
-
- agent profiles
|
|
15
|
-
- agent card
|
|
16
|
-
- MCP policy, registry, and lock
|
|
17
|
-
- A2A discovery metadata
|
|
18
|
-
|
|
19
|
-
## Local packaging
|
|
20
|
-
|
|
21
|
-
```bash
|
|
22
|
-
bash tools/release/package-policy-bundles.sh --version 2026.03
|
|
23
|
-
bash tools/release/package-policy-bundles.sh --json
|
|
24
|
-
```
|
|
25
|
-
|
|
26
|
-
## Release workflow
|
|
27
|
-
|
|
28
|
-
Use the `Policy Bundle Release` workflow.
|
|
29
|
-
|
|
30
|
-
Release controls:
|
|
31
|
-
|
|
32
|
-
- source ref must be signed
|
|
33
|
-
- governance JSON must validate with `jq`
|
|
34
|
-
- bundle archive gets a SHA-256 checksum
|
|
35
|
-
- bundle archive gets GitHub provenance attestation
|
|
36
|
-
|
|
37
|
-
Signed commits remain mandatory for any policy change.
|
package/docs/security/README.md
DELETED
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
render_with_liquid: false
|
|
3
|
-
---
|
|
4
|
-
|
|
5
|
-
# Security Documentation
|
|
6
|
-
|
|
7
|
-
This directory contains security documentation for the dotfiles project.
|
|
8
|
-
|
|
9
|
-
## Index
|
|
10
|
-
|
|
11
|
-
| Document | Description |
|
|
12
|
-
|----------|-------------|
|
|
13
|
-
| [SECURITY.md](SECURITY.md) | Core security model and opt-in hardening |
|
|
14
|
-
| [THREAT_MODEL.md](THREAT_MODEL.md) | Threat analysis with trust boundaries |
|
|
15
|
-
| [SECRETS.md](SECRETS.md) | Secrets management (Age, SOPS, Keychain) |
|
|
16
|
-
| [KEY_ROTATION.md](KEY_ROTATION.md) | Key rotation procedures |
|
|
17
|
-
| [KEYS.md](KEYS.md) | Keybindings reference |
|
|
18
|
-
| [COMPLIANCE.md](COMPLIANCE.md) | SOC 2, ISO 27001, GDPR, HIPAA mapping |
|
|
19
|
-
| [AI_ACT_COMPLIANCE.md](AI_ACT_COMPLIANCE.md) | EU AI Act risk classification and exemption analysis |
|
|
20
|
-
| [SECURITY_CHECKLIST.md](SECURITY_CHECKLIST.md) | Pre-release security verification |
|
|
21
|
-
|
|
22
|
-
## Quick Reference
|
|
23
|
-
|
|
24
|
-
- **Encryption:** Age + SOPS for secrets at rest
|
|
25
|
-
- **Signing:** SSH ED25519 commit signing enforced
|
|
26
|
-
- **Scanning:** Gitleaks pre-commit hook prevents credential leaks
|
|
27
|
-
- **Telemetry:** Disabled by default, no data leaves your machine
|
|
28
|
-
- **Hardening:** Opt-in firewall, DNS-over-HTTPS, lock-screen, USB safety
|
|
@@ -1,195 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
render_with_liquid: false
|
|
3
|
-
---
|
|
4
|
-
|
|
5
|
-
# OpenSSF Scorecard
|
|
6
|
-
|
|
7
|
-
This page records the current OpenSSF Scorecard posture for this
|
|
8
|
-
repository, the known gaps, and the remediation roadmap. The badge in
|
|
9
|
-
the README links to the live result; this page is the maintained
|
|
10
|
-
narrative behind it.
|
|
11
|
-
|
|
12
|
-
## Live score
|
|
13
|
-
|
|
14
|
-
<!-- BEGIN scorecard-snapshot (auto-generated, do not edit by hand) -->
|
|
15
|
-
Aggregate score **7.6 / 10** at 2026-05-17T08:11:51Z.
|
|
16
|
-
|
|
17
|
-
| Check | Score | Reason |
|
|
18
|
-
|---|---:|---|
|
|
19
|
-
| Binary-Artifacts | 10 | no binaries found in the repo |
|
|
20
|
-
| Branch-Protection | -1 | internal error: error during branchesHandler.setup: internal error: some github tokens can't read cl |
|
|
21
|
-
| CI-Tests | 10 | 15 out of 15 merged PRs checked by a CI test -- score normalized to 10 |
|
|
22
|
-
| CII-Best-Practices | 2 | badge detected: InProgress |
|
|
23
|
-
| Code-Review | 0 | Found 0/30 approved changesets -- score normalized to 0 |
|
|
24
|
-
| Contributors | 0 | project has 0 contributing companies or organizations -- score normalized to 0 |
|
|
25
|
-
| Dangerous-Workflow | 10 | no dangerous workflow patterns detected |
|
|
26
|
-
| Dependency-Update-Tool | 10 | update tool detected |
|
|
27
|
-
| Fuzzing | 0 | project is not fuzzed |
|
|
28
|
-
| License | 9 | license file detected |
|
|
29
|
-
| Maintained | 10 | 30 commit(s) and 30 issue activity found in the last 90 days -- score normalized to 10 |
|
|
30
|
-
| Packaging | 10 | packaging workflow detected |
|
|
31
|
-
| Pinned-Dependencies | 9 | dependency not pinned by hash detected -- score normalized to 9 |
|
|
32
|
-
| SAST | 10 | SAST tool is run on all commits |
|
|
33
|
-
| Security-Policy | 10 | security policy file detected |
|
|
34
|
-
| Signed-Releases | 3 | 1 out of the last 3 releases have a total of 2 signed artifacts. |
|
|
35
|
-
| Token-Permissions | 10 | GitHub workflow tokens follow principle of least privilege |
|
|
36
|
-
| Vulnerabilities | 10 | 0 existing vulnerabilities detected |
|
|
37
|
-
|
|
38
|
-
*Refresh: `scripts/qa/scorecard-snapshot.sh` · Monitoring: `.github/workflows/scorecard.yml`.*
|
|
39
|
-
<!-- END scorecard-snapshot -->
|
|
40
|
-
|
|
41
|
-
[](https://scorecard.dev/viewer/?uri=github.com/sebastienrousseau/dotfiles)
|
|
42
|
-
|
|
43
|
-
The badge above is regenerated every Monday at 06:00 UTC and on every
|
|
44
|
-
push to `main` by `.github/workflows/scorecard.yml`. The SARIF
|
|
45
|
-
result is uploaded to GitHub Code Scanning (Security tab) and
|
|
46
|
-
retained as a 30-day workflow artifact.
|
|
47
|
-
|
|
48
|
-
## Threshold policy
|
|
49
|
-
|
|
50
|
-
| Score | Action |
|
|
51
|
-
|---|---|
|
|
52
|
-
| ≥ 8.0 | Healthy. Keep doing what we're doing. |
|
|
53
|
-
| 7.0 – 7.9 | Acceptable. Tracked. |
|
|
54
|
-
| < 7.0 | Regression — the workflow auto-opens a tracking issue labelled `type:security + priority:high`. |
|
|
55
|
-
|
|
56
|
-
Regressions are triaged within one Monday cycle: identify the check
|
|
57
|
-
that dropped, either remediate or file an exception entry below with
|
|
58
|
-
a rationale and an expiry date.
|
|
59
|
-
|
|
60
|
-
## Per-check posture (snapshot, main HEAD)
|
|
61
|
-
|
|
62
|
-
The checks below come from OpenSSF Scorecard's published rubric. Tick
|
|
63
|
-
marks reflect this repo's posture at the time of writing — the
|
|
64
|
-
*live* badge is authoritative if these diverge.
|
|
65
|
-
|
|
66
|
-
| Check | Status | Notes |
|
|
67
|
-
|---|---|---|
|
|
68
|
-
| Branch-Protection | ⚠ | `main` requires signed commits, linear history, required checks (`.github/rulesets/main.json`). Scorecard can't read classic protection rules without a fine-grained PAT, so this check reports as `-1` ("internal error"). |
|
|
69
|
-
| Code-Review | ⚠ | Single-maintainer repo; PRs are self-merged after CI. Scorecard scores 0/30 here by design — see `Open findings` below. |
|
|
70
|
-
| Signed-Commits | ✓ | Enforced by pre-push hook (`scripts/git-hooks/pre-push`) and at-push by branch protection (#853 + #857). |
|
|
71
|
-
| Dependency-Update-Tool | ✓ | Dependabot configured for github-actions / npm / docker / devcontainers / uv. |
|
|
72
|
-
| Fuzzing | ⚠ | `install.sh` fuzz harness lives under `fuzz/install/` (closes #881), but it's shell-based and Scorecard's heuristic only recognizes OSS-Fuzz / ClusterFuzzLite / native Go fuzz / libFuzzer / Atheris. None support shell. Property tests under `tests/unit/functions/test_property_*.sh` cover the closest equivalent surface. |
|
|
73
|
-
| License | ✓ | MIT at repo root (`LICENSE`). |
|
|
74
|
-
| Maintained | ✓ | Active commit cadence; the [README](https://github.com/sebastienrousseau/dotfiles/blob/main/README.md) lists the current `dotfiles_version`. |
|
|
75
|
-
| Pinned-Dependencies | ⚠ | Closed 8 of 14 findings this cycle (every Dockerfile base + every workflow action + 2 `curl \| sh` installers + the `npm install -g npm` upgrade step). 5 residual findings stay open by design — see `Open findings`. |
|
|
76
|
-
| SAST | ✓ | CodeQL (`.github/workflows/codeql.yml`) + Checkov + Grype. |
|
|
77
|
-
| SBOM | ✓ | Generated per PR by `sbom-diff.yml` and per release by `security-release.yml`. |
|
|
78
|
-
| Security-Policy | ✓ | `SECURITY.md` + this page + `docs/security/THREAT_MODEL.md`. |
|
|
79
|
-
| Token-Permissions | ✓ | Top-level `permissions:` blocks restricted to `contents: read`. `write` scopes scoped to the jobs that need them (#886). |
|
|
80
|
-
| Vulnerabilities | ✓ | Grype gate hard-fails on `high` / `critical` on `main` (#852). |
|
|
81
|
-
| Webhooks | n/a | No external webhooks configured. |
|
|
82
|
-
| CI-Tests | ✓ | Linux + macOS Intel + Apple Silicon matrix; optional Windows. |
|
|
83
|
-
| CII-Best-Practices | ☐ | Not applied yet — see `Open work` below. |
|
|
84
|
-
| Dangerous-Workflow | ✓ | No `pull_request_target` with checkout-PR-code anti-pattern. |
|
|
85
|
-
| Packaging | ✓ | `npm publish --provenance` via OIDC (`.github/workflows/npm-publish.yml`); `policy-bundle-release.yml` for the policy artifact. |
|
|
86
|
-
| Signed-Releases | ⚠ | SLSA provenance + minisig attached via `security-release.yml`; Cosign keyless signing tracked at #876. |
|
|
87
|
-
|
|
88
|
-
## Open findings
|
|
89
|
-
|
|
90
|
-
The eight items below are surfaced as alerts at
|
|
91
|
-
<https://github.com/sebastienrousseau/dotfiles/security/code-scanning>.
|
|
92
|
-
Each row gives the dismissal **reason** and the exact **comment text**
|
|
93
|
-
to paste when triaging.
|
|
94
|
-
|
|
95
|
-
### Bucket 1 — Dismiss in the UI (5 items)
|
|
96
|
-
|
|
97
|
-
Scorecard flags every `npm install`, `pip install`, `go install`, and
|
|
98
|
-
`curl | sh` invocation under the `Pinned-Dependencies` check. The five
|
|
99
|
-
below either belong to user-facing "update everything" aliases or are
|
|
100
|
-
false positives in Scorecard's regex.
|
|
101
|
-
|
|
102
|
-
| Path | Reason | Comment to paste |
|
|
103
|
-
|---|---|---|
|
|
104
|
-
| `.chezmoitemplates/aliases/legal/legal.aliases.sh:64` | **Won't fix** | User-facing convenience alias — `go install <fortune-style joke command>@latest`. Pinning by SHA would require users to update the alias manually on every upstream change. Intentional. |
|
|
105
|
-
| `.chezmoitemplates/aliases/update/update.aliases.sh:173` | **Won't fix** | User-facing convenience alias — bulk-update wrapper around `npm`. The alias's purpose is to update everything; pinning defeats it. Intentional. |
|
|
106
|
-
| `dot_local/bin/executable_update:99` | **Won't fix** | `dot_local/bin/executable_update` is the user-invoked "update everything" command. The literal point of `npm update -g` is to update to whatever's latest. Pinning defeats it. Intentional. |
|
|
107
|
-
| `scripts/dot/commands/tools.sh:121` | **False positive** | `npm install --package-lock-only --ignore-scripts --silent` generates a lockfile and does NOT fetch packages. Scorecard's regex matches `npm install` blindly; this invocation has no supply-chain surface. |
|
|
108
|
-
| `install/provision/run_onchange_10-linux-packages.sh.tmpl:369` | **Won't fix** | Already exact-version-pins `aider-chat==0.86.2`. Scorecard wants sha256-hash pinning, which would require a ~2,700-line lockfile covering all 108 transitive deps and re-generated on every aider release — disproportionate maintenance for a single optional provisioning install. |
|
|
109
|
-
|
|
110
|
-
### Bucket 2 — Architectural (1 item)
|
|
111
|
-
|
|
112
|
-
| Alert | Why architectural |
|
|
113
|
-
|---|---|
|
|
114
|
-
| `CodeReviewID` (high) — score 0 | Scorecard requires every merged PR to record an approval review by a different GitHub user than the author. This repo is single-maintainer; PRs are self-merged after CI. The fix path is either (a) onboard a co-maintainer who reviews PRs before merge, or (b) accept the finding. Dismiss as **Won't fix** with comment: "Single-maintainer project — no second reviewer available. CI gates (47 required checks per PR) substitute for human review." |
|
|
115
|
-
|
|
116
|
-
### Bucket 3 — External action (2 items)
|
|
117
|
-
|
|
118
|
-
| Alert | Action |
|
|
119
|
-
|---|---|
|
|
120
|
-
| `FuzzingID` (medium) | Dismiss as **Won't fix** with comment: "Repo is bash + Go-template + Lua. ClusterFuzzLite / OSS-Fuzz / native Go fuzz / libFuzzer / Atheris (the frameworks Scorecard recognises) all target compiled languages, none support shell. The `fuzz/install/fuzz_install.sh` harness + property tests under `tests/unit/functions/test_property_*.sh` cover the equivalent surface." |
|
|
121
|
-
| `CIIBestPracticesID` (low) | Apply at <https://www.bestpractices.dev/projects/new>. ~67 self-attested questions, free, 1-2 hours. After silver-tier approval, paste the badge into `README.md` next to the existing Scorecard badge. Most criteria already met (signed commits, CI, security policy, license). |
|
|
122
|
-
|
|
123
|
-
## Closed this cycle
|
|
124
|
-
|
|
125
|
-
| Date | Score | Alerts open | Change |
|
|
126
|
-
|---|---|---|---|
|
|
127
|
-
| 2026-05-14 | 6.5 | 28 | First clean publish after fixing the scorecard.yml `uses:`-only restriction (#885). Findings had been hidden by publish-step 400s until then. |
|
|
128
|
-
| 2026-05-14 | 6.5 | 11 | Closed 17 of 28: 10× TokenPermissions (#886), 6× Dockerfile bases (#886), 1× gitleaks fixture (#884). |
|
|
129
|
-
| 2026-05-14 | 6.5 | 9 | Closed 2× `curl \| sh` installers (#888). |
|
|
130
|
-
| 2026-05-14 | 6.5 | 8 | Closed 1× `npm install -g npm@…` via Node 24 bump (#889). |
|
|
131
|
-
| 2026-05-17 | 7.6 | 7 | v0.2.502 released; Cosign keyless signing live (#876 implementation landed in `security-release.yml` sbom job). |
|
|
132
|
-
| 2026-05-17 | 7.6 | 6 | SLSA Release Attestation pipeline unblocked (PR #894 — 6 prior releases had failed identically). v0.2.502 backfilled with `.intoto.jsonl` + `.sig` + `.pem` triplet. `Signed-Releases` should bump from 3 to ~10 on next Scorecard re-scrape. |
|
|
133
|
-
| 2026-05-17 | 7.6 | — | Added `MAINTAINERS.md` + `GOVERNANCE.md` at repo root. Provides the formal context for the `Code-Review` 0/30 score (solo maintainer) and unblocks the CII Best Practices badge application. |
|
|
134
|
-
|
|
135
|
-
## Open work
|
|
136
|
-
|
|
137
|
-
- **Apply for the OpenSSF Best Practices Badge** — see Bucket 3 above. All passing-tier criteria are now met (signed commits, CI, security policy, MIT license, MAINTAINERS.md, GOVERNANCE.md, RFC process documented).
|
|
138
|
-
- **Re-trigger Scorecard after SLSA backfill propagates** — expected `Signed-Releases` 3 → 10.
|
|
139
|
-
- **`harden-runner` block-mode adoption (#878)** — should tighten the `Token-Permissions` check further.
|
|
140
|
-
- **Investigate `License` 9/10 false-positive** — repo is MIT (SPDX-compliant), Scorecard's penalty should not apply.
|
|
141
|
-
- **Investigate `Branch-Protection` `-1`** — scanner internal error; manually verify with `gh api repos/:owner/:repo/branches/main/protection` and document.
|
|
142
|
-
|
|
143
|
-
### Enabling Branch-Protection + Webhooks checks (one-time PAT setup)
|
|
144
|
-
|
|
145
|
-
Scorecard's `Branch-Protection` and `Webhooks` checks require a
|
|
146
|
-
fine-grained Personal Access Token with `Administration: read`
|
|
147
|
-
scope. Without it both checks return `-1` ("internal error"). The
|
|
148
|
-
workflow already wires this up — only the secret needs to be created.
|
|
149
|
-
|
|
150
|
-
Steps (one-time, repo owner):
|
|
151
|
-
|
|
152
|
-
1. Go to <https://github.com/settings/personal-access-tokens/new>
|
|
153
|
-
2. **Resource owner**: `sebastienrousseau` · **Repository access**: only `sebastienrousseau/dotfiles`
|
|
154
|
-
3. **Repository permissions** → `Administration: read-only` and `Metadata: read-only`
|
|
155
|
-
4. **Expiration**: 1 year (set a calendar reminder to rotate; document the rotation in this file when done)
|
|
156
|
-
5. Generate the token, copy it once
|
|
157
|
-
6. Add as a secret named `SCORECARD_TOKEN` at <https://github.com/sebastienrousseau/dotfiles/settings/secrets/actions/new>
|
|
158
|
-
7. Next Scorecard run (manual via `gh workflow run scorecard.yml` or weekly cron) picks it up automatically
|
|
159
|
-
8. Expected effect: `Branch-Protection` `-1` → 10/10 if all rules are correctly configured; `Webhooks` `-1` → 10/10 (no webhooks present).
|
|
160
|
-
|
|
161
|
-
The PAT secret is **optional**. When absent, the workflow falls back
|
|
162
|
-
to `${{ github.token }}` and Scorecard continues to run, only with
|
|
163
|
-
those two checks at `-1`. Adding the PAT cannot reduce any other check's
|
|
164
|
-
score — it's a strict improvement.
|
|
165
|
-
|
|
166
|
-
## Exceptions
|
|
167
|
-
|
|
168
|
-
| Check | Expiry | Rationale |
|
|
169
|
-
|---|---|---|
|
|
170
|
-
| *(none currently)* | *—* | *—* |
|
|
171
|
-
|
|
172
|
-
If you add an exception, include the check name, an expiry date
|
|
173
|
-
(don't allow indefinite), and the rationale. Re-evaluate every quarter.
|
|
174
|
-
|
|
175
|
-
## Refreshing this document
|
|
176
|
-
|
|
177
|
-
```bash
|
|
178
|
-
# Re-count open alerts:
|
|
179
|
-
gh api 'repos/sebastienrousseau/dotfiles/code-scanning/alerts?state=open&per_page=50' \
|
|
180
|
-
--jq '[.[].rule.id] | group_by(.) | map({rule: .[0], count: length})'
|
|
181
|
-
|
|
182
|
-
# Trigger Scorecard manually:
|
|
183
|
-
gh workflow run scorecard.yml --ref main
|
|
184
|
-
```
|
|
185
|
-
|
|
186
|
-
If a new category appears, add a row to the matching bucket. If a
|
|
187
|
-
remediation closes one of the rows above, delete the row.
|
|
188
|
-
|
|
189
|
-
## References
|
|
190
|
-
|
|
191
|
-
- `.github/workflows/scorecard.yml` — the scanner workflow (split into
|
|
192
|
-
`analysis` + `track-regression` jobs per #885).
|
|
193
|
-
- [Scorecard project](https://github.com/ossf/scorecard).
|
|
194
|
-
- [Scorecard checks reference](https://github.com/ossf/scorecard/blob/main/docs/checks.md).
|
|
195
|
-
- Tracking issue [#869](https://github.com/sebastienrousseau/dotfiles/issues/869).
|