@aldegad/safedeps 2.1.0

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/LICENSE ADDED
@@ -0,0 +1,190 @@
1
+ Apache License
2
+ Version 2.0, January 2004
3
+ http://www.apache.org/licenses/
4
+
5
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6
+
7
+ 1. Definitions.
8
+
9
+ "License" shall mean the terms and conditions for use, reproduction,
10
+ and distribution as defined by Sections 1 through 9 of this document.
11
+
12
+ "Licensor" shall mean the copyright owner or entity authorized by
13
+ the copyright owner that is granting the License.
14
+
15
+ "Legal Entity" shall mean the union of the acting entity and all
16
+ other entities that control, are controlled by, or are under common
17
+ control with that entity. For the purposes of this definition,
18
+ "control" means (i) the power, direct or indirect, to cause the
19
+ direction or management of such entity, whether by contract or
20
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
21
+ outstanding shares, or (iii) beneficial ownership of such entity.
22
+
23
+ "You" (or "Your") shall mean an individual or Legal Entity
24
+ exercising permissions granted by this License.
25
+
26
+ "Source" form shall mean the preferred form for making modifications,
27
+ including but not limited to software source code, documentation
28
+ source, and configuration files.
29
+
30
+ "Object" form shall mean any form resulting from mechanical
31
+ transformation or translation of a Source form, including but
32
+ not limited to compiled object code, generated documentation,
33
+ and conversions to other media types.
34
+
35
+ "Work" shall mean the work of authorship, whether in Source or
36
+ Object form, made available under the License, as indicated by a
37
+ copyright notice that is included in or attached to the work
38
+ (an example is provided in the Appendix below).
39
+
40
+ "Derivative Works" shall mean any work, whether in Source or Object
41
+ form, that is based on (or derived from) the Work and for which the
42
+ editorial revisions, annotations, elaborations, or other modifications
43
+ represent, as a whole, an original work of authorship. For the purposes
44
+ of this License, Derivative Works shall not include works that remain
45
+ separable from, or merely link (or bind by name) to the interfaces of,
46
+ the Work and Derivative Works thereof.
47
+
48
+ "Contribution" shall mean any work of authorship, including
49
+ the original version of the Work and any modifications or additions
50
+ to that Work or Derivative Works thereof, that is intentionally
51
+ submitted to the Licensor for inclusion in the Work by the copyright owner
52
+ or by an individual or Legal Entity authorized to submit on behalf of
53
+ the copyright owner. For the purposes of this definition, "submitted"
54
+ means any form of electronic, verbal, or written communication sent
55
+ to the Licensor or its representatives, including but not limited to
56
+ communication on electronic mailing lists, source code control systems,
57
+ and issue tracking systems that are managed by, or on behalf of, the
58
+ Licensor for the purpose of discussing and improving the Work, but
59
+ excluding communication that is conspicuously marked or otherwise
60
+ designated in writing by the copyright owner as "Not a Contribution."
61
+
62
+ "Contributor" shall mean Licensor and any individual or Legal Entity
63
+ on behalf of whom a Contribution has been received by the Licensor and
64
+ subsequently incorporated within the Work.
65
+
66
+ 2. Grant of Copyright License. Subject to the terms and conditions of
67
+ this License, each Contributor hereby grants to You a perpetual,
68
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69
+ copyright license to reproduce, prepare Derivative Works of,
70
+ publicly display, publicly perform, sublicense, and distribute the
71
+ Work and such Derivative Works in Source or Object form.
72
+
73
+ 3. Grant of Patent License. Subject to the terms and conditions of
74
+ this License, each Contributor hereby grants to You a perpetual,
75
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76
+ (except as stated in this section) patent license to make, have made,
77
+ use, offer to sell, sell, import, and otherwise transfer the Work,
78
+ where such license applies only to those patent claims licensable
79
+ by such Contributor that are necessarily infringed by their
80
+ Contribution(s) alone or by combination of their Contribution(s)
81
+ with the Work to which such Contribution(s) was submitted. If You
82
+ institute patent litigation against any entity (including a
83
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
84
+ or a Contribution incorporated within the Work constitutes direct
85
+ or contributory patent infringement, then any patent licenses
86
+ granted to You under this License for that Work shall terminate
87
+ as of the date such litigation is filed.
88
+
89
+ 4. Redistribution. You may reproduce and distribute copies of the
90
+ Work or Derivative Works thereof in any medium, with or without
91
+ modifications, and in Source or Object form, provided that You
92
+ meet the following conditions:
93
+
94
+ (a) You must give any other recipients of the Work or
95
+ Derivative Works a copy of this License; and
96
+
97
+ (b) You must cause any modified files to carry prominent notices
98
+ stating that You changed the files; and
99
+
100
+ (c) You must retain, in the Source form of any Derivative Works
101
+ that You distribute, all copyright, patent, trademark, and
102
+ attribution notices from the Source form of the Work,
103
+ excluding those notices that do not pertain to any part of
104
+ the Derivative Works; and
105
+
106
+ (d) If the Work includes a "NOTICE" text file as part of its
107
+ distribution, then any Derivative Works that You distribute must
108
+ include a readable copy of the attribution notices contained
109
+ within such NOTICE file, excluding any notices that do not
110
+ pertain to any part of the Derivative Works, in at least one
111
+ of the following places: within a NOTICE text file distributed
112
+ as part of the Derivative Works; within the Source form or
113
+ documentation, if provided along with the Derivative Works; or,
114
+ within a display generated by the Derivative Works, if and
115
+ wherever such third-party notices normally appear. The contents
116
+ of the NOTICE file are for informational purposes only and
117
+ do not modify the License. You may add Your own attribution
118
+ notices within Derivative Works that You distribute, alongside
119
+ or as an addendum to the NOTICE text from the Work, provided
120
+ that such additional attribution notices cannot be construed
121
+ as modifying the License.
122
+
123
+ You may add Your own copyright statement to Your modifications and
124
+ may provide additional or different license terms and conditions
125
+ for use, reproduction, or distribution of Your modifications, or
126
+ for any such Derivative Works as a whole, provided Your use,
127
+ reproduction, and distribution of the Work otherwise complies with
128
+ the conditions stated in this License.
129
+
130
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
131
+ any Contribution intentionally submitted for inclusion in the Work
132
+ by You to the Licensor shall be under the terms and conditions of
133
+ this License, without any additional terms or conditions.
134
+ Notwithstanding the above, nothing herein shall supersede or modify
135
+ the terms of any separate license agreement you may have executed
136
+ with Licensor regarding such Contributions.
137
+
138
+ 6. Trademarks. This License does not grant permission to use the trade
139
+ names, trademarks, service marks, or product names of the Licensor,
140
+ except as required for reasonable and customary use in describing the
141
+ origin of the Work and reproducing the content of the NOTICE file.
142
+
143
+ 7. Disclaimer of Warranty. Unless required by applicable law or
144
+ agreed to in writing, Licensor provides the Work (and each
145
+ Contributor provides its Contributions) on an "AS IS" BASIS,
146
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147
+ implied, including, without limitation, any warranties or conditions
148
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149
+ PARTICULAR PURPOSE. You are solely responsible for determining the
150
+ appropriateness of using or redistributing the Work and assume any
151
+ risks associated with Your exercise of permissions under this License.
152
+
153
+ 8. Limitation of Liability. In no event and under no legal theory,
154
+ whether in tort (including negligence), contract, or otherwise,
155
+ unless required by applicable law (such as deliberate and grossly
156
+ negligent acts) or agreed to in writing, shall any Contributor be
157
+ liable to You for damages, including any direct, indirect, special,
158
+ incidental, or consequential damages of any character arising as a
159
+ result of this License or out of the use or inability to use the
160
+ Work (including but not limited to damages for loss of goodwill,
161
+ work stoppage, computer failure or malfunction, or any and all
162
+ other commercial damages or losses), even if such Contributor
163
+ has been advised of the possibility of such damages.
164
+
165
+ 9. Accepting Warranty or Additional Liability. While redistributing
166
+ the Work or Derivative Works thereof, You may choose to offer,
167
+ and charge a fee for, acceptance of support, warranty, indemnity,
168
+ or other liability obligations and/or rights consistent with this
169
+ License. However, in accepting such obligations, You may act only
170
+ on Your own behalf and on Your sole responsibility, not on behalf
171
+ of any other Contributor, and only if You agree to indemnify,
172
+ defend, and hold each Contributor harmless for any liability
173
+ incurred by, or claims asserted against, such Contributor by reason
174
+ of your accepting any such warranty or additional liability.
175
+
176
+ END OF TERMS AND CONDITIONS
177
+
178
+ Copyright 2026 soohongkim
179
+
180
+ Licensed under the Apache License, Version 2.0 (the "License");
181
+ you may not use this file except in compliance with the License.
182
+ You may obtain a copy of the License at
183
+
184
+ http://www.apache.org/licenses/LICENSE-2.0
185
+
186
+ Unless required by applicable law or agreed to in writing, software
187
+ distributed under the License is distributed on an "AS IS" BASIS,
188
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
189
+ See the License for the specific language governing permissions and
190
+ limitations under the License.
package/README.md ADDED
@@ -0,0 +1,311 @@
1
+ # Safedeps
2
+
3
+ > Dependency install safety gate -- advisory checks, approved spec enforcement, and auto-rollback suspicious package installs in Claude Code and Codex CLI.
4
+
5
+ ## Why "reorg"?
6
+
7
+ In blockchain networks, a **reorganization (reorg)** invalidates a sequence of blocks and reverts the chain to a previously confirmed safe state. `safedeps` applies the same principle to your `node_modules`: every install is treated as an unconfirmed block candidate until it passes a battery of supply-chain security checks. If anything looks wrong, the tool performs a **reorg** -- rolling back lock files, `package.json`, and `node_modules` to the last confirmed safe snapshot.
8
+
9
+ No manual review. No leftover malicious code. Fully automatic.
10
+
11
+ ## Distribution Model
12
+
13
+ Safedeps has two distribution surfaces:
14
+
15
+ 1. **Agent skill + hooks (canonical)** -- the repo itself is the skill folder. `SKILL.md`, hook scripts, provider/ledger libraries, and install helpers stay together in one directory.
16
+ 2. **npm package (CLI convenience)** -- `@aldegad/safedeps` installs the `safedeps` command. npm does **not** make Claude Code or Codex automatically discover the skill; after npm installation, users still need to run the hook/skill installer or manually register the skill folder.
17
+
18
+ Use the GitHub release when you want the full skill/hook source tree as the canonical artifact. Use npm when you mainly want a versioned global CLI.
19
+
20
+ ## How It Works
21
+
22
+ `safedeps` plugs into Claude Code and Codex CLI hooks as a pair of **PreToolUse** and **PostToolUse** hooks that wrap package install commands. The CLI owns provider lookups and the approved-spec ledger; hooks enforce that ledger and run post-install rollback checks.
23
+
24
+ ```
25
+ PreToolUse PostToolUse
26
+ (safedeps-pre-guard.sh) (safedeps-post-verify.sh)
27
+ | |
28
+ install cmd ──> [ Advisory/ledger gate ] ──> [ Execute ] ──> [ Verify ]
29
+ | | | |
30
+ Block if Snapshot Clean? Suspicious?
31
+ unapproved lock/manifest files, | |
32
+ or risky package listings Confirm REORG
33
+ | |
34
+ | v v
35
+ +--- parent_snapshot_id ──> confirmed
36
+ |
37
+ Rollback to last
38
+ confirmed snapshot
39
+ ```
40
+
41
+ ### Phase 1: Advisory Gate + Pre-flight (PreToolUse)
42
+
43
+ Before an agent installs a dependency, it should run:
44
+
45
+ ```bash
46
+ safedeps check <ecosystem> <pkg>@<version|range> --json
47
+ ```
48
+
49
+ That command queries OSV (canonical), CISA KEV (hard-risk overlay), and GitHub Advisory (enrichment). Clean or safely narrowed specs are written to `~/.safedeps/approved-specs/`.
50
+
51
+ When Claude Code or Codex CLI is about to run `npm install`, `pip install`, `cargo add`, `go get`, `gem install`, or similar commands, the guard hook:
52
+
53
+ 1. **Snapshots** the current `package-lock.json`, `pnpm-lock.yaml`, `yarn.lock`, and `package.json` into `~/.safedeps/snapshots/`.
54
+ 2. **Records metadata** including a `parent_snapshot_id` linking to the previous confirmed snapshot (forming a chain, just like blocks).
55
+ 3. **Captures pre-install state** of `node_modules` (package listings and binary listings) for diff-based detection later.
56
+ 4. **Enforces the approved-spec ledger** for explicit `pkg@version` install commands.
57
+ 5. **Runs pre-flight checks** and **blocks** the command entirely if it detects:
58
+ - Typosquatting package names (`lod_sh`, `reacct`, `axois`, etc.)
59
+ - Non-standard `--registry` URLs (anything outside `registry.npmjs.org` and `registry.yarnpkg.com`)
60
+ - Piped remote execution patterns (`curl ... | bash`)
61
+ - Explicit disabling of install script safety (`npm config set ignore-scripts false`)
62
+
63
+ If the ledger gate or a pre-flight check fails, the command is **blocked before execution** -- nothing is installed.
64
+
65
+ ### Phase 2: Post-install verification (`safedeps-post-verify.sh` -- PostToolUse)
66
+
67
+ After the install command completes, the verify hook analyzes what changed:
68
+
69
+ 1. **Install script analysis** -- Scans newly added packages for `preinstall`, `install`, and `postinstall` scripts containing:
70
+ - Network access (`curl`, `wget`, `fetch`, `http`, `socket`, `dns`)
71
+ - Dynamic code execution (`eval`, `exec`, `spawn`, `child_process`, `Function()`)
72
+ - Sensitive path access (`~/.ssh`, `.env`, `.aws`, `credentials`)
73
+ - Obfuscated content (`base64`, `atob`, `Buffer.from`, hex/unicode escapes)
74
+
75
+ 2. **Lock file diff analysis** -- Compares the snapshotted lock file content against the post-install version:
76
+ - Resolved URLs pointing to non-standard registries
77
+ - Insecure protocols (`http://`, `git://`) in resolved URLs
78
+ - Unusually large dependency additions (>50 new resolved entries, indicating potential dependency confusion)
79
+
80
+ 3. **Binary inspection** -- Checks `node_modules/.bin/` for newly added native binaries (ELF, Mach-O, shared objects) that should not appear in a JavaScript project.
81
+
82
+ ### Phase 3: Confirm or Reorg
83
+
84
+ - **All checks pass** -- The snapshot is marked as **confirmed** in `~/.safedeps/confirmed`. This becomes the new safe baseline.
85
+ - **Any check fails** -- A **reorg** is triggered:
86
+ 1. Lock files are restored from the last confirmed snapshot.
87
+ 2. `package.json` is restored if it was modified.
88
+ 3. `node_modules` is rebuilt via `npm ci` (or `npm install` as fallback) to purge any malicious artifacts.
89
+ 4. The event is logged to `~/.safedeps/reorg.log`.
90
+ 5. Claude Code receives a system message detailing the detected threats and rollback actions.
91
+
92
+ ## The Blockchain Analogy
93
+
94
+ | Blockchain Concept | Safedeps Equivalent |
95
+ |---|---|
96
+ | **Block candidate** | Snapshot taken before `npm install` |
97
+ | **Block validation** | Post-install security checks (scripts, lock diff, binaries) |
98
+ | **Finality / confirmation** | Snapshot ID written to `~/.safedeps/confirmed` |
99
+ | **Chain reorganization** | Rollback to last confirmed snapshot + `node_modules` rebuild |
100
+ | **Parent hash linking** | `parent_snapshot_id` in each snapshot's `_meta.json` |
101
+ | **Chain pruning** | Old unconfirmed snapshots cleaned up, confirmed chain preserved |
102
+
103
+ ## Detection Rules
104
+
105
+ | Category | What it catches | Phase | Action |
106
+ |---|---|---|---|
107
+ | Typosquatting | Known misspelling patterns of popular packages | Pre-flight | **Block** |
108
+ | Pipe execution | `curl \| bash`, `wget \| sh` | Pre-flight | **Block** |
109
+ | Registry hijack | `--registry` pointing to unofficial sources | Pre-flight | **Block** |
110
+ | Script safety bypass | `npm config set ignore-scripts false` | Pre-flight | **Block** |
111
+ | Command indirection | `eval "npm install ..."`, subshell expansion, variable indirection | Pre-flight | **Guard** |
112
+ | npx/dlx execution | `npx`, `pnpm dlx`, `yarn dlx` package execution | Pre-flight | **Guard** |
113
+ | Malicious install scripts | Network calls, `eval`/`exec`, sensitive path access in hooks | Post-install | **Reorg** |
114
+ | Obfuscated code | Base64, hex encoding, `Buffer.from` in install scripts | Post-install | **Reorg** |
115
+ | Lock file tampering | Resolved URLs from non-standard registries | Post-install | **Reorg** |
116
+ | Insecure protocols | `http://` or `git://` resolved URLs | Post-install | **Reorg** |
117
+ | Dependency confusion | >50 new dependencies in a single install | Post-install | **Reorg** |
118
+ | Native binaries | Compiled executables in `node_modules/.bin/` | Post-install | **Reorg** |
119
+
120
+ ## Installation
121
+
122
+ ### Prerequisites
123
+
124
+ - [Claude Code](https://docs.anthropic.com/en/docs/claude-code) with hook support
125
+ - `jq` -- JSON parsing (hooks exit gracefully if missing)
126
+ - `shasum` or `sha256sum` -- hash computation
127
+ - `file` (optional) -- binary detection
128
+
129
+ ```bash
130
+ # macOS
131
+ brew install jq
132
+
133
+ # Ubuntu / Debian
134
+ sudo apt-get install jq
135
+ ```
136
+
137
+ ### Setup From GitHub (Skill + Hooks)
138
+
139
+ **1. Clone the repository:**
140
+
141
+ ```bash
142
+ git clone https://github.com/aldegad/safedeps.git
143
+ cd safedeps
144
+ ```
145
+
146
+ **2. Install the skill + hooks:**
147
+
148
+ ```bash
149
+ node scripts/install/install-safedeps-hooks.mjs
150
+ ```
151
+
152
+ The installer is idempotent. It symlinks the skill into `~/.claude/skills/safedeps` and `~/.codex/skills/safedeps` when those roots exist, patches the matching hook config, and can also place `safedeps` on PATH through `~/.local/bin`.
153
+
154
+ **3. Manual hook registration, if needed:**
155
+
156
+ Edit `.claude/settings.json` (project-level) or `~/.claude/settings.json` (global):
157
+
158
+ ```json
159
+ {
160
+ "hooks": {
161
+ "PreToolUse": [
162
+ {
163
+ "matcher": "Bash",
164
+ "hooks": [
165
+ {
166
+ "type": "command",
167
+ "command": "~/.claude/skills/safedeps/scripts/safedeps-pre-guard.sh"
168
+ }
169
+ ]
170
+ }
171
+ ],
172
+ "PostToolUse": [
173
+ {
174
+ "matcher": "Bash",
175
+ "hooks": [
176
+ {
177
+ "type": "command",
178
+ "command": "~/.claude/skills/safedeps/scripts/safedeps-post-verify.sh"
179
+ }
180
+ ]
181
+ }
182
+ ]
183
+ }
184
+ }
185
+ ```
186
+
187
+ **4. Verify permissions:**
188
+
189
+ ```bash
190
+ chmod +x ~/.claude/skills/safedeps/scripts/safedeps-pre-guard.sh
191
+ chmod +x ~/.claude/skills/safedeps/scripts/safedeps-post-verify.sh
192
+ ```
193
+
194
+ That's it. The guard activates automatically whenever Claude Code or Codex CLI runs a package install command.
195
+
196
+ ### Setup From npm (CLI First)
197
+
198
+ ```bash
199
+ npm install -g @aldegad/safedeps
200
+ safedeps version
201
+ ```
202
+
203
+ npm puts `safedeps` on PATH through its standard `bin` entry. It does **not** register the agent skill or hooks for Claude Code / Codex. To enable the hooks from the npm-installed copy, run the installer from the installed package root:
204
+
205
+ ```bash
206
+ cd "$(npm root -g)/@aldegad/safedeps"
207
+ node scripts/install/install-safedeps-hooks.mjs
208
+ ```
209
+
210
+ The installer is idempotent and only adds symlinks/hook entries. The `--link-bin` flag is **only useful when you installed via GitHub clone instead of npm** — npm already places the CLI on PATH, so the flag is redundant in this path.
211
+
212
+ If you want the skill folder itself to be the canonical local source, prefer the GitHub setup above.
213
+
214
+ ### Daily Re-check With macOS Alerts
215
+
216
+ Install a per-user LaunchAgent to re-check the approved-spec ledger once per day:
217
+
218
+ ```bash
219
+ node scripts/install/install-safedeps-recheck-agent.mjs install --hour 9 --minute 0
220
+ ```
221
+
222
+ This runs `safedeps re-check --json` against `~/.safedeps/approved-specs/`. It does not use LLM tokens; it only calls the advisory providers used by safedeps. If a new CVE/KEV is found, a spec is revoked, or a provider check is skipped, the wrapper writes `~/.safedeps/recheck-alerts.jsonl` and raises a macOS notification.
223
+
224
+ Useful commands:
225
+
226
+ ```bash
227
+ node scripts/install/install-safedeps-recheck-agent.mjs status
228
+ node scripts/install/install-safedeps-recheck-agent.mjs uninstall
229
+ tail -f ~/.safedeps/recheck.log
230
+ ```
231
+
232
+ ### Legacy State Migration
233
+
234
+ If you used the old `npm-reorg-guard` state directory, migrate it once:
235
+
236
+ ```bash
237
+ safedeps migrate
238
+ ```
239
+
240
+ This copies missing state from `~/.npm-reorg-guard` into `~/.safedeps` and archives the legacy directory so there is no second active state root.
241
+
242
+ ## Real-World Attack Coverage
243
+
244
+ `safedeps` is designed to catch the patterns behind real supply-chain incidents:
245
+
246
+ - **`event-stream` (2018)** -- Malicious `postinstall` script with obfuscated code that exfiltrated cryptocurrency wallet keys. Caught by: install script analysis (obfuscation + network access detection).
247
+ - **`ua-parser-js` hijack (2021)** -- Compromised package added a `preinstall` script that downloaded and executed cryptominers. Caught by: install script analysis (network access + code execution).
248
+ - **`colors` / `faker` sabotage (2022)** -- While these were author-initiated, the abnormal dependency behavior would trigger the dependency explosion check.
249
+ - **Typosquatting campaigns** -- Ongoing campaigns publishing packages like `crossenv` (instead of `cross-env`) or `babelcli` (instead of `babel-cli`). Caught by: pre-flight typosquatting pattern matching.
250
+ - **Dependency confusion attacks** -- Internal package names published to the public registry with higher version numbers. Caught by: non-standard registry detection + large dependency count changes.
251
+
252
+ ## Logs and Snapshots
253
+
254
+ | Path | Description |
255
+ |---|---|
256
+ | `~/.safedeps/reorg.log` | Full reorg event history with timestamps, reasons, and rolled-back files |
257
+ | `~/.safedeps/confirmed` | Current confirmed (safe) snapshot ID |
258
+ | `~/.safedeps/snapshots/` | All snapshot files (lock files, package.json copies, metadata) |
259
+
260
+ ```bash
261
+ # View reorg history
262
+ cat ~/.safedeps/reorg.log
263
+
264
+ # Check current confirmed snapshot
265
+ cat ~/.safedeps/confirmed
266
+
267
+ # List all snapshots
268
+ ls -la ~/.safedeps/snapshots/
269
+ ```
270
+
271
+ Old unconfirmed snapshots are automatically pruned (keeping the 10 most recent), while the confirmed snapshot chain is always preserved.
272
+
273
+ ## Security Hardening
274
+
275
+ `safedeps` includes multiple layers of defense against attacks targeting the guard itself:
276
+
277
+ | Measure | What it prevents |
278
+ |---|---|
279
+ | **JSON-safe metadata** | `project_dir` is escaped via `jq -Rs` to prevent JSON injection in snapshot metadata |
280
+ | **Path canonicalization** | `realpath`/`readlink -f` resolves symlinks and `..` traversal in `cwd` before use |
281
+ | **Atomic state files** | Snapshot ID and project directory are written as a single JSON file, preventing TOCTOU races |
282
+ | **Stale lock recovery** | Locks older than 60 seconds are automatically removed, preventing permanent DoS from `SIGKILL`/OOM |
283
+ | **Project-scoped state** | Each project gets its own confirmed snapshot chain (`confirmed_${dir_hash}`), preventing cross-project interference |
284
+ | **Restrictive permissions** | `umask 077` ensures `~/.safedeps/` is readable only by the owner |
285
+ | **Indirection detection** | Commands using `eval`, `$()`, or backticks with package manager keywords are treated as install candidates |
286
+
287
+ ## Project Structure
288
+
289
+ ```
290
+ safedeps/
291
+ bin/
292
+ safedeps # CLI -- advisory gate, ledger, revoke, re-check
293
+ lib/
294
+ providers/ # OSV / CISA KEV / GHSA adapters
295
+ ledger/ # approved-spec ledger
296
+ scripts/
297
+ safedeps-pre-guard.sh # PreToolUse hook -- snapshot + ledger enforcement
298
+ safedeps-post-verify.sh # PostToolUse hook -- post-install verification + reorg
299
+ install/install-safedeps-hooks.mjs
300
+ install/install-safedeps-recheck-agent.mjs
301
+ install/migrate-safedeps-state.mjs
302
+ safedeps-recheck-alert.sh
303
+ test/
304
+ package.json
305
+ SKILL.md # Claude Code / Codex skill manifest
306
+ LICENSE # Apache-2.0
307
+ ```
308
+
309
+ ## License
310
+
311
+ [Apache License 2.0](LICENSE)
package/ROADMAP.md ADDED
@@ -0,0 +1,131 @@
1
+ # Safedeps Roadmap
2
+
3
+ > 시간축 + 우선순위. **왜·어떻게** 는 `ARCHITECTURE.md`, **언제·뭐 먼저** 는 이 파일.
4
+
5
+ ---
6
+
7
+ ## 결정 SSoT
8
+
9
+ **스코프 = 개발 의존성만** (npm / pip / cargo / go / gem / maven / nuget).
10
+ OS-level (nginx / apt / brew / system binary) 은 **별도 도구로 분리**. SRP 측면 더 깔끔.
11
+
12
+ 근거: dev 의존성과 OS 패키지는 운영 결이 다름.
13
+ - dev = "새 기능 → install 명령 → 매번 새 패키지 진입" (install 순간 게이트가 의미 큼).
14
+ - OS = "기존 패키지 security update" (cron 주기 audit + RSS 알람이 더 맞음).
15
+
16
+ → safedeps = dev 의존성 install 단계 결.
17
+ → OS-level 은 별도 (가칭 `infra-cve-monitor` — 미래 v3+).
18
+
19
+ ---
20
+
21
+ ## v1 (출시 완료)
22
+
23
+ **이름**: `npm-reorg-guard`
24
+ **Status**: shipped as v1. GitHub repo has since been renamed to `aldegad/safedeps`.
25
+
26
+ - npm ecosystem 전용.
27
+ - PreToolUse hook (guard.sh): typosquat / curl|bash / 비표준 registry 등 **hardcoded pattern** 차단.
28
+ - PostToolUse hook (verify.sh): lockfile diff + install script 검사 → 의심 시 **reorg** (rollback).
29
+ - 외부 vuln DB 조회 0. self-contained.
30
+
31
+ **한계**:
32
+ - npm 만.
33
+ - 알려진 CVE 검사 X (pattern matching 위주).
34
+ - adversarial 회피 가능.
35
+
36
+ ---
37
+
38
+ ## v2 — Safedeps (현재 작업 중)
39
+
40
+ **이름**: `safedeps`, 내부 engine = `reorg-guard` (v1 자산 보존).
41
+ **Status**: `ARCHITECTURE.md` v2 작성 완료, v2.1 provider/ledger 구현 시작.
42
+
43
+ ### 핵심 변화
44
+ - ecosystem 통합: npm / yarn / pnpm / pip (poetry, uv, pipenv) / cargo / go / gem / maven / nuget.
45
+ - **외부 vuln DB 결합**: OSV.dev (primary) + CISA KEV (hard-risk overlay) + GHSA (cross-check). NVD / deps.dev / Snyk = enrichment.
46
+ - **3-phase defense**:
47
+ 1. Advisory Gate (`safedeps check`) — install 명령 *작성 전* vuln DB 조회 → 안전 spec 결정 → `~/.safedeps/approved-specs/<hash>.json` ledger 기록.
48
+ 2. Hook Enforcement (`safedeps-pre-guard.sh`) — ledger 일치 검증.
49
+ 3. Post-Install Reorg (`safedeps-post-verify.sh`) — v1 engine 그대로 (rollback fallback).
50
+ - Approved spec **TTL** (30일) + **daily re-check** cron (새 CVE 발견 시 revoke + 알람).
51
+ - **No silent fallback**: provider fail = fail-closed + `--allow-unverified` explicit override (observable).
52
+
53
+ ### 구현 마일스톤
54
+
55
+ | 마일스톤 | 산출물 | 의존 |
56
+ |---|---|---|
57
+ | **v2.0-doc** ✅ | `ARCHITECTURE.md` v2 작성·push | — |
58
+ | **v2.0-roadmap** ✅ | 이 문서 | — |
59
+ | **v2.1-rename** ✅ | GitHub repo rename `aldegad/npm-reorg-guard` → `aldegad/safedeps` ✅. 로컬 repo/skill id/path `safedeps` ✅. `safedeps migrate` 로 legacy `~/.npm-reorg-guard` → `~/.safedeps` 이전 + legacy hook cleanup. | v2.0-doc |
60
+ | **v2.1-providers** ✅ | `lib/providers/` 신규 — OSV / KEV / GHSA adapter. 단일 query interface. 응답 cache (TTL 24h). | — |
61
+ | **v2.1-ledger** ✅ | `lib/ledger/` 신규 — approved spec JSON I/O (atomic write, hash 계산, TTL 검사). | v2.1-providers |
62
+ | **v2.1-cli** ✅ | `bin/safedeps` 신규 — `check`, `ledger`, `revoke`, `re-check`, `migrate`, `version` 서브커맨드. | v2.1-providers, v2.1-ledger |
63
+ | **v2.1-guard-patch** ✅ | `scripts/safedeps-pre-guard.sh` 갱신 — ledger 일치 검증 추가 + v1 pattern 유지. | v2.1-ledger |
64
+ | **v2.1-verify-patch** ✅ | `scripts/safedeps-post-verify.sh` 갱신 — approved spec 과 lockfile diff 비교 추가 + v1 reorg 유지. | v2.1-ledger |
65
+ | **v2.1-multi-ecosystem** ✅ | pip / cargo / go / gem / maven / nuget 명령 파싱 + lockfile snapshot. `safedeps-pre-guard.sh` 는 install 분류와 typosquat pattern 을 확장했고, `safedeps-post-verify.sh` 는 monitored dependency files 기준으로 rollback truth 를 공유한다. | v2.1-guard-patch |
66
+ | **v2.1-hook-rename** ✅ | hook 파일 namespacing (`guard.sh` → `safedeps-pre-guard.sh`, `verify.sh` → `safedeps-post-verify.sh`) + cross-engine installer (`scripts/install/install-safedeps-hooks.mjs`, ~/.claude + ~/.codex 자동 등록, idempotent, --uninstall). | v2.1-cli |
67
+ | **v2.1-recheck-cron** ✅ | daily re-check launchd — 전체 approved spec 재 query → 새 CVE/KEV/provider-skip 시 revoke + macOS 알림. | v2.1-providers, v2.1-ledger |
68
+ | **v2.1-tests** ✅ | end-to-end 테스트 — fixture provider 응답 → 명령 시뮬레이션 → ledger / hook / re-check / migration 동작 검증. | 모든 v2.1 |
69
+ | **v2.1-release** | npm package publish (`@aldegad/safedeps`) + GitHub release v2.1.0. | 모든 v2.1 |
70
+
71
+ ### 2026-05-18 릴리즈 전 정리 메모
72
+
73
+ - npm package metadata 는 v2.1.0 기준으로 정합화한다 (`package.json` version + `bin.safedeps`).
74
+ - `npm test` 는 release smoke suite 를 실행한다. full fixture E2E 는 `v2.1-tests` 후속으로 남긴다.
75
+ - daily re-check 는 토큰을 쓰지 않는다. 알렉스가 opt-in 하면 macOS `launchd` user agent 로 `safedeps re-check --json` 을 매일 실행하는 구조가 기본이다. 네트워크는 OSV/CISA/GHSA provider query 에만 사용된다.
76
+ - 실제 local background job 은 `scripts/install/install-safedeps-recheck-agent.mjs` 로 atomic install 한다. wrapper 는 `~/.safedeps/recheck.log` 와 `~/.safedeps/recheck-alerts.jsonl` 를 쓰고, 새 CVE/KEV/revoke/provider-skip 이 있으면 macOS notification 을 띄운다.
77
+
78
+ ### 후속 로드맵 — 전체 workspace inventory audit
79
+
80
+ 전체 repo/lockfile inventory scan 은 safedeps v2.1 daily re-check 와 분리한다. 후보 설계는 최초 one-shot inventory scan 으로 workspace 의 manifest/lockfile 을 발견하고, 사용자가 채택한 spec 만 approved ledger 또는 별도 inventory ledger 에 넣은 뒤 주기 re-check 대상으로 삼는 방식이다. 이렇게 해야 safedeps 의 현재 책임인 install approval gate 와 이미 디스크에 존재하는 dependency audit 의 책임 소재가 섞이지 않는다.
81
+
82
+ ### 우선순위
83
+
84
+ 1. v2.1-release: commit / tag / GitHub release / npm publish.
85
+
86
+ ---
87
+
88
+ ## v3 (미래 — 알렉스 결정 시점)
89
+
90
+ - **plugin model** — 사용자 정의 provider (회사 내부 vuln DB, private registry).
91
+ - **policy file** — `.safedeps.toml` 로 \"우리 팀 정책: KEV hit 자동 block, CVSS 7+ 사용자 컨펌, 특정 패키지 allowlist\" 명시.
92
+ - **CI mode** — `safedeps check --ci` 로 GitHub Actions / CircleCI fail-fast.
93
+ - **transitive risk score** — deps.dev graph 통합. 직접 dep 만 아니라 transitive dep 의 \"위험 점수\" 시각화.
94
+
95
+ ---
96
+
97
+ ## v4+ (장기)
98
+
99
+ - **team-shared ledger** — multi-machine approved spec sync (회사 dev 모두가 같은 ledger 공유).
100
+ - **AI agent integration** — Claude / Codex 가 vuln 발견 시 \"대체 모듈 X 권장\" 직접 제안 (LLM-as-judge).
101
+ - **diff visualization UI** — 두 approved spec snapshot 사이의 dep tree diff 시각화.
102
+
103
+ ---
104
+
105
+ ## 명시적 NON-GOAL (이 도구는 하지 않는다)
106
+
107
+ - **OS-level CVE 감시** (nginx, apt 패키지, system binary). → 별도 도구 `infra-cve-monitor` 결로 분리.
108
+ - **컨테이너 이미지 스캔**. → Trivy / Grype.
109
+ - **runtime 권한 sandbox**. → lavamoat / firejail.
110
+ - **registry 자체의 손상 감지**. → registry 운영사 책임.
111
+ - **사용자 평판 분석 (behavioral)**. → socket.dev.
112
+
113
+ safedeps 의 결 = **\"개발 의존성 install 단계의 advisory + spec gate + rollback\"** 한 줄. 다른 결로 확장하지 않는다 — SRP 측면 다른 도구로 분리.
114
+
115
+ ---
116
+
117
+ ## 관련 미래 도구 (분리 권장)
118
+
119
+ | 도구 | 결 | 관계 |
120
+ |---|---|---|
121
+ | `safedeps` (이것) | dev 의존성 (npm/pip/cargo/...) install 단계 | 현재 작업 |
122
+ | `infra-cve-monitor` (가칭) | nginx / apt / OS package 주기적 audit + RSS 알람 | 미래 별 도구 |
123
+ | `container-scan-bridge` (가칭) | Trivy / Grype wrapper, 컨테이너 이미지 결 | 미래 별 도구 |
124
+
125
+ 세 도구가 같은 결 (\"보안\") 의 다른 layer. 한 skill 에 통합하지 않고 분리.
126
+
127
+ ---
128
+
129
+ ## 변경 history
130
+
131
+ - 2026-05-18: ROADMAP.md 최초 작성. v1 → v2 결정 + v3 / v4 / NON-GOAL 명시. (코덱시 surface:195 합의 + 클로디시 surface:61 작성.)