@sebastienrousseau/dotfiles 0.2.519 → 0.2.520
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 +182 -0
- package/README.md +1163 -163
- package/docs/ARCHITECTURE.md +117 -0
- package/docs/COPYRIGHT +1 -1
- package/docs/ECOSYSTEM.md +220 -0
- package/docs/GOLD-STANDARD-AUDIT.md +352 -0
- package/docs/GOVERNANCE.md +1 -1
- package/docs/MAINTAINERS.md +1 -1
- package/docs/MINIMUM-TOOLCHAIN.md +100 -0
- package/docs/README.md +1 -1
- package/docs/STRUCTURE.md +1 -1
- package/docs/architecture/ARCHITECTURE.md +11 -108
- package/docs/architecture/REPO_LAYOUT.md +3 -3
- package/docs/guides/MACOS_ICLOUD_SYMLINKS.md +121 -0
- package/docs/index.md +3 -3
- package/docs/manual/00-introduction.md +1 -1
- package/docs/manual/03-reference/01-dot-cli.md +28 -3
- package/docs/manual/command-index.md +24 -4
- package/docs/manual/concept-index.md +2 -0
- package/docs/migration/README.md +81 -0
- package/docs/migration/from-bare-git-repo.md +156 -0
- package/docs/migration/from-gnu-stow.md +165 -0
- package/docs/migration/from-plain-chezmoi.md +148 -0
- package/docs/migration/from-yadm.md +187 -0
- package/docs/operations/PERFORMANCE_BUDGETS.md +196 -0
- package/docs/operations/REGISTRY.md +1 -1
- package/docs/operations/RELEASE_PIPELINE.md +4 -4
- package/docs/operations/TESTING.md +3 -3
- package/docs/operations/TRACEABILITY.md +1 -0
- package/docs/packaging.md +222 -0
- package/docs/reference/FEATURE-MATRIX.md +646 -0
- package/docs/reference/TOOLS.md +1 -1
- package/docs/reference/UTILS.md +1 -0
- package/docs/security/COMPLIANCE.md +1 -1
- package/docs/security/DISCLOSURE.md +4 -4
- package/docs/security/FUZZING.md +113 -18
- package/docs/security/KEY_ROTATION.md +1 -1
- package/docs/security/SCORECARD.md +3 -3
- package/docs/security/VERIFY_RELEASE.md +2 -2
- package/install.sh +6 -6
- package/package.json +2 -2
- package/scripts/ci/check-copyright-headers.sh +1 -1
- package/scripts/ci/check-shell-preamble.sh +1 -1
- package/scripts/ci/guard-gitleaks-checkout.sh +1 -1
- package/scripts/demo/record.sh +1 -1
- package/scripts/diagnostics/a2a-conformance.sh +1 -1
- package/scripts/diagnostics/alias-governance.sh +30 -3
- package/scripts/diagnostics/aliases-cheatsheet.sh +1 -1
- package/scripts/diagnostics/aliases-manifest.sh +1 -1
- package/scripts/diagnostics/attest-verify.sh +147 -0
- package/scripts/diagnostics/benchmark.sh +1 -1
- package/scripts/diagnostics/conflicts.sh +1 -1
- package/scripts/diagnostics/doctor-unified.sh +6 -2
- package/scripts/diagnostics/doctor.sh +56 -10
- package/scripts/diagnostics/drift-dashboard.sh +3 -2
- package/scripts/diagnostics/health.sh +43 -10
- package/scripts/diagnostics/history-analysis.sh +1 -1
- package/scripts/diagnostics/mcp-doctor.sh +2 -2
- package/scripts/diagnostics/perf.sh +1 -1
- package/scripts/diagnostics/scorecard.sh +3 -2
- package/scripts/diagnostics/secret-governance.sh +1 -1
- package/scripts/diagnostics/security-score.sh +1 -1
- package/scripts/diagnostics/smoke-test.sh +1 -1
- package/scripts/diagnostics/snapshot.sh +1 -1
- package/scripts/diagnostics/verify.sh +1 -1
- package/scripts/diagnostics/verify_state.sh +1 -1
- package/scripts/diagnostics/version-locks.sh +1 -1
- package/scripts/diagnostics/workstation-attestation.sh +26 -1
- package/scripts/dot/commands/agent.sh +64 -14
- package/scripts/dot/commands/agents.sh +24 -8
- package/scripts/dot/commands/ai.sh +20 -7
- package/scripts/dot/commands/aliases.sh +1 -1
- package/scripts/dot/commands/appearance.sh +1 -1
- package/scripts/dot/commands/completion.sh +42 -5
- package/scripts/dot/commands/core.sh +1 -1
- package/scripts/dot/commands/diagnostics.sh +1 -1
- package/scripts/dot/commands/env-emit.sh +1 -1
- package/scripts/dot/commands/fleet.sh +41 -18
- package/scripts/dot/commands/init.sh +1 -1
- package/scripts/dot/commands/lint.sh +1 -1
- package/scripts/dot/commands/manual.sh +1 -1
- package/scripts/dot/commands/meta.sh +115 -10
- package/scripts/dot/commands/patterns.sh +1 -1
- package/scripts/dot/commands/registry.sh +43 -7
- package/scripts/dot/commands/restore.sh +1 -1
- package/scripts/dot/commands/secrets.sh +1 -1
- package/scripts/dot/commands/security.sh +1 -1
- package/scripts/dot/commands/tools.sh +21 -7
- package/scripts/fonts/install-nerd-fonts.sh +1 -1
- package/scripts/fonts/patch-fonts.sh +1 -1
- package/scripts/git-hooks/install.sh +1 -1
- package/scripts/git-hooks/pre-commit-audit.sh +2 -2
- package/scripts/lib/secrets_provider.sh +19 -4
- package/scripts/nvim/headless-upgrade.lua +81 -0
- package/scripts/ops/ai-setup.sh +1 -1
- package/scripts/ops/bundle.sh +1 -1
- package/scripts/ops/chaos.sh +1 -1
- package/scripts/ops/chezmoi-apply.sh +1 -1
- package/scripts/ops/chezmoi-diff.sh +1 -1
- package/scripts/ops/chezmoi-remove.sh +3 -3
- package/scripts/ops/chezmoi-update.sh +6 -2
- package/scripts/ops/heal-chezmoi.sh +1 -1
- package/scripts/ops/heal-system.sh +1 -1
- package/scripts/ops/heal-tools.sh +1 -1
- package/scripts/ops/heal.sh +1 -1
- package/scripts/ops/post-apply-repair.sh +1 -1
- package/scripts/ops/prewarm.sh +1 -1
- package/scripts/ops/release.sh +1 -1
- package/scripts/ops/rollback.sh +11 -2
- package/scripts/ops/setup.sh +1 -1
- package/scripts/ops/teleport.sh +1 -1
- package/scripts/qa/check-feature-matrix.sh +296 -0
- package/scripts/qa/check-version-consistency.sh +7 -119
- package/scripts/qa/coverage-baseline.sh +1 -1
- package/scripts/qa/docs-coverage.sh +9 -3
- package/scripts/qa/examples-coverage.sh +1 -1
- package/scripts/qa/reliability-audit.sh +1 -1
- package/scripts/qa/scorecard-snapshot.sh +1 -1
- package/scripts/qa/traceability-coverage.sh +9 -2
- package/scripts/qa/validate-examples.sh +66 -3
- package/scripts/qa/wsl-contract.sh +1 -1
- package/scripts/secrets/age-init.sh +1 -1
- package/scripts/secrets/create-secrets-file.sh +1 -1
- package/scripts/secrets/encrypt-ssh-key.sh +1 -1
- package/scripts/security/backup.sh +1 -1
- package/scripts/security/check-disclosure-key-expiry.sh +1 -1
- package/scripts/security/dns-doh.sh +1 -1
- package/scripts/security/encryption-check.sh +1 -1
- package/scripts/security/enforce-policies.sh +315 -98
- package/scripts/security/firewall.sh +1 -1
- package/scripts/security/lock-configs.sh +1 -1
- package/scripts/security/lock-screen.sh +1 -1
- package/scripts/security/manage-secrets.sh +1 -1
- package/scripts/security/ssh-cert.sh +1 -1
- package/scripts/security/telemetry-kill.sh +1 -1
- package/scripts/security/usb-safety.sh +1 -1
- package/scripts/theme/apply-gnome-theme.sh +1 -1
- package/scripts/theme/extract-heic-frames.sh +1 -1
- package/scripts/theme/extract-theme.py +284 -6
- package/scripts/theme/install-boot-logo.sh +1 -1
- package/scripts/theme/install-catppuccin-themes.sh +1 -1
- package/scripts/theme/install-cursors.sh +1 -1
- package/scripts/theme/install-file-icons.sh +1 -1
- package/scripts/theme/install-grub-theme.sh +1 -1
- package/scripts/theme/install-lock-icon.sh +1 -1
- package/scripts/theme/merge-wallpaper.sh +1 -1
- package/scripts/theme/rebuild-themes.sh +64 -5
- package/scripts/theme/switch.sh +46 -19
- package/scripts/theme/wallpaper-rotate.sh +1 -1
- package/scripts/theme/wallpaper-sync.sh +1 -1
- package/scripts/tools/cmatrix.sh +1 -1
- package/scripts/tools/detect-collisions.py +1 -1
- package/scripts/tools/emoji-picker.sh +1 -1
- package/scripts/tools/figlet-banner.sh +1 -1
- package/scripts/tools/log-rotate.sh +1 -1
- package/scripts/tools/lolcat-wrap.sh +1 -1
- package/scripts/tools/pipes.sh +1 -1
- package/scripts/tuning/linux.sh +1 -1
- package/scripts/tuning/macos.sh +1 -1
- package/scripts/uninstall.sh +1 -1
- package/scripts/verify-release-versions +156 -0
- package/scripts/version-sync.sh +63 -3
- package/LICENSE +0 -21
package/docs/reference/TOOLS.md
CHANGED
|
@@ -35,7 +35,7 @@ Integrated tools organized by role in the workflow.
|
|
|
35
35
|
| Tool | Purpose | Description |
|
|
36
36
|
| :--- | :--- | :--- |
|
|
37
37
|
| **Pueue** | Task queue | Offload long-running tasks to a background daemon |
|
|
38
|
-
| **Wasmtime** | Wasm runtime |
|
|
38
|
+
| **Wasmtime** | Wasm runtime | Runs `lib/wasm-tools` (`dot-sys.wasm`) for `dot attest --verify` |
|
|
39
39
|
| **SOPS** | Secrets operations | Encrypted secrets with automatic en/decryption |
|
|
40
40
|
|
|
41
41
|
---
|
package/docs/reference/UTILS.md
CHANGED
|
@@ -198,6 +198,7 @@ Every `dot` command's individually-enforced subcommands (see `dot help`).
|
|
|
198
198
|
| `dot agent conformance` | Run the A2A conformance test suite |
|
|
199
199
|
| `dot mcp doctor` | Run the MCP policy/supply-chain/config audit |
|
|
200
200
|
| `dot mcp registry` | Show the configured MCP server registry |
|
|
201
|
+
| `dot mcp serve` | Run the stdio MCP server (JSON-RPC 2.0 on stdin/stdout) |
|
|
201
202
|
| `dot secrets edit` | Edit the encrypted secrets file (age) |
|
|
202
203
|
| `dot secrets set` | Store a secret value under a key |
|
|
203
204
|
| `dot secrets get` | Retrieve a secret value (--raw for plaintext) |
|
|
@@ -370,7 +370,7 @@ bash tests/unit/test_dot_commands_apply.sh
|
|
|
370
370
|
|
|
371
371
|
| File | Purpose | Location |
|
|
372
372
|
|------|---------|----------|
|
|
373
|
-
| SECURITY.md | Vulnerability reporting |
|
|
373
|
+
| SECURITY.md | Vulnerability reporting | `SECURITY.md` |
|
|
374
374
|
| CONTRIBUTING.md | Contribution guidelines | `.github/CONTRIBUTING.md` |
|
|
375
375
|
| CODEOWNERS | Code ownership | `.github/CODEOWNERS` |
|
|
376
376
|
| INCIDENT_RESPONSE.md | Incident response plan | `docs/security/` |
|
|
@@ -34,7 +34,7 @@ gpg --fingerprint security@sebastienrousseau.com
|
|
|
34
34
|
```
|
|
35
35
|
|
|
36
36
|
The fingerprint must match the one published in
|
|
37
|
-
[
|
|
37
|
+
[`SECURITY.md`](https://github.com/sebastienrousseau/dotfiles/blob/main/SECURITY.md). Cross-verify
|
|
38
38
|
against the SSH signing key in `dot_config/git/allowed_signers.tmpl`
|
|
39
39
|
— the maintainer signs commits with the same identity, so both
|
|
40
40
|
fingerprints derive from the same identity claim.
|
|
@@ -75,7 +75,7 @@ subjects in plain text).
|
|
|
75
75
|
## 5. Acknowledgement
|
|
76
76
|
|
|
77
77
|
You should receive an acknowledgement within the SLA in
|
|
78
|
-
[
|
|
78
|
+
[`SECURITY.md`](https://github.com/sebastienrousseau/dotfiles/blob/main/SECURITY.md):
|
|
79
79
|
|
|
80
80
|
| Severity | Initial response |
|
|
81
81
|
|---|---|
|
|
@@ -107,7 +107,7 @@ The maintainer commits to:
|
|
|
107
107
|
- Public credit at fix time in the release notes (unless you
|
|
108
108
|
request anonymity at report time).
|
|
109
109
|
- A backport to any actively-supported release line listed in
|
|
110
|
-
|
|
110
|
+
`SECURITY.md`.
|
|
111
111
|
|
|
112
112
|
## What NOT to do
|
|
113
113
|
|
|
@@ -122,7 +122,7 @@ The maintainer commits to:
|
|
|
122
122
|
|
|
123
123
|
## See also
|
|
124
124
|
|
|
125
|
-
- [
|
|
125
|
+
- [`SECURITY.md`](https://github.com/sebastienrousseau/dotfiles/blob/main/SECURITY.md) — policy
|
|
126
126
|
overview + fingerprint.
|
|
127
127
|
- [`docs/security/KEY_ROTATION.md`](KEY_ROTATION.md) — schedule for
|
|
128
128
|
when the disclosure key is rotated.
|
package/docs/security/FUZZING.md
CHANGED
|
@@ -26,56 +26,144 @@ Drift between the shell and Go port IS the bug class the
|
|
|
26
26
|
fuzzer is designed to surface — if the Go port accepts a string
|
|
27
27
|
the shell rejects (or vice-versa), one of them has a hole.
|
|
28
28
|
|
|
29
|
+
## Where the harnesses live
|
|
30
|
+
|
|
31
|
+
The framework ships three Go binaries as well as the shell, so
|
|
32
|
+
harnesses live in four modules:
|
|
33
|
+
|
|
34
|
+
| Module | Harnesses | Runs against |
|
|
35
|
+
|--------|-----------|--------------|
|
|
36
|
+
| `fuzz` | 11 | ports of the shell helpers **and** of the two binaries' parsers — this is the package OSS-Fuzz and ClusterFuzzLite compile |
|
|
37
|
+
| `defaults/dot_local/share/dot-ui` | 8 | the real dot-ui implementation, in-module |
|
|
38
|
+
| `defaults/dot_local/share/dot-ai-tui` | 11 | the real dot-ai-tui implementation, in-module |
|
|
39
|
+
| `defaults/dot_local/share/dot-mcp` | 5 | the real MCP server, in-module — everything a peer can put on the wire |
|
|
40
|
+
|
|
41
|
+
`dot-ui` and `dot-ai-tui` are `package main` in their own modules,
|
|
42
|
+
which OSS-Fuzz's `compile_native_go_fuzzer` cannot import — it needs a
|
|
43
|
+
library package. Their parsers are therefore **ported** into
|
|
44
|
+
`fuzz` alongside the shell ports, and fuzzed
|
|
45
|
+
in-module as well. The in-module targets are the ones that catch real
|
|
46
|
+
bugs on every push; the ports are what runs continuously at scale.
|
|
47
|
+
The same lockstep rule applies: drift between a port and its original
|
|
48
|
+
is a bug in one of them.
|
|
49
|
+
|
|
29
50
|
## Harnesses today
|
|
30
51
|
|
|
52
|
+
### Ports (built by OSS-Fuzz / ClusterFuzzLite)
|
|
53
|
+
|
|
31
54
|
| Harness | Mirrors | What it proves |
|
|
32
55
|
|---------|---------|----------------|
|
|
33
56
|
| `FuzzValidateName` | `scripts/dot/lib/utils.sh:101` (`validate_name`) | Every accepted name contains only `[a-zA-Z0-9._-]`; no shell metacharacter slips through; empty input refused. |
|
|
34
57
|
| `FuzzInitURLResolver` | `scripts/dot/commands/init.sh` (URL construction in `dot init <user\|owner/repo\|url>`) | Accepted URLs use `https://` / `git@` / `ssh://` only; plain HTTP refused; no shell metacharacters in constructed URLs; one input shape per acceptable form. |
|
|
58
|
+
| `FuzzUIEventLine` | dot-ui `run.go` (`parseEvent`, `renderBar`) | A line either decodes to valid JSON or is refused; an accepted event round-trips; the derived progress width is always a legal repeat count. |
|
|
59
|
+
| `FuzzUIHexColor` | dot-ui `theme.go` (`parseColor`) | An accepted `DOT_UI_*` value is a literal `#rgb`/`#rrggbb` with no metacharacter or escape sequence — these are interpolated into terminal escapes. |
|
|
60
|
+
| `FuzzUIPickFilter` | dot-ui `pick.go` (`fuzzyMatch`, `readItems`) | No blank candidate survives; every candidate matches itself in any script; a query longer than the candidate never matches. |
|
|
61
|
+
| `FuzzUIPickArgs` | dot-ui `main.go` (`parsePickArgs`) | The parser never invents a value; every prefix of the argument list is safe. |
|
|
62
|
+
| `FuzzUITableRows` | dot-ui `table.go` (`runTable` input) | The `\x1f` split is reversible, so no cell can merge into or leak across a neighbouring column. |
|
|
63
|
+
| `FuzzAISessionFile` | dot-ai-tui `main.go` (`parseSession`) | A malformed session file decodes to nothing, never to a partial or mutated transcript; a valid one round-trips. |
|
|
64
|
+
| `FuzzAISqliteOutput` | dot-ai-tui `main.go` (`filterSqliteOutput`) | No `~/.sqliterc` meta line (`.timer`, `Run Time:`) survives into the cost/run data the cockpit renders. |
|
|
65
|
+
| `FuzzAIFenceTag` | dot-ai-tui `main.go` (`langRe`, `highlight`) | Every fence info string taken from model output is refused or a short identifier, so an unbounded chroma lexer lookup cannot stall rendering; prose segments survive segmentation. |
|
|
66
|
+
| `FuzzAIGatewayURL` | dot-ai-tui `main.go` (`gatewayURL`) | The health-check URL always keeps the `http` scheme and the configured host and port verbatim. |
|
|
67
|
+
|
|
68
|
+
### In-module (against the real implementation)
|
|
69
|
+
|
|
70
|
+
| Module | Harnesses |
|
|
71
|
+
|--------|-----------|
|
|
72
|
+
| dot-ui | `FuzzParseEvent`, `FuzzStepApply`, `FuzzParseColor`, `FuzzFuzzyMatch`, `FuzzPickKeys`, `FuzzRunTable`, `FuzzReadItems`, `FuzzParsePickArgs` |
|
|
73
|
+
| dot-ai-tui | `FuzzHighlight`, `FuzzBuildPrompt`, `FuzzHandleSlash`, `FuzzPalette`, `FuzzWindowRows`, `FuzzRenderTranscript`, `FuzzParseSession`, `FuzzFilterSqliteOutput`, `FuzzGatewayURL`, `FuzzModelKeys`, `FuzzModelCycle` |
|
|
74
|
+
| dot-mcp | `FuzzReadFrames`, `FuzzDecodeRequest`, `FuzzValidateArgs`, `FuzzServeSession`, `FuzzBuildCallResult` |
|
|
75
|
+
|
|
76
|
+
Each module's `FEATURES.md` maps every harness to the feature it
|
|
77
|
+
covers, and a matrix test fails if a harness is missing from it.
|
|
78
|
+
|
|
79
|
+
### Findings so far
|
|
80
|
+
|
|
81
|
+
| Harness | Bug | Fix |
|
|
82
|
+
|---------|-----|-----|
|
|
83
|
+
| `FuzzStepApply` | `{"t":"progress","cur":-1,"total":1}` produced a negative `strings.Repeat` count and panicked the run view mid-apply. | Clamp the bar width to `[0, w]`. |
|
|
84
|
+
| `FuzzFuzzyMatch` | The picker compared a query **byte** against a candidate **rune**, so no non-ASCII query could match — not even the identical string. | Compare both sides as runes. |
|
|
85
|
+
| `FuzzHighlight` | A 5 000-character fenced-block language tag stalled every render for 13s (chroma's unknown-lexer lookup is linear in the tag length). | Validate fence tags against a short-identifier pattern and memoise the lookup. |
|
|
86
|
+
| `FuzzRenderTranscript` | An empty transcript on a 12-row terminal with the palette open asked the splash for a negative height and panicked on a slice bound. | Drop the "recent runs" block when it does not fit; clamp the splash height. |
|
|
87
|
+
|
|
88
|
+
### Harness files must be self-contained
|
|
89
|
+
|
|
90
|
+
`compile_native_go_fuzzer` rewrites **one** `*_test.go` file into a
|
|
91
|
+
regular `.go` file and builds it **without** the package's other test
|
|
92
|
+
files. A harness that references a symbol declared in a sibling
|
|
93
|
+
`_test.go` therefore passes `go test` everywhere and fails only inside
|
|
94
|
+
the OSS-Fuzz / ClusterFuzzLite container:
|
|
95
|
+
|
|
96
|
+
```
|
|
97
|
+
./dot_ui_parsers_test.go_fuzz.go:117:21: undefined: dangerousChars
|
|
98
|
+
2026/09/07 01:14:42 failed to build packages:exit status 1
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
So a shared constant is deliberately **duplicated** per harness file
|
|
102
|
+
rather than factored out. If sharing is genuinely warranted, put the
|
|
103
|
+
symbol in a non-test `.go` file in the package — those the builder keeps.
|
|
104
|
+
|
|
105
|
+
`tools/ci/check-fuzz-harness-self-contained.sh` enforces this by
|
|
106
|
+
type-checking each harness alone in a scratch module; it runs in the
|
|
107
|
+
`Fuzz / Harness self-containment` job on every relevant PR.
|
|
35
108
|
|
|
36
109
|
Add a harness when:
|
|
37
110
|
|
|
38
111
|
- a new `dot <subcommand>` accepts user input via `$1` / `--flag`,
|
|
39
112
|
- a new regex appears in `scripts/dot/lib/utils.sh`,
|
|
40
|
-
- a new "construct a URL / path / shell-eval string" code path lands
|
|
113
|
+
- a new "construct a URL / path / shell-eval string" code path lands,
|
|
114
|
+
- a new function in `dot-ui`, `dot-ai-tui` or `dot-mcp` parses or transforms
|
|
115
|
+
stdin, an environment variable, a key stream or model output —
|
|
116
|
+
add it in-module *and* port it to `fuzz`.
|
|
41
117
|
|
|
42
118
|
## Running locally
|
|
43
119
|
|
|
44
120
|
```sh
|
|
45
|
-
|
|
121
|
+
# Ports (also what OSS-Fuzz builds)
|
|
122
|
+
cd fuzz
|
|
123
|
+
go test -run '^$' -fuzz=FuzzValidateName -fuzztime=30s ./...
|
|
124
|
+
go test -run '^$' -fuzz=FuzzUIEventLine -fuzztime=30s ./...
|
|
46
125
|
|
|
47
|
-
#
|
|
48
|
-
|
|
49
|
-
go test -run
|
|
126
|
+
# In-module, against the real implementation
|
|
127
|
+
cd defaults/dot_local/share/dot-ui
|
|
128
|
+
go test -run '^$' -fuzz=FuzzStepApply -fuzztime=30s ./...
|
|
50
129
|
|
|
51
|
-
|
|
52
|
-
go test -run
|
|
130
|
+
cd defaults/dot_local/share/dot-ai-tui
|
|
131
|
+
go test -run '^$' -fuzz=FuzzHighlight -fuzztime=30s ./...
|
|
132
|
+
|
|
133
|
+
# Replay every committed corpus in a module (no fuzzing, no flakes)
|
|
134
|
+
go test -run '^Fuzz' -v ./...
|
|
53
135
|
```
|
|
54
136
|
|
|
137
|
+
Each module's README lists every harness with a copy-pasteable
|
|
138
|
+
command.
|
|
139
|
+
|
|
55
140
|
Failures land in `testdata/fuzz/Fuzz<Name>/` as auto-saved
|
|
56
141
|
reproducers. Commit them — they become permanent regression
|
|
57
|
-
guards
|
|
142
|
+
guards, replayed by `go test ./...` and by the `replay` job in
|
|
143
|
+
`.github/workflows/fuzz.yml`.
|
|
58
144
|
|
|
59
145
|
## OSS-Fuzz integration (pending)
|
|
60
146
|
|
|
61
|
-
The `oss-fuzz
|
|
147
|
+
The `fuzz/oss-fuzz/` directory contains everything OSS-Fuzz
|
|
62
148
|
needs to onboard this project:
|
|
63
149
|
|
|
64
150
|
```
|
|
65
|
-
oss-fuzz
|
|
151
|
+
fuzz/oss-fuzz/
|
|
66
152
|
├── project.yaml # OSS-Fuzz project metadata
|
|
67
153
|
├── Dockerfile # build environment
|
|
68
154
|
├── build.sh # compiles every harness in fuzz/
|
|
69
155
|
└── fuzz/ # the harnesses themselves
|
|
70
156
|
├── go.mod
|
|
71
157
|
├── validate_name_test.go
|
|
72
|
-
|
|
158
|
+
├── init_url_resolver_test.go
|
|
159
|
+
├── dot_ui_parsers_test.go # ports of the dot-ui parsers
|
|
160
|
+
└── dot_ai_tui_parsers_test.go # ports of the dot-ai-tui parsers
|
|
73
161
|
```
|
|
74
162
|
|
|
75
163
|
To onboard:
|
|
76
164
|
|
|
77
165
|
1. Fork `github.com/google/oss-fuzz`.
|
|
78
|
-
2. Copy `oss-fuzz
|
|
166
|
+
2. Copy `fuzz/oss-fuzz/` contents to `projects/dotfiles/` in the fork.
|
|
79
167
|
3. Verify locally per <https://google.github.io/oss-fuzz/getting-started/new-project-guide/#testing-locally>:
|
|
80
168
|
|
|
81
169
|
```sh
|
|
@@ -95,16 +183,23 @@ which runs OSS-Fuzz-style fuzzing on every PR in this repo
|
|
|
95
183
|
|
|
96
184
|
## CI workflow
|
|
97
185
|
|
|
98
|
-
`.github/workflows/fuzz.yml`
|
|
99
|
-
60 seconds on every PR touching:
|
|
186
|
+
`.github/workflows/fuzz.yml` has two gates:
|
|
100
187
|
|
|
101
|
-
-
|
|
102
|
-
-
|
|
103
|
-
|
|
188
|
+
- **replay** — on every push and PR, every committed corpus (seed
|
|
189
|
+
entries plus the minimized crashers of previously-fixed findings) is
|
|
190
|
+
replayed in all three modules with `go test -run '^Fuzz'`. No
|
|
191
|
+
fuzzing, so no flakes: a fixed crash cannot silently come back.
|
|
192
|
+
- **fuzz** — a 60-second window per harness (configurable via
|
|
193
|
+
`workflow_dispatch`) on PRs touching an input-parsing surface:
|
|
194
|
+
`scripts/dot/lib/utils.sh`, `scripts/dot/commands/init.sh`,
|
|
195
|
+
`fuzz/**`, `.clusterfuzzlite/**` or either Go
|
|
196
|
+
module.
|
|
104
197
|
|
|
105
198
|
This is the local equivalent of CIFuzz and catches the
|
|
106
199
|
"shell-regex-change without Go-port update" drift class before
|
|
107
|
-
PR merge.
|
|
200
|
+
PR merge. The per-module test workflows (`dot-ui-test.yml`,
|
|
201
|
+
`cockpit-test.yml`) replay their own corpus too, so the guard holds
|
|
202
|
+
even when only one module changes.
|
|
108
203
|
|
|
109
204
|
## See also
|
|
110
205
|
|
|
@@ -6,7 +6,7 @@ render_with_liquid: false
|
|
|
6
6
|
|
|
7
7
|
This page tracks two distinct key lifecycles:
|
|
8
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
|
|
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
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
11
|
|
|
12
12
|
Both sections live here so a single audit can confirm the project's
|
|
@@ -69,13 +69,13 @@ marks reflect this repo's posture at the time of writing — the
|
|
|
69
69
|
| Code-Review | ⚠ | Single-maintainer repo; PRs are self-merged after CI. Scorecard scores 0/30 here by design — see `Open findings` below. |
|
|
70
70
|
| Signed-Commits | ✓ | Enforced by pre-push hook (`scripts/git-hooks/pre-push`) and at-push by branch protection (#853 + #857). |
|
|
71
71
|
| Dependency-Update-Tool | ✓ | Dependabot configured for github-actions / npm / docker / devcontainers / uv. |
|
|
72
|
-
| Fuzzing | ⚠ | `install.sh` fuzz harness lives under `
|
|
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
73
|
| License | ✓ | MIT at repo root (`LICENSE`). |
|
|
74
74
|
| Maintained | ✓ | Active commit cadence; the [README](https://github.com/sebastienrousseau/dotfiles/blob/main/README.md) lists the current `dotfiles_version`. |
|
|
75
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
76
|
| SAST | ✓ | CodeQL (`.github/workflows/codeql.yml`) + Checkov + Grype. |
|
|
77
77
|
| SBOM | ✓ | Generated per PR by `sbom-diff.yml` and per release by `security-release.yml`. |
|
|
78
|
-
| Security-Policy | ✓ |
|
|
78
|
+
| Security-Policy | ✓ | `SECURITY.md` + this page + `docs/security/THREAT_MODEL.md`. |
|
|
79
79
|
| Token-Permissions | ✓ | Top-level `permissions:` blocks restricted to `contents: read`. `write` scopes scoped to the jobs that need them (#886). |
|
|
80
80
|
| Vulnerabilities | ✓ | Grype gate hard-fails on `high` / `critical` on `main` (#852). |
|
|
81
81
|
| Webhooks | n/a | No external webhooks configured. |
|
|
@@ -117,7 +117,7 @@ false positives in Scorecard's regex.
|
|
|
117
117
|
|
|
118
118
|
| Alert | Action |
|
|
119
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 `
|
|
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
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
122
|
|
|
123
123
|
## Closed this cycle
|
|
@@ -187,13 +187,13 @@ verify-dot-release v0.2.502 # verify specific tag
|
|
|
187
187
|
`security@sebastienrousseau.com` (encrypted to the WKD-published
|
|
188
188
|
GPG key — fingerprint
|
|
189
189
|
`55AFAD364FD9DB3819E61F0C8D688FAFA9144693`). Acknowledgement
|
|
190
|
-
SLA: 72 hours per
|
|
190
|
+
SLA: 72 hours per `SECURITY.md`.
|
|
191
191
|
|
|
192
192
|
---
|
|
193
193
|
|
|
194
194
|
## See also
|
|
195
195
|
|
|
196
|
-
-
|
|
196
|
+
- `SECURITY.md` — coordinated disclosure policy.
|
|
197
197
|
- `docs/security/KEY_ROTATION.md` — disclosure-key rotation procedure.
|
|
198
198
|
- `docs/security/SCORECARD.md` — OpenSSF Scorecard posture.
|
|
199
199
|
- `docs/operations/HARD_AUDIT_2026.md` Part 7 — the GPG key generation + WKD publication record.
|
package/install.sh
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env bash
|
|
2
|
-
# SPDX-License-Identifier: MIT
|
|
2
|
+
# SPDX-License-Identifier: Apache-2.0 OR MIT
|
|
3
3
|
# Copyright (c) 2015-2026 Sebastien Rousseau
|
|
4
4
|
# Universal Dotfiles Installer (Zero-Dependency)
|
|
5
5
|
# Usage: gh repo clone sebastienrousseau/dotfiles && cd dotfiles && ./install.sh
|
|
@@ -71,7 +71,7 @@ show_help() {
|
|
|
71
71
|
Usage: install.sh [version] [options]
|
|
72
72
|
|
|
73
73
|
Arguments:
|
|
74
|
-
version The version (tag or branch) to install (default: v0.2.
|
|
74
|
+
version The version (tag or branch) to install (default: v0.2.520)
|
|
75
75
|
|
|
76
76
|
Options:
|
|
77
77
|
--help Show this help message
|
|
@@ -87,7 +87,7 @@ EOF
|
|
|
87
87
|
}
|
|
88
88
|
|
|
89
89
|
main() {
|
|
90
|
-
local version="v0.2.
|
|
90
|
+
local version="v0.2.520"
|
|
91
91
|
local version_set=0
|
|
92
92
|
local minimal=0
|
|
93
93
|
local provision="${DOTFILES_PROVISION:-0}"
|
|
@@ -117,7 +117,7 @@ main() {
|
|
|
117
117
|
# like `foobar` doesn't trigger a 30s+ network download attempt.
|
|
118
118
|
# Caught by the install.sh fuzz harness (#881).
|
|
119
119
|
if [[ ! "$arg" =~ ^v?[0-9]+\.[0-9]+\.[0-9]+([-+][a-zA-Z0-9.-]+)?$ ]]; then
|
|
120
|
-
error "Unrecognized positional argument '$arg' — expected a semver version (e.g. v0.2.
|
|
120
|
+
error "Unrecognized positional argument '$arg' — expected a semver version (e.g. v0.2.520)."
|
|
121
121
|
fi
|
|
122
122
|
version="$arg"
|
|
123
123
|
version_set=1
|
|
@@ -369,7 +369,7 @@ main() {
|
|
|
369
369
|
# 6. Initialize & Apply
|
|
370
370
|
step "Applying Configuration..."
|
|
371
371
|
|
|
372
|
-
# ── Auto-migration for v0.2.
|
|
372
|
+
# ── Auto-migration for v0.2.520 reorg ─────────────────────────────────
|
|
373
373
|
# If the user is upgrading from a pre-0.2.503 install, run the
|
|
374
374
|
# migration script BEFORE `chezmoi apply` so the reorg's source-
|
|
375
375
|
# path moves don't cause chezmoi to delete deployed files.
|
|
@@ -378,7 +378,7 @@ main() {
|
|
|
378
378
|
for migrate_src in "$SOURCE_DIR" "$LEGACY_SOURCE_DIR"; do
|
|
379
379
|
migrate_script="$migrate_src/install/migrate/migrate-v0_2-to-v0_2_503.sh"
|
|
380
380
|
if [[ -x "$migrate_script" ]]; then
|
|
381
|
-
echo " Running v0.2.
|
|
381
|
+
echo " Running v0.2.520 migration (idempotent; safe on fresh installs)..."
|
|
382
382
|
"$migrate_script" || echo " migration exited non-zero — continuing apply"
|
|
383
383
|
break
|
|
384
384
|
fi
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sebastienrousseau/dotfiles",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.520",
|
|
4
4
|
"description": "The Trusted Shell Platform — Universal dotfiles managed by Chezmoi. Features Bash & Zsh for macOS, Linux & WSL. Rust modern tooling & enterprise-grade security.",
|
|
5
5
|
"main": "install.sh",
|
|
6
6
|
"bin": {
|
|
@@ -48,7 +48,7 @@
|
|
|
48
48
|
"email": "sebastienrousseau@users.noreply.github.com",
|
|
49
49
|
"url": "https://sebastienrousseau.com"
|
|
50
50
|
},
|
|
51
|
-
"license": "MIT",
|
|
51
|
+
"license": "Apache-2.0 OR MIT",
|
|
52
52
|
"bugs": {
|
|
53
53
|
"url": "https://github.com/sebastienrousseau/dotfiles/issues"
|
|
54
54
|
},
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env bash
|
|
2
|
-
# SPDX-License-Identifier: MIT
|
|
2
|
+
# SPDX-License-Identifier: Apache-2.0 OR MIT
|
|
3
3
|
# Copyright (c) 2015-2026 Sebastien Rousseau
|
|
4
4
|
# Compat shim: the canonical script moved to tools/ci/ during the repo reorg.
|
|
5
5
|
# Pinned reusable workflows on main still reference the old path;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env bash
|
|
2
|
-
# SPDX-License-Identifier: MIT
|
|
2
|
+
# SPDX-License-Identifier: Apache-2.0 OR MIT
|
|
3
3
|
# Copyright (c) 2015-2026 Sebastien Rousseau
|
|
4
4
|
# Compat shim: the canonical script moved to tools/ci/ during the repo reorg.
|
|
5
5
|
# Pinned reusable workflows on main still reference the old path;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env bash
|
|
2
|
-
# SPDX-License-Identifier: MIT
|
|
2
|
+
# SPDX-License-Identifier: Apache-2.0 OR MIT
|
|
3
3
|
# Copyright (c) 2015-2026 Sebastien Rousseau
|
|
4
4
|
# Compat shim: the canonical script moved to tools/ci/ during the repo reorg.
|
|
5
5
|
# Pinned reusable workflows on main still reference the old path;
|
package/scripts/demo/record.sh
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env bash
|
|
2
|
-
# SPDX-License-Identifier: MIT
|
|
2
|
+
# SPDX-License-Identifier: Apache-2.0 OR MIT
|
|
3
3
|
# Copyright (c) 2015-2026 Sebastien Rousseau
|
|
4
4
|
# Alias governance checks:
|
|
5
5
|
# - duplicate alias names
|
|
@@ -54,6 +54,31 @@ if [[ -f "$SCRIPT_DIR/../../package.json" ]]; then
|
|
|
54
54
|
fi
|
|
55
55
|
repo_version="${repo_version:-0.0.0}"
|
|
56
56
|
|
|
57
|
+
# ripgrep is preferred but is NOT guaranteed to be installed (the CI
|
|
58
|
+
# runners and minimal setups often lack it, which is why
|
|
59
|
+
# aliases-manifest.sh already carries a grep fallback). Without one
|
|
60
|
+
# here, `rg` exiting 127 reads as "no match": every gated override was
|
|
61
|
+
# reported as ungated, and this gate failed with false errors on any
|
|
62
|
+
# machine without ripgrep.
|
|
63
|
+
_gov_grep_file() { # <ere-pattern> <file>
|
|
64
|
+
if command -v rg >/dev/null 2>&1; then
|
|
65
|
+
rg -q "$1" "$2"
|
|
66
|
+
else
|
|
67
|
+
grep -qE "$1" "$2"
|
|
68
|
+
fi
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
_gov_grep_tree() { # <ere-pattern> <dir>...
|
|
72
|
+
local pattern="$1"
|
|
73
|
+
shift
|
|
74
|
+
if command -v rg >/dev/null 2>&1; then
|
|
75
|
+
rg -q --glob '*.sh' --glob '*.aliases.sh' --glob '*.tmpl' "$pattern" "$@" 2>/dev/null
|
|
76
|
+
else
|
|
77
|
+
grep -rqE --include='*.sh' --include='*.aliases.sh' --include='*.tmpl' \
|
|
78
|
+
"$pattern" "$@" 2>/dev/null
|
|
79
|
+
fi
|
|
80
|
+
}
|
|
81
|
+
|
|
57
82
|
# 1) Duplicate alias names
|
|
58
83
|
dupes="$(awk -F'\t' '{count[$1]++} END {for (k in count) if (count[k] > 1) print k}' "$tmp_manifest" | sort)"
|
|
59
84
|
if [[ -n "$dupes" ]]; then
|
|
@@ -77,7 +102,7 @@ while IFS=$'\t' read -r name _value file _line; do
|
|
|
77
102
|
if [[ "$file" == *"/aliases/gnu/"* ]]; then
|
|
78
103
|
continue
|
|
79
104
|
fi
|
|
80
|
-
if !
|
|
105
|
+
if ! _gov_grep_file 'DOTFILES_(ENABLE|SAFE|ALIAS)' "$file"; then
|
|
81
106
|
echo "ERROR: risky override '$name' in $file is not gated by a DOTFILES_* flag"
|
|
82
107
|
errors=$((errors + 1))
|
|
83
108
|
fi
|
|
@@ -111,7 +136,9 @@ if [[ -f "$deprecations_file" ]]; then
|
|
|
111
136
|
alias_found=1
|
|
112
137
|
fi
|
|
113
138
|
function_found=0
|
|
114
|
-
if
|
|
139
|
+
if _gov_grep_tree "^[[:space:]]*(function[[:space:]]+)?${alias_name}[[:space:]]*\\(\\)" \
|
|
140
|
+
"$SCRIPT_DIR/../../defaults/.chezmoitemplates/aliases" \
|
|
141
|
+
"$SCRIPT_DIR/../../scripts/dot"; then
|
|
115
142
|
function_found=1
|
|
116
143
|
fi
|
|
117
144
|
if [[ $alias_found -eq 1 || $function_found -eq 1 ]]; then
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# SPDX-License-Identifier: Apache-2.0 OR MIT
|
|
3
|
+
# Copyright (c) 2015-2026 Sebastien Rousseau
|
|
4
|
+
## Verify workstation attestation evidence with the WebAssembly verifier.
|
|
5
|
+
##
|
|
6
|
+
## Runs `lib/wasm-tools` built for `wasm32-wasip1` under `wasmtime` and feeds
|
|
7
|
+
## it an evidence record on stdin. The module has no filesystem, no network
|
|
8
|
+
## and no environment: it reads the document, applies the policy and writes a
|
|
9
|
+
## verdict. Nothing about the verdict depends on the tools installed on the
|
|
10
|
+
## machine under review — which is the point, since that machine is the one
|
|
11
|
+
## making the claims.
|
|
12
|
+
##
|
|
13
|
+
## Usage: dot attest --verify [--json|-j] [--max-age SECS] [FILE]
|
|
14
|
+
## dot attest --json | bash scripts/diagnostics/attest-verify.sh
|
|
15
|
+
##
|
|
16
|
+
## Exit codes: 0 every check passed, 1 a check failed, 2 the evidence or the
|
|
17
|
+
## toolchain was unusable.
|
|
18
|
+
|
|
19
|
+
set -euo pipefail
|
|
20
|
+
|
|
21
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
22
|
+
REPO_ROOT="${REPO_ROOT:-$(cd "$SCRIPT_DIR/../.." && pwd)}"
|
|
23
|
+
export REPO_ROOT
|
|
24
|
+
|
|
25
|
+
# shellcheck source=../../lib/dot/ui.sh
|
|
26
|
+
# shellcheck disable=SC1091
|
|
27
|
+
source "$SCRIPT_DIR/../../lib/dot/ui.sh"
|
|
28
|
+
|
|
29
|
+
CRATE_DIR="$REPO_ROOT/lib/wasm-tools"
|
|
30
|
+
WASM_TARGET="wasm32-wasip1"
|
|
31
|
+
DEFAULT_MODULE="$CRATE_DIR/target/$WASM_TARGET/release/dot-sys.wasm"
|
|
32
|
+
|
|
33
|
+
JSON_MODE=0
|
|
34
|
+
MAX_AGE=""
|
|
35
|
+
EVIDENCE_FILE=""
|
|
36
|
+
while [[ $# -gt 0 ]]; do
|
|
37
|
+
case "$1" in
|
|
38
|
+
--json | -j)
|
|
39
|
+
JSON_MODE=1
|
|
40
|
+
shift
|
|
41
|
+
;;
|
|
42
|
+
--max-age | -a)
|
|
43
|
+
MAX_AGE="${2:-}"
|
|
44
|
+
shift 2
|
|
45
|
+
;;
|
|
46
|
+
--verify | -V)
|
|
47
|
+
# Accepted so the flag can be forwarded verbatim from `dot attest`.
|
|
48
|
+
shift
|
|
49
|
+
;;
|
|
50
|
+
--help | -h)
|
|
51
|
+
cat <<'USAGE'
|
|
52
|
+
Usage: dot attest --verify [--json|-j] [--max-age SECS] [FILE]
|
|
53
|
+
|
|
54
|
+
Runs the wasm32-wasip1 build of lib/wasm-tools under wasmtime and checks an
|
|
55
|
+
evidence record against the workstation policy. Reads FILE, or stdin, or a
|
|
56
|
+
fresh `dot attest --json` when given neither.
|
|
57
|
+
|
|
58
|
+
--json, -j emit the machine-readable verdict
|
|
59
|
+
--max-age SECS freshness window for `generated_at` (`any` to lift it)
|
|
60
|
+
--help, -h print this text
|
|
61
|
+
|
|
62
|
+
Exit codes: 0 every check passed, 1 a check failed, 2 unusable input or
|
|
63
|
+
toolchain.
|
|
64
|
+
USAGE
|
|
65
|
+
exit 0
|
|
66
|
+
;;
|
|
67
|
+
--)
|
|
68
|
+
shift
|
|
69
|
+
break
|
|
70
|
+
;;
|
|
71
|
+
-*)
|
|
72
|
+
echo "attest-verify: unknown option $1" >&2
|
|
73
|
+
exit 2
|
|
74
|
+
;;
|
|
75
|
+
*)
|
|
76
|
+
EVIDENCE_FILE="$1"
|
|
77
|
+
shift
|
|
78
|
+
;;
|
|
79
|
+
esac
|
|
80
|
+
done
|
|
81
|
+
|
|
82
|
+
# Resolve the WebAssembly runtime. `wasmtime` is pinned in mise.toml, shipped
|
|
83
|
+
# by flake.nix and the Brewfile, and checked by `dot doctor`.
|
|
84
|
+
WASMTIME_BIN="${WASMTIME:-wasmtime}"
|
|
85
|
+
if ! command -v "$WASMTIME_BIN" >/dev/null 2>&1; then
|
|
86
|
+
echo "attest-verify: no WebAssembly runtime found (looked for '$WASMTIME_BIN')." >&2
|
|
87
|
+
echo "attest-verify: install it with 'mise install wasmtime' or set WASMTIME." >&2
|
|
88
|
+
exit 2
|
|
89
|
+
fi
|
|
90
|
+
|
|
91
|
+
# Resolve the module, building it on demand when a Rust toolchain is present.
|
|
92
|
+
MODULE="${DOT_SYS_WASM:-$DEFAULT_MODULE}"
|
|
93
|
+
if [[ ! -f "$MODULE" ]]; then
|
|
94
|
+
if [[ -n "${DOT_SYS_WASM:-}" ]]; then
|
|
95
|
+
echo "attest-verify: DOT_SYS_WASM points at a missing file: $MODULE" >&2
|
|
96
|
+
exit 2
|
|
97
|
+
fi
|
|
98
|
+
if ! command -v cargo >/dev/null 2>&1; then
|
|
99
|
+
echo "attest-verify: no verifier at $MODULE and no cargo to build one." >&2
|
|
100
|
+
echo "attest-verify: build it with:" >&2
|
|
101
|
+
echo " cargo build --release --target $WASM_TARGET --manifest-path lib/wasm-tools/Cargo.toml" >&2
|
|
102
|
+
exit 2
|
|
103
|
+
fi
|
|
104
|
+
echo "attest-verify: building the verifier for $WASM_TARGET ..." >&2
|
|
105
|
+
cargo build --quiet --release --target "$WASM_TARGET" \
|
|
106
|
+
--manifest-path "$CRATE_DIR/Cargo.toml" --bin dot-sys >&2
|
|
107
|
+
fi
|
|
108
|
+
|
|
109
|
+
# Collect the evidence: an explicit file, a pipe, or a fresh attestation.
|
|
110
|
+
evidence=""
|
|
111
|
+
if [[ -n "$EVIDENCE_FILE" ]]; then
|
|
112
|
+
if [[ ! -f "$EVIDENCE_FILE" ]]; then
|
|
113
|
+
echo "attest-verify: no such evidence file: $EVIDENCE_FILE" >&2
|
|
114
|
+
exit 2
|
|
115
|
+
fi
|
|
116
|
+
evidence="$(cat "$EVIDENCE_FILE")"
|
|
117
|
+
elif [[ ! -t 0 ]]; then
|
|
118
|
+
evidence="$(cat)"
|
|
119
|
+
else
|
|
120
|
+
evidence="$(bash "$SCRIPT_DIR/workstation-attestation.sh" --json)"
|
|
121
|
+
fi
|
|
122
|
+
|
|
123
|
+
module_args=(verify)
|
|
124
|
+
[[ "$JSON_MODE" -eq 1 ]] && module_args+=(--json)
|
|
125
|
+
[[ -n "$MAX_AGE" ]] && module_args+=(--max-age "$MAX_AGE")
|
|
126
|
+
|
|
127
|
+
set +e
|
|
128
|
+
verdict="$(printf '%s' "$evidence" | "$WASMTIME_BIN" run "$MODULE" "${module_args[@]}")"
|
|
129
|
+
status=$?
|
|
130
|
+
set -e
|
|
131
|
+
|
|
132
|
+
if [[ "$JSON_MODE" -eq 1 ]]; then
|
|
133
|
+
printf '%s\n' "$verdict"
|
|
134
|
+
exit "$status"
|
|
135
|
+
fi
|
|
136
|
+
|
|
137
|
+
ui_init
|
|
138
|
+
ui_dot_banner "Diagnostics"
|
|
139
|
+
ui_header "Attestation Verification"
|
|
140
|
+
printf '%s\n' "$verdict"
|
|
141
|
+
if [[ "$status" -eq 0 ]]; then
|
|
142
|
+
ui_ok "Verdict" "every check passed"
|
|
143
|
+
else
|
|
144
|
+
ui_err "Verdict" "see the failed checks above"
|
|
145
|
+
fi
|
|
146
|
+
ui_info "Verifier" "$MODULE (wasm32-wasip1, $("$WASMTIME_BIN" --version | head -n 1))"
|
|
147
|
+
exit "$status"
|