@aldegad/safedeps 2.1.1 → 2.2.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/ARCHITECTURE.md +268 -462
- package/README.ko.md +34 -12
- package/README.md +65 -38
- package/ROADMAP.md +82 -87
- package/SKILL.md +13 -7
- package/bin/safedeps +385 -52
- package/lib/gates/audit.sh +36 -0
- package/lib/gates/hooks.sh +93 -0
- package/lib/gates/repo-profile.sh +60 -0
- package/lib/gates/scan.sh +94 -0
- package/lib/ledger/ledger.sh +94 -16
- package/lib/npm/closure.sh +115 -0
- package/lib/providers/providers.sh +244 -25
- package/package.json +1 -1
- package/scripts/install/install-safedeps-hooks.mjs +62 -23
- package/scripts/release-gates.sh +252 -0
- package/scripts/safedeps-post-verify.sh +167 -10
- package/scripts/safedeps-pre-guard.sh +270 -32
- package/scripts/test/e2e.sh +180 -4
- package/scripts/test/fixture-provider.mjs +21 -0
- package/scripts/test/smoke.sh +135 -10
package/README.ko.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
> **모든 install 을 미확정 블록으로 본다 — `safedeps` 는 안전한 것만 승인하고, 그렇지 않으면 reorg 한다.**
|
|
4
4
|
>
|
|
5
|
-
> OSV / CISA KEV / GitHub Advisory 로 의존성 spec 을 사전 승인하고, Claude Code 와 Codex CLI 의 hook 에서
|
|
5
|
+
> OSV / CISA KEV / GitHub Advisory 로 의존성 spec 을 사전 승인하고, Claude Code 와 Codex CLI 의 hook 에서 실제 설치 closure 를 강제하며, 승인과 어긋난 install 은 자동으로 마지막 안전 snapshot 으로 롤백한다.
|
|
6
6
|
|
|
7
7
|
*Detailed reference → [README.md](./README.md) (영문, SSoT)*
|
|
8
8
|
|
|
@@ -12,28 +12,50 @@
|
|
|
12
12
|
|
|
13
13
|
블록체인에서 **reorg (재편성)** 은 미확정 블록 시퀀스를 무효화하고 마지막 확정된 안전 상태로 체인을 되돌린다. `safedeps` 는 같은 원리를 `node_modules` 에 적용한다 — 모든 install 은 일련의 공급망 보안 검사를 통과하기 전까지는 **미확정 블록 후보** 로 취급된다. 의심스러우면 도구가 **reorg** 를 수행한다 — lock 파일, `package.json`, `node_modules` 를 마지막 확정된 안전 snapshot 으로 되돌린다.
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
빠른 advisory 피드백, 관측 가능한 rollback, silent fallback 없음. command guard 는 best-effort UX 이고, 설치 결과 effect 가 backstop 이다.
|
|
16
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
## 두 lane
|
|
20
|
+
|
|
21
|
+
`safedeps` 는 두 보안 lane 을 소유한다 (전체 설계: [`ARCHITECTURE.md`](./ARCHITECTURE.md) §1):
|
|
22
|
+
|
|
23
|
+
- **install-time** (이 README 의 초점) — advisory check + approved-spec ledger + 빠른 PreToolUse guard + PostToolUse effect enforcement + post-install reorg. 패키지 단위, install 명령과 실제 lockfile effect 주변.
|
|
24
|
+
- **release-time** — `safedeps gates run`, `safedeps scan secrets [--repo|--worktree|--staged]`, `safedeps audit npm`, `safedeps hooks install|check`. repo 트리 secret scan, 의존성 audit, repo-local git hook 설치/검사 (push/release 전). repo-specific policy(gitleaks config, privacy 경로)는 대상 repo 에 남고 safedeps 는 실행 owner. *(옛 `security-release-gates` 흡수.)*
|
|
16
25
|
|
|
17
26
|
---
|
|
18
27
|
|
|
19
28
|
## 어떻게 동작
|
|
20
29
|
|
|
30
|
+
`safedeps` 는 모든 install 을 두 동작으로 감싼다:
|
|
31
|
+
|
|
32
|
+
- **설치 전** — `safedeps check` 가 패키지를 OSV(canonical) + CISA KEV + GitHub Advisory 로 검사하고 로컬 ledger 에 승인을 기록한다. npm 은 패키지의 전체 의존성 closure 를 풀어 딸린 모든 transitive 패키지까지 검사한다.
|
|
33
|
+
- **설치 후** — PostToolUse hook 이 실제 `package-lock.json` 에 뭐가 깔렸는지 다시 읽고, ledger 에 없거나 advisory DB 가 새로 취약하다고 답하는 패키지를 reorg(롤백)한다.
|
|
34
|
+
|
|
35
|
+
설치 전 command hook(PreToolUse)은 빠른 advisory 넛지다 — 명백한 미승인 install 과 위험한 명령 형태를 막아 에이전트에게 즉시 피드백을 준다. 하지만 npm 의 진짜 권위는 설치 후 effect gate 다: 명령이 *어떻게 생겼는지* 가 아니라 *실제로 뭐가 깔렸는지* 를 보기 때문에, wrapper 나 난독화된 install 명령으로도 패키지를 통과시킬 수 없다.
|
|
36
|
+
|
|
37
|
+
**스크립트 안전 (무실행 설치).** Claude Code 에서는 PreToolUse hook 이 npm install 에 `--ignore-scripts` 를 붙여 rewrite 한다 — 그래서 설치가 **무실행(inert)** 으로 돈다(패키지는 디스크에 앉되 lifecycle script 는 아직 안 돎). 그다음 effect gate 가 closure 를 검증하고, 통과했을 때만 PostToolUse 가 `npm rebuild` 로 이제서야 검증된 스크립트를 실행한다. 게이트가 거부한 패키지는 *스크립트가 한 번도 돌기 전에* reorg 된다. (Claude Code 의 hook `updatedInput` 기능을 쓴다. Codex CLI 는 이 기능이 없어 Codex 에서는 install 이 정상 실행되고 effect gate 는 detect-and-rollback 이다 — 악성 install script 가 롤백 전에 1회 실행될 수 있다.)
|
|
38
|
+
|
|
39
|
+
이 effect-primary 모델은 현재 npm 한정이다. `pip`, `cargo`, `go`, `gem`, `maven`, `nuget` 은 closure resolver 가 붙기 전까지 v2.1 command-gate + reorg 모델을 유지한다.
|
|
40
|
+
|
|
21
41
|
```
|
|
22
42
|
PreToolUse PostToolUse
|
|
23
43
|
(safedeps-pre-guard.sh) (safedeps-post-verify.sh)
|
|
24
44
|
| |
|
|
25
|
-
install cmd ──> [ Advisory / ledger
|
|
45
|
+
install cmd ──> [ Advisory / ledger UX ] ──> [ Execute ] ──> [ npm effect gate ]
|
|
26
46
|
| | | |
|
|
27
|
-
|
|
28
|
-
block
|
|
47
|
+
명백한 miss/ lock / manifest 깨끗? 의심?
|
|
48
|
+
risk block snapshot | |
|
|
29
49
|
Confirm REORG
|
|
30
50
|
```
|
|
31
51
|
|
|
32
52
|
### 3 단계 구성
|
|
33
53
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
54
|
+
**① Advisory check (`safedeps check`)** — `safedeps check <ecosystem> <pkg>@<range>` 가 OSV(canonical) + CISA KEV(hard-risk overlay) + GHSA(enrichment) 를 조회한다. npm 은 temp dir 에서 `npm install --package-lock-only --ignore-scripts` 로 스크립트 실행 없는 lockfile 을 만들어 전체 closure 를 뽑고 OSV `/v1/querybatch` 로 묶어 검사한다. 깨끗하면 direct spec 과 `transitive_specs` 를 `~/.safedeps/approved-specs/<hash>.json` 에 30일 TTL 로 기록한다.
|
|
55
|
+
|
|
56
|
+
**② 빠른 command guard (`safedeps-pre-guard.sh`, PreToolUse)** — install 명령의 `pkg@version` 토큰을 ledger 와 대조하고 lockfile/manifest 를 snapshot 한다. 미승인이면 차단하고, 다음에 실행할 `safedeps check ...` 명령을 차단 사유에 박아준다 (PATH 에 있으면 `safedeps`, 없으면 절대경로). 에이전트는 그 메시지로 check → 재시도하면 된다. 이 단계는 빠른 advisory/UX 일 뿐 최종 권위는 아니다.
|
|
57
|
+
|
|
58
|
+
**③ Effect gate + reorg (`safedeps-post-verify.sh`, PostToolUse)** — 설치 후 실제 `package-lock.json` closure 전체를 ledger 의 direct entry + `transitive_specs` 와 대조하고 OSV batch 로 재확인한다. **npm 에서는 이 effect gate 가 primary 권위다.** 미승인·취약·provider fail-closed, 또는 의심스러운 install script·native binary 가 있으면 마지막 confirmed snapshot 으로 자동 reorg 한다.
|
|
37
59
|
|
|
38
60
|
---
|
|
39
61
|
|
|
@@ -119,16 +141,16 @@ node scripts/install/install-safedeps-recheck-agent.mjs install --hour 9 --minut
|
|
|
119
141
|
전형적인 흐름:
|
|
120
142
|
|
|
121
143
|
1. 에이전트가 `npm install foo@1.2.3` 같은 명령을 작성한다.
|
|
122
|
-
2. PreToolUse hook 이
|
|
144
|
+
2. PreToolUse hook 이 빠른 advisory ledger check 를 수행한다. direct spec 이 없거나 만료됐거나 명백히 위험하면 install 을 **차단**하고, 다음에 실행할 정확한 `safedeps check npm foo@1.2.3` 명령을 reason 에 박아 에이전트에게 돌려준다.
|
|
123
145
|
3. 에이전트가 그 안내를 받아 `safedeps check` 를 호출 → OSV / CISA KEV / GitHub Advisory 조회 → 안전하면 **허용목록 (ledger) 에 박는다**. KEV 매치면 hard-block (override 불가), CVE 에 patch 가 있으면 안전 버전으로 자동 narrow.
|
|
124
146
|
4. 다시 install 시도 → 이번엔 ledger 매치되어 **통과**.
|
|
125
|
-
5. install 후 PostToolUse hook 이 lockfile / install script / native binary 를
|
|
147
|
+
5. install 후 PostToolUse hook 이 npm primary authority 로 실제 lockfile closure 를 direct ledger / `transitive_specs` / OSV batch 와 대조하고, install script / native binary 를 검증한다. 어긋나면 마지막 안전 snapshot 으로 **자동 reorg**.
|
|
126
148
|
|
|
127
|
-
이 흐름으로
|
|
149
|
+
이 흐름으로 일반적인 package-manager install 명령은 실행 전에 빠른 advisory 피드백을 받고, npm install 은 실행 후 effect-time closure enforcement 를 받는다. 다만 command hook 은 best-effort 명령 휴리스틱이지 sandbox 가 아니다. 비정상 wrapper/interpreter 경로나 같은 사용자 권한으로 로컬 safedeps 상태를 조작하는 공격은 ledger 서명/강화 전까지 trust boundary 밖이다. npm effect-primary 모델은 아직 `pip`, `cargo`, `go`, `gem`, `maven`, `nuget` 에 적용되지 않으며, 이 ecosystem 들은 v2.1 command-gate + reorg 모델을 유지한다. SaaS 의존 없이 로컬 + 공개 DB (OSV / KEV / GHSA) 만 쓴다.
|
|
128
150
|
|
|
129
151
|
---
|
|
130
152
|
|
|
131
|
-
## Legacy
|
|
153
|
+
## Legacy / Migration: v1 `npm-reorg-guard`
|
|
132
154
|
|
|
133
155
|
v1 시절 이름이 `npm-reorg-guard` 였고 state 디렉토리가 `~/.npm-reorg-guard/` 였다. v2 로 rename 되면서 state 도 `~/.safedeps/` 로 옮겨야 하는데, 그 1회 이전을 자동화한 명령이 있다:
|
|
134
156
|
|
package/README.md
CHANGED
|
@@ -2,13 +2,13 @@
|
|
|
2
2
|
|
|
3
3
|
> **Treat every install as an unconfirmed block — `safedeps` approves the safe ones, reorgs the rest.**
|
|
4
4
|
>
|
|
5
|
-
> Pre-approve dependency installs against OSV / CISA KEV / GitHub Advisory, enforce
|
|
5
|
+
> Pre-approve dependency installs against OSV / CISA KEV / GitHub Advisory, enforce the installed closure from Claude Code and Codex CLI hooks, and auto-rollback any install that diverges from the approved closure. *(한국어 README → [README.ko.md](./README.ko.md))*
|
|
6
6
|
|
|
7
7
|
## Why "reorg"?
|
|
8
8
|
|
|
9
9
|
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.
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
Fast advisory feedback, observable rollback, and no hidden fallback. The command guard is best-effort UX; the installed effect is the backstop.
|
|
12
12
|
|
|
13
13
|
## Distribution Model
|
|
14
14
|
|
|
@@ -19,19 +19,35 @@ Safedeps has two distribution surfaces:
|
|
|
19
19
|
|
|
20
20
|
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.
|
|
21
21
|
|
|
22
|
+
## Two Lanes
|
|
23
|
+
|
|
24
|
+
`safedeps` owns two security lanes (full design in [`ARCHITECTURE.md`](./ARCHITECTURE.md) §1):
|
|
25
|
+
|
|
26
|
+
- **Install-time** (the focus of this README) — advisory check + approved-spec ledger + fast PreToolUse guard + PostToolUse effect enforcement + post-install reorg. Per-package, around the install command and its actual lockfile effect.
|
|
27
|
+
- **Release-time** — `safedeps gates run`, `safedeps scan secrets [--repo|--worktree|--staged]`, `safedeps audit npm`, `safedeps hooks install|check`. Repo-tree secret scan, dependency audit, and repo-local git hook install/check before push/release. Repo-specific policy (gitleaks config, privacy paths) stays in the target repo; safedeps owns execution. *(Absorbed the former `security-release-gates`.)*
|
|
28
|
+
|
|
22
29
|
## How It Works
|
|
23
30
|
|
|
24
|
-
`safedeps`
|
|
31
|
+
`safedeps` works in two moves around every install:
|
|
32
|
+
|
|
33
|
+
- **Before** — `safedeps check` clears a package against OSV (canonical), CISA KEV, and GitHub Advisory, then records the approval in a local ledger. For npm it resolves the package's full dependency closure and checks every transitive package too.
|
|
34
|
+
- **After** — the PostToolUse hook re-reads what actually landed in `package-lock.json` and reorgs (rolls back) anything that isn't in the ledger or that the advisory databases now flag.
|
|
35
|
+
|
|
36
|
+
The pre-install command hook (PreToolUse) is a fast advisory nudge — it blocks obvious unapproved installs and risky command forms so the agent gets immediate feedback. But for npm the real authority is the post-install effect gate: it judges what was *actually installed*, not what the command looked like, so a wrapped or obfuscated install command can't slip a package past it.
|
|
37
|
+
|
|
38
|
+
**Script safety (inert install).** On Claude Code, the PreToolUse hook rewrites an npm install to add `--ignore-scripts`, so the install runs **inert** — packages land on disk but no lifecycle script runs yet. The effect gate then verifies the closure; only if it passes does the PostToolUse hook run `npm rebuild` to execute the now-verified scripts. A package the gate rejects is reorged before any of its scripts run. (This uses the Claude Code hook `updatedInput` capability. Codex CLI does not expose it, so on Codex the install runs normally and the effect gate is detect-and-rollback — a malicious install script can run once before the rollback.)
|
|
39
|
+
|
|
40
|
+
This effect-primary model is npm-only for now. `pip`, `cargo`, `go`, `gem`, `maven`, and `nuget` stay on the v2.1 command-gate + reorg model until their closure resolvers land.
|
|
25
41
|
|
|
26
42
|
```
|
|
27
43
|
PreToolUse PostToolUse
|
|
28
44
|
(safedeps-pre-guard.sh) (safedeps-post-verify.sh)
|
|
29
45
|
| |
|
|
30
|
-
install cmd ──> [ Advisory/ledger
|
|
46
|
+
install cmd ──> [ Advisory/ledger UX ] ──> [ Execute ] ──> [ npm effect gate ]
|
|
31
47
|
| | | |
|
|
32
|
-
Block
|
|
33
|
-
|
|
34
|
-
|
|
48
|
+
Block obvious Snapshot Clean? Suspicious?
|
|
49
|
+
misses/risk lock/manifest files, | |
|
|
50
|
+
package listings Confirm REORG
|
|
35
51
|
| |
|
|
36
52
|
| v v
|
|
37
53
|
+--- parent_snapshot_id ──> confirmed
|
|
@@ -40,7 +56,7 @@ Use the GitHub release when you want the full skill/hook source tree as the cano
|
|
|
40
56
|
confirmed snapshot
|
|
41
57
|
```
|
|
42
58
|
|
|
43
|
-
### Phase 1: Advisory
|
|
59
|
+
### Phase 1: Advisory Check (`safedeps check`)
|
|
44
60
|
|
|
45
61
|
Before an agent installs a dependency, it should run:
|
|
46
62
|
|
|
@@ -48,40 +64,44 @@ Before an agent installs a dependency, it should run:
|
|
|
48
64
|
safedeps check <ecosystem> <pkg>@<version|range> --json
|
|
49
65
|
```
|
|
50
66
|
|
|
51
|
-
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
|
|
67
|
+
That command queries OSV (canonical), CISA KEV (hard-risk overlay), and GitHub Advisory (enrichment). For npm, it first creates a script-free temp lockfile with `npm install --package-lock-only --ignore-scripts`, extracts the full dependency closure, and queries OSV `/v1/querybatch`. Clean or safely narrowed specs are written to `~/.safedeps/approved-specs/`; npm entries also record `transitive_specs`.
|
|
68
|
+
|
|
69
|
+
### Phase 2: Fast Command Guard + Snapshots (PreToolUse)
|
|
52
70
|
|
|
53
|
-
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:
|
|
71
|
+
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 provides a fast advisory/UX layer:
|
|
54
72
|
|
|
55
73
|
1. **Snapshots** the current `package-lock.json`, `pnpm-lock.yaml`, `yarn.lock`, and `package.json` into `~/.safedeps/snapshots/`.
|
|
56
74
|
2. **Records metadata** including a `parent_snapshot_id` linking to the previous confirmed snapshot (forming a chain, just like blocks).
|
|
57
75
|
3. **Captures pre-install state** of `node_modules` (package listings and binary listings) for diff-based detection later.
|
|
58
|
-
4. **
|
|
76
|
+
4. **Fast-checks the approved-spec ledger** for explicit `pkg@version` install commands.
|
|
59
77
|
5. **Runs pre-flight checks** and **blocks** the command entirely if it detects:
|
|
60
78
|
- Typosquatting package names (`lod_sh`, `reacct`, `axois`, etc.)
|
|
61
79
|
- Non-standard `--registry` URLs (anything outside `registry.npmjs.org` and `registry.yarnpkg.com`)
|
|
62
80
|
- Piped remote execution patterns (`curl ... | bash`)
|
|
63
81
|
- Explicit disabling of install script safety (`npm config set ignore-scripts false`)
|
|
64
82
|
|
|
65
|
-
If the ledger gate or a pre-flight check fails, the command is **blocked before execution** -- nothing is installed.
|
|
83
|
+
If the ledger gate or a pre-flight check fails, the command is **blocked before execution** -- nothing is installed. This command guard is intentionally best-effort; it improves the agent loop and catches direct misses, while npm authority lives in the post-install effect gate.
|
|
84
|
+
|
|
85
|
+
### Phase 3: Post-install Effect Enforcement (`safedeps-post-verify.sh` -- PostToolUse)
|
|
66
86
|
|
|
67
|
-
|
|
87
|
+
After the install command completes, the verify hook analyzes what changed. For npm, this is the primary enforcement surface: it reads the actual `package-lock.json` closure, verifies every package against approved direct entries and their `transitive_specs`, and re-checks the closure with OSV batch.
|
|
68
88
|
|
|
69
|
-
|
|
89
|
+
1. **npm effect gate** -- Reorgs if any lockfile package is unapproved, KEV-blocked, vulnerable, or cannot be verified fail-closed.
|
|
70
90
|
|
|
71
|
-
|
|
91
|
+
2. **Install script analysis** -- Scans newly added packages for `preinstall`, `install`, and `postinstall` scripts containing:
|
|
72
92
|
- Network access (`curl`, `wget`, `fetch`, `http`, `socket`, `dns`)
|
|
73
93
|
- Dynamic code execution (`eval`, `exec`, `spawn`, `child_process`, `Function()`)
|
|
74
94
|
- Sensitive path access (`~/.ssh`, `.env`, `.aws`, `credentials`)
|
|
75
95
|
- Obfuscated content (`base64`, `atob`, `Buffer.from`, hex/unicode escapes)
|
|
76
96
|
|
|
77
|
-
|
|
97
|
+
3. **Lock file diff analysis** -- Compares the snapshotted lock file content against the post-install version:
|
|
78
98
|
- Resolved URLs pointing to non-standard registries
|
|
79
99
|
- Insecure protocols (`http://`, `git://`) in resolved URLs
|
|
80
100
|
- Unusually large dependency additions (>50 new resolved entries, indicating potential dependency confusion)
|
|
81
101
|
|
|
82
|
-
|
|
102
|
+
4. **Binary inspection** -- Checks `node_modules/.bin/` for newly added native binaries (ELF, Mach-O, shared objects) that should not appear in a JavaScript project.
|
|
83
103
|
|
|
84
|
-
###
|
|
104
|
+
### Confirm or Reorg
|
|
85
105
|
|
|
86
106
|
- **All checks pass** -- The snapshot is marked as **confirmed** in `~/.safedeps/confirmed`. This becomes the new safe baseline.
|
|
87
107
|
- **Any check fails** -- A **reorg** is triggered:
|
|
@@ -96,7 +116,7 @@ After the install command completes, the verify hook analyzes what changed:
|
|
|
96
116
|
| Blockchain Concept | Safedeps Equivalent |
|
|
97
117
|
|---|---|
|
|
98
118
|
| **Block candidate** | Snapshot taken before `npm install` |
|
|
99
|
-
| **Block validation** | Post-install
|
|
119
|
+
| **Block validation** | Post-install effect checks (npm closure, scripts, lock diff, binaries) |
|
|
100
120
|
| **Finality / confirmation** | Snapshot ID written to `~/.safedeps/confirmed` |
|
|
101
121
|
| **Chain reorganization** | Rollback to last confirmed snapshot + `node_modules` rebuild |
|
|
102
122
|
| **Parent hash linking** | `parent_snapshot_id` in each snapshot's `_meta.json` |
|
|
@@ -106,18 +126,20 @@ After the install command completes, the verify hook analyzes what changed:
|
|
|
106
126
|
|
|
107
127
|
| Category | What it catches | Phase | Action |
|
|
108
128
|
|---|---|---|---|
|
|
109
|
-
| Typosquatting | Known misspelling patterns of popular packages |
|
|
110
|
-
| Pipe execution | `curl \| bash`, `wget \| sh` |
|
|
111
|
-
| Registry hijack | `--registry` pointing to unofficial sources |
|
|
112
|
-
| Script safety bypass | `npm config set ignore-scripts false` |
|
|
113
|
-
| Command indirection | `eval "npm install ..."`, subshell expansion, variable indirection |
|
|
114
|
-
| npx/dlx execution | `npx`, `pnpm dlx`, `yarn dlx` package execution |
|
|
115
|
-
|
|
|
116
|
-
|
|
|
117
|
-
|
|
|
118
|
-
|
|
|
119
|
-
|
|
|
120
|
-
|
|
|
129
|
+
| Typosquatting | Known misspelling patterns of popular packages | PreToolUse advisory guard | **Block** |
|
|
130
|
+
| Pipe execution | `curl \| bash`, `wget \| sh` | PreToolUse advisory guard | **Block** |
|
|
131
|
+
| Registry hijack | `--registry` pointing to unofficial sources | PreToolUse advisory guard | **Block** |
|
|
132
|
+
| Script safety bypass | `npm config set ignore-scripts false` | PreToolUse advisory guard | **Block** |
|
|
133
|
+
| Command indirection | `eval "npm install ..."`, subshell expansion, variable indirection | PreToolUse advisory guard | **Guard** |
|
|
134
|
+
| npx/dlx execution | `npx`, `pnpm dlx`, `yarn dlx` package execution | PreToolUse advisory guard | **Guard** |
|
|
135
|
+
| Unapproved transitive dependency | npm `package-lock.json` package missing from direct ledger or `transitive_specs` | PostToolUse npm primary effect gate | **Reorg** |
|
|
136
|
+
| Vulnerable closure package | npm direct/transitive package with OSV/KEV hit | PostToolUse npm primary effect gate | **Reorg** |
|
|
137
|
+
| Malicious install scripts | Network calls, `eval`/`exec`, sensitive path access in hooks | PostToolUse effect verify | **Reorg** |
|
|
138
|
+
| Obfuscated code | Base64, hex encoding, `Buffer.from` in install scripts | PostToolUse effect verify | **Reorg** |
|
|
139
|
+
| Lock file tampering | Resolved URLs from non-standard registries | PostToolUse effect verify | **Reorg** |
|
|
140
|
+
| Insecure protocols | `http://` or `git://` resolved URLs | PostToolUse effect verify | **Reorg** |
|
|
141
|
+
| Dependency confusion | >50 new dependencies in a single install | PostToolUse effect verify | **Reorg** |
|
|
142
|
+
| Native binaries | Compiled executables in `node_modules/.bin/` | PostToolUse effect verify | **Reorg** |
|
|
121
143
|
|
|
122
144
|
## Installation
|
|
123
145
|
|
|
@@ -151,7 +173,7 @@ cd safedeps
|
|
|
151
173
|
node scripts/install/install-safedeps-hooks.mjs
|
|
152
174
|
```
|
|
153
175
|
|
|
154
|
-
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`.
|
|
176
|
+
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 — with `--link-bin` — can also place `safedeps` on PATH through `~/.local/bin`. That PATH link is optional: the hooks name an absolute fallback path in their block messages, so the gate is self-contained and works with zero PATH setup.
|
|
155
177
|
|
|
156
178
|
**3. Manual hook registration, if needed:**
|
|
157
179
|
|
|
@@ -286,8 +308,8 @@ safedeps/
|
|
|
286
308
|
providers/ # OSV / CISA KEV / GHSA adapters
|
|
287
309
|
ledger/ # approved-spec ledger
|
|
288
310
|
scripts/
|
|
289
|
-
safedeps-pre-guard.sh # PreToolUse hook --
|
|
290
|
-
safedeps-post-verify.sh # PostToolUse hook --
|
|
311
|
+
safedeps-pre-guard.sh # PreToolUse hook -- advisory ledger UX + snapshots
|
|
312
|
+
safedeps-post-verify.sh # PostToolUse hook -- npm primary effect verification + reorg
|
|
291
313
|
install/install-safedeps-hooks.mjs
|
|
292
314
|
install/install-safedeps-recheck-agent.mjs
|
|
293
315
|
install/migrate-safedeps-state.mjs
|
|
@@ -305,14 +327,19 @@ safedeps/
|
|
|
305
327
|
Typical flow:
|
|
306
328
|
|
|
307
329
|
1. The agent writes `npm install foo@1.2.3` (or any of the other supported install verbs).
|
|
308
|
-
2. The PreToolUse hook
|
|
330
|
+
2. The PreToolUse hook does a fast advisory ledger check. If the direct spec is missing, expired, or obviously risky, it **blocks** the install and returns the exact `safedeps check npm foo@1.2.3` command the agent should run next, in the block reason.
|
|
309
331
|
3. The agent runs `safedeps check`. The CLI queries OSV / CISA KEV / GitHub Advisory and, if safe, **adds the spec to the ledger**. KEV matches are hard-block (no override). CVEs with an available patch are auto-narrowed to the fixed version.
|
|
310
332
|
4. The agent retries the install. The ledger entry now matches, so the install **proceeds**.
|
|
311
|
-
5. After the install, the PostToolUse hook
|
|
333
|
+
5. After the install, the PostToolUse hook is the npm primary authority: it verifies the actual lockfile closure against direct ledger entries, `transitive_specs`, and OSV batch, then checks install scripts and native binaries and **auto-reorgs** to the last confirmed snapshot if anything diverged.
|
|
334
|
+
|
|
335
|
+
Every install command gets fast advisory feedback before it runs; every npm install gets closure-level enforcement after it runs. The suspicious package a human would catch at PR review is already caught at install time — and there is no SaaS dependency, only the local CLI plus public databases (OSV / KEV / GHSA).
|
|
336
|
+
|
|
337
|
+
Two honest boundaries:
|
|
312
338
|
|
|
313
|
-
|
|
339
|
+
- **The command hook is a heuristic, not a sandbox.** Unusual wrappers, shell interpreters, or same-user tampering with local `~/.safedeps` state sit outside its trust boundary. The npm effect gate is the backstop — it catches what the command hook misses, because it inspects the installed result rather than the command text.
|
|
340
|
+
- **Effect-primary enforcement is npm-only today.** `pip`, `cargo`, `go`, `gem`, `maven`, and `nuget` stay on the v2.1 command-gate + reorg model until their closure resolvers land.
|
|
314
341
|
|
|
315
|
-
## Legacy
|
|
342
|
+
## Legacy / Migration: v1 `npm-reorg-guard`
|
|
316
343
|
|
|
317
344
|
The v1 product was named `npm-reorg-guard` and used `~/.npm-reorg-guard/` as the state directory. v2 moves state to `~/.safedeps/`. A one-shot migration is provided:
|
|
318
345
|
|
package/ROADMAP.md
CHANGED
|
@@ -1,131 +1,126 @@
|
|
|
1
1
|
# Safedeps Roadmap
|
|
2
2
|
|
|
3
|
-
>
|
|
3
|
+
> Timeline and priorities. The **why / how** lives in [`ARCHITECTURE.md`](./ARCHITECTURE.md); the **when / what first** lives here. *(한국어 → [ROADMAP.ko.md](./ROADMAP.ko.md))*
|
|
4
4
|
|
|
5
5
|
---
|
|
6
6
|
|
|
7
|
-
##
|
|
7
|
+
## Scope
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
OS-level (nginx / apt / brew / system binary) 은 **별도 도구로 분리**. SRP 측면 더 깔끔.
|
|
9
|
+
Safedeps gates **development dependency installs** (npm / pip / cargo / go / gem / maven / nuget). At release time it also runs a repo-tree secret scan, dependency audit, and git-hook install/check (the lane absorbed from the former `security-release-gates`).
|
|
11
10
|
|
|
12
|
-
|
|
13
|
-
- dev = "새 기능 → install 명령 → 매번 새 패키지 진입" (install 순간 게이트가 의미 큼).
|
|
14
|
-
- OS = "기존 패키지 security update" (cron 주기 audit + RSS 알람이 더 맞음).
|
|
15
|
-
|
|
16
|
-
→ safedeps = dev 의존성 install 단계 결.
|
|
17
|
-
→ OS-level 은 별도 (가칭 `infra-cve-monitor` — 미래 v3+).
|
|
11
|
+
Out of scope: OS / system packages, container images, runtime sandboxing, registry integrity, and reputation analysis. Those are different security layers and stay in different tools — see [`ARCHITECTURE.md`](./ARCHITECTURE.md) §1 for the boundary.
|
|
18
12
|
|
|
19
13
|
---
|
|
20
14
|
|
|
21
|
-
## v1 (
|
|
22
|
-
|
|
23
|
-
**이름**: `npm-reorg-guard`
|
|
24
|
-
**Status**: shipped as v1. GitHub repo has since been renamed to `aldegad/safedeps`.
|
|
15
|
+
## v1 — `npm-reorg-guard` (shipped)
|
|
25
16
|
|
|
26
|
-
- npm
|
|
27
|
-
- PreToolUse hook
|
|
28
|
-
- PostToolUse hook
|
|
29
|
-
- 외부 vuln DB 조회 0. self-contained.
|
|
17
|
+
- npm-only, self-contained, no external advisory database.
|
|
18
|
+
- PreToolUse hook: typosquat / `curl | bash` / non-standard registry pattern blocks.
|
|
19
|
+
- PostToolUse hook: lockfile diff + install-script analysis → reorg (rollback) on suspicion.
|
|
30
20
|
|
|
31
|
-
|
|
32
|
-
- npm 만.
|
|
33
|
-
- 알려진 CVE 검사 X (pattern matching 위주).
|
|
34
|
-
- adversarial 회피 가능.
|
|
21
|
+
Limits: npm only, no CVE lookup (pattern matching), evadable by a determined adversary. The GitHub repo has since been renamed `aldegad/safedeps`.
|
|
35
22
|
|
|
36
23
|
---
|
|
37
24
|
|
|
38
|
-
## v2 —
|
|
25
|
+
## v2 — `safedeps` (shipped, v2.1.x)
|
|
39
26
|
|
|
40
|
-
|
|
41
|
-
**Status**: `ARCHITECTURE.md` v2 작성 완료, v2.1 provider/ledger 구현 시작.
|
|
27
|
+
The internal engine keeps the v1 `reorg-guard` assets.
|
|
42
28
|
|
|
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).
|
|
29
|
+
### What changed
|
|
52
30
|
|
|
53
|
-
|
|
31
|
+
- **Multi-ecosystem**: npm / yarn / pnpm / pip (poetry, uv, pipenv) / cargo / go / gem / maven / nuget.
|
|
32
|
+
- **External advisory databases**: OSV.dev (canonical) + CISA KEV (hard-risk overlay) + GitHub Advisory (enrichment).
|
|
33
|
+
- **Three-phase defense**:
|
|
34
|
+
1. Advisory gate (`safedeps check`) — query the advisory databases before the install command is written, decide a safe spec, and record it to the `~/.safedeps/approved-specs/` ledger.
|
|
35
|
+
2. Hook enforcement (`safedeps-pre-guard.sh`) — verify the install matches the ledger.
|
|
36
|
+
3. Post-install reorg (`safedeps-post-verify.sh`) — the v1 engine, rolling back on divergence.
|
|
37
|
+
- **Approved-spec TTL** (30 days) + **daily re-check** (revoke + alert when a new CVE appears).
|
|
38
|
+
- **No silent fallback**: a provider failure is fail-closed; any override is explicit and observable.
|
|
54
39
|
|
|
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 |
|
|
40
|
+
### Milestones (all shipped)
|
|
70
41
|
|
|
71
|
-
|
|
42
|
+
| Milestone | Output |
|
|
43
|
+
|---|---|
|
|
44
|
+
| `v2.0-doc` | `ARCHITECTURE.md` v2 written and pushed. |
|
|
45
|
+
| `v2.1-rename` | Repo / skill id / paths renamed to `safedeps`; `safedeps migrate` moves legacy `~/.npm-reorg-guard` state to `~/.safedeps` and cleans up legacy hooks. |
|
|
46
|
+
| `v2.1-providers` | `lib/providers/` — OSV / KEV / GHSA adapters behind one query interface, with a 24h response cache. |
|
|
47
|
+
| `v2.1-ledger` | `lib/ledger/` — approved-spec JSON I/O (atomic write, hash, TTL check). |
|
|
48
|
+
| `v2.1-cli` | `bin/safedeps` — `check`, `ledger`, `revoke`, `re-check`, `migrate`, `version` subcommands. |
|
|
49
|
+
| `v2.1-guard-patch` | `safedeps-pre-guard.sh` — ledger enforcement on top of the v1 pattern blocks. |
|
|
50
|
+
| `v2.1-verify-patch` | `safedeps-post-verify.sh` — lockfile-diff comparison against the approved spec on top of the v1 reorg. |
|
|
51
|
+
| `v2.1-multi-ecosystem` | pip / cargo / go / gem / maven / nuget command parsing + lockfile snapshots, shared as rollback truth across both hooks. |
|
|
52
|
+
| `v2.1-hook-rename` | Hook file namespacing + cross-engine installer (`install-safedeps-hooks.mjs`, idempotent, `--uninstall`). |
|
|
53
|
+
| `v2.1-recheck-cron` | Daily re-check LaunchAgent — re-queries every approved spec, revokes + notifies on new CVE/KEV/provider-skip. |
|
|
54
|
+
| `v2.1-tests` | End-to-end tests — fixture provider responses drive ledger / hook / re-check / migration checks. |
|
|
55
|
+
| `v2.1-release` | npm publish (`@aldegad/safedeps`) + GitHub release. |
|
|
72
56
|
|
|
73
|
-
|
|
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 을 띄운다.
|
|
57
|
+
### Release notes
|
|
77
58
|
|
|
78
|
-
|
|
59
|
+
- The npm package version in `package.json` is the single source of truth. `bin/safedeps` `SAFEDEPS_VERSION` tracks it and the smoke test reads `package.json` to compare (current: v2.2.0).
|
|
60
|
+
- `npm test` runs the release smoke suite; the full fixture E2E lives under `v2.1-tests`.
|
|
61
|
+
- The daily re-check uses no LLM tokens. It is opt-in: a macOS `launchd` user agent runs `safedeps re-check --json` daily, installed atomically by `install-safedeps-recheck-agent.mjs`. It writes `~/.safedeps/recheck.log` and `~/.safedeps/recheck-alerts.jsonl` and raises a macOS notification on a new CVE/KEV/revoke/provider-skip. Network is used only for OSV / CISA / GHSA queries.
|
|
79
62
|
|
|
80
|
-
|
|
63
|
+
## v2.2 — effect-based enforcement (npm)
|
|
81
64
|
|
|
82
|
-
|
|
65
|
+
Status: shipped as v2.2.0 (npm-first).
|
|
83
66
|
|
|
84
|
-
|
|
67
|
+
### What changed
|
|
85
68
|
|
|
86
|
-
|
|
69
|
+
- **Authority moved to effects**: PostToolUse now reads the actual `package-lock.json` closure and compares every installed `pkg@version` against approved direct specs plus their `transitive_specs`.
|
|
70
|
+
- **Full closure approval for npm**: `safedeps check npm <pkg>@<version>` resolves a script-free lockfile in a temp dir with `npm install --package-lock-only --ignore-scripts`, extracts the full closure, and queries OSV `/v1/querybatch`.
|
|
71
|
+
- **Batch + cache**: OSV batch responses are written back into the same per `pkg@version` 24h cache used by single-package provider queries.
|
|
72
|
+
- **No blind trust for transitives**: a clean direct package with an unapproved or vulnerable transitive dependency is not enough; the full closure must be clean and recorded.
|
|
73
|
+
- **PreToolUse demoted to fast UX guard**: command parsing still blocks obvious unapproved install attempts and keeps the bypass regression coverage, but PostToolUse is the primary enforcement surface.
|
|
74
|
+
- **Inert install (Claude Code)**: the PreToolUse hook rewrites an npm install to add `--ignore-scripts` via the hook `updatedInput` capability, so the install runs inert; PostToolUse runs `npm rebuild` only after the closure is verified clean, so a rejected package's lifecycle scripts never run. Codex CLI lacks `updatedInput`, so it stays on detect-and-rollback.
|
|
87
75
|
|
|
88
|
-
|
|
76
|
+
### npm-only boundary
|
|
89
77
|
|
|
90
|
-
|
|
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 의 \"위험 점수\" 시각화.
|
|
78
|
+
This phase covers npm lockfile closure only. pip / cargo / go / gem / maven / nuget keep the v2.1 command/ledger/reorg behavior until each ecosystem has an explicit closure resolver and script/no-execution policy.
|
|
94
79
|
|
|
95
|
-
|
|
80
|
+
### Verification
|
|
81
|
+
|
|
82
|
+
- closure approval records `transitive_specs`
|
|
83
|
+
- unapproved transitive package in `package-lock.json` triggers post-verify reorg
|
|
84
|
+
- approved full-closure install passes without false reorg
|
|
85
|
+
- heredoc / echo text does not trigger install detection
|
|
86
|
+
- existing smoke + fixture E2E regression suite remains green
|
|
96
87
|
|
|
97
|
-
|
|
88
|
+
### Current focus
|
|
98
89
|
|
|
99
|
-
|
|
100
|
-
- **AI agent integration** — Claude / Codex 가 vuln 발견 시 \"대체 모듈 X 권장\" 직접 제안 (LLM-as-judge).
|
|
101
|
-
- **diff visualization UI** — 두 approved spec snapshot 사이의 dep tree diff 시각화.
|
|
90
|
+
1. `v2.2.0-release`: merge `safedeps-security-hardening`, tag `v2.2.0`, GitHub release, `npm publish`.
|
|
102
91
|
|
|
103
92
|
---
|
|
104
93
|
|
|
105
|
-
##
|
|
94
|
+
## v3 (future)
|
|
106
95
|
|
|
107
|
-
|
|
108
|
-
- **컨테이너 이미지 스캔**. → Trivy / Grype.
|
|
109
|
-
- **runtime 권한 sandbox**. → lavamoat / firejail.
|
|
110
|
-
- **registry 자체의 손상 감지**. → registry 운영사 책임.
|
|
111
|
-
- **사용자 평판 분석 (behavioral)**. → socket.dev.
|
|
96
|
+
### Ledger tamper resistance
|
|
112
97
|
|
|
113
|
-
|
|
98
|
+
Defends the second-order attack where a malicious package's `postinstall` (running as the user) forges a "B approved" ledger entry so a later install of B skips the advisory check. The package cannot do this *before* it runs, so closing the install-time gate is the first line of defense; this hardens the case where a first compromise already happened.
|
|
114
99
|
|
|
115
|
-
|
|
100
|
+
Approach — **treat OSV as the authority and the ledger as a cache**, plus tamper detection. Cheap, layers onto existing infra:
|
|
101
|
+
|
|
102
|
+
1. **Re-validate at enforcement / re-check** — verify the stored evidence against OSV instead of trusting the ledger verdict. A forged entry with no real evidence (or for a package OSV reports as vulnerable) is caught and revoked. Reduces the ledger to memoization with OSV as SSoT.
|
|
103
|
+
2. **Watch `~/.safedeps/` in the post-install scan** — the post-verify hook already flags `postinstall` scripts that touch `~/.ssh` / `.env`; add `~/.safedeps/` so a package that writes the ledger trips a reorg — catching the forge in the act.
|
|
104
|
+
3. **Provenance cross-check in daily re-check** — flag ledger entries with no matching `advisory.log` record (i.e. no real `safedeps check` ever ran) as suspected forgeries.
|
|
105
|
+
|
|
106
|
+
Explicit non-approach: **cryptographic ledger signing is not pursued** — a same-uid attacker can read the signing key and re-sign forgeries, so a local HMAC/signature adds no real boundary. The defense is authority-elsewhere (OSV) + detection, not local secrets.
|
|
107
|
+
|
|
108
|
+
### Other v3 work
|
|
116
109
|
|
|
117
|
-
|
|
110
|
+
- **Plugin providers** — user-defined advisory sources (internal vuln DB, private registry).
|
|
111
|
+
- **Policy file** — `.safedeps.toml` for team policy (auto-block on KEV hit, user confirm on CVSS 7+, per-package allowlist).
|
|
112
|
+
- **CI mode** — `safedeps check --ci` for fail-fast in GitHub Actions / CircleCI.
|
|
113
|
+
- **Closure expansion beyond npm** — pip / cargo / go / gem / maven / nuget closure resolvers with explicit no-script/no-build policies.
|
|
114
|
+
- **Transitive risk score** — deps.dev graph integration; risk visualization beyond direct dependencies.
|
|
118
115
|
|
|
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, 컨테이너 이미지 결 | 미래 별 도구 |
|
|
116
|
+
## v4+ (long-term)
|
|
124
117
|
|
|
125
|
-
|
|
118
|
+
- **Team-shared ledger** — multi-machine approved-spec sync.
|
|
119
|
+
- **Agent remediation** — Claude / Codex suggests a safer replacement when a vuln is found (LLM-as-judge).
|
|
120
|
+
- **Diff visualization** — dependency-tree diff between two approved-spec snapshots.
|
|
126
121
|
|
|
127
122
|
---
|
|
128
123
|
|
|
129
|
-
##
|
|
124
|
+
## History
|
|
130
125
|
|
|
131
|
-
- 2026-05-18: ROADMAP
|
|
126
|
+
- 2026-05-18: Initial ROADMAP — v1 → v2 decision plus v3 / v4 outline.
|