trawly 0.0.1 → 0.1.1

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/README.md CHANGED
@@ -1,12 +1,14 @@
1
1
  # trawly
2
2
 
3
- A dependency sanity scanner for JavaScript projects. Reads exact installed
4
- versions from your `package-lock.json` and queries the
5
- [OSV](https://google.github.io/osv.dev/api/) advisory database for known
6
- vulnerabilities.
3
+ A dependency risk gate for JavaScript projects and SBOMs. Reads exact installed
4
+ versions from npm, pnpm, and Yarn lockfiles, or from SPDX/CycloneDX Package
5
+ URLs, and queries the [OSV](https://google.github.io/osv.dev/api/) advisory
6
+ database for known vulnerabilities. It also flags supply-chain risk signals such
7
+ as install scripts, deprecated packages, unexpected registries, and unusually
8
+ new packages.
7
9
 
8
- > **Limitation:** trawly reports known advisories. It cannot prove a package is
9
- > safe : absence of findings is not absence of risk.
10
+ > **Limitation:** trawly reports known advisories and heuristic signals. It
11
+ > cannot prove a package is safe : absence of findings is not absence of risk.
10
12
 
11
13
  ## Install
12
14
 
@@ -27,11 +29,32 @@ npx trawly inspect
27
29
  # gating run : exits non-zero when findings meet --fail-on (default: high). Use this in CI.
28
30
  npx trawly scan
29
31
 
30
- # scan a specific lockfile
32
+ # create trawly.toml and a baseline for existing findings
33
+ npx trawly init
34
+
35
+ # scan specific lockfiles or SBOMs
31
36
  npx trawly scan --lockfile path/to/package-lock.json
37
+ npx trawly scan --lockfile pnpm-lock.yaml --lockfile yarn.lock
38
+ npx trawly scan --sbom bom.cdx.json --sbom bom.spdx.json
32
39
 
33
- # JSON output (stable schema, suitable for CI artefacts)
40
+ # machine-readable output
34
41
  npx trawly scan --format json > trawly-report.json
42
+ npx trawly scan --format sarif --output trawly.sarif
43
+ npx trawly scan --format markdown --output trawly.md
44
+
45
+ # include committed .env-file checks
46
+ npx trawly scan --env
47
+
48
+ # use built-in policy presets
49
+ npx trawly scan --policy strict
50
+ npx trawly scan --policy library
51
+
52
+ # fail only on findings absent from a saved baseline
53
+ npx trawly scan --baseline trawly-baseline.json
54
+ npx trawly inspect --write-baseline trawly-baseline.json
55
+
56
+ # explain where a package appears in the lockfile
57
+ npx trawly why lodash
35
58
 
36
59
  # only production deps
37
60
  npx trawly scan --prod
@@ -56,14 +79,25 @@ Both produce identical output. Only the exit behaviour differs.
56
79
  ```
57
80
  trawly scan [path] Gating run. Exits non-zero when --fail-on is met.
58
81
  trawly inspect [path] Log-only run. Always exits 0 on findings.
82
+ trawly init [path] Write trawly.toml and an initial baseline.
83
+ trawly why <pkg> [path] Explain where a package appears in lockfiles.
59
84
 
60
85
  Common options (both commands):
61
86
 
62
- --lockfile <path> Explicit path to package-lock.json
63
- --format table|json Output format (default: table)
87
+ --lockfile <path> Explicit lockfile path; may be repeated
88
+ --sbom <path> Explicit SPDX/CycloneDX SBOM path; may be repeated
89
+ --format table|json|markdown|sarif
90
+ Output format (default: table)
91
+ --output <path> Write report output to a file
92
+ --config <path> Path to trawly.toml
93
+ --policy ci|strict|library|app
94
+ Apply built-in scan defaults
95
+ --baseline <path> Mark existing findings and fail only on new ones
96
+ --write-baseline <path> Write the current active findings baseline
97
+ --risk / --no-risk Override risk signals (default: config, otherwise on)
98
+ --env / --no-env Override committed .env scanning (CLI default: off)
64
99
  --prod Skip dev dependencies
65
100
  --include-dev Include dev dependencies (default)
66
- --no-cache Bypass any local cache
67
101
  -v, --details Show one row per advisory instead of grouping
68
102
  -q, --summary Print only the one-line severity summary
69
103
 
@@ -72,6 +106,18 @@ scan-only:
72
106
  (critical|high|moderate|low|none, default: high)
73
107
  ```
74
108
 
109
+ ### Policy presets
110
+
111
+ Policy presets are conservative defaults that can be overridden by explicit CLI
112
+ flags or `trawly.toml`.
113
+
114
+ | Policy | Fail on | Risk signals | Env scan | Dev deps | Best for |
115
+ | --------- | -------- | ------------ | -------- | -------- | ------------------------- |
116
+ | `ci` | high | on | off | included | Default CI gate |
117
+ | `strict` | moderate | on | on | included | Security-sensitive repos |
118
+ | `library` | moderate | on | off | excluded | Published packages |
119
+ | `app` | high | on | on | included | Deployed applications |
120
+
75
121
  ### Exit codes
76
122
 
77
123
  | Code | Meaning |
@@ -104,14 +150,18 @@ The result follows this shape:
104
150
  "source": "osv",
105
151
  "type": "vulnerability",
106
152
  "severity": "high",
153
+ "ecosystem": "npm",
107
154
  "packageName": "lodash",
108
155
  "installedVersion": "4.17.20",
109
156
  "summary": "Prototype pollution in lodash",
110
157
  "url": "https://github.com/advisories/GHSA-...",
111
158
  "fixedVersions": ["4.17.21"],
112
159
  "affectedPaths": ["node_modules/lodash"],
160
+ "fingerprint": "sha256...",
161
+ "aliases": ["CVE-..."],
113
162
  },
114
163
  ],
164
+ "ignoredFindings": [],
115
165
  "summary": {
116
166
  "critical": 0,
117
167
  "high": 1,
@@ -120,9 +170,32 @@ The result follows this shape:
120
170
  "unknown": 0,
121
171
  },
122
172
  "errors": [],
173
+ "warnings": [],
123
174
  }
124
175
  ```
125
176
 
177
+ ## Config
178
+
179
+ trawly auto-discovers `trawly.toml` in the scanned project, or you can pass
180
+ `--config`.
181
+
182
+ ```toml
183
+ failOn = "high"
184
+ policy = "ci"
185
+ risk = true
186
+ env = false
187
+ allowedRegistries = ["https://registry.npmjs.org", "https://registry.yarnpkg.com"]
188
+
189
+ [[ignore]]
190
+ id = "GHSA-example"
191
+ package = "lodash"
192
+ ecosystem = "npm"
193
+ expires = "2026-06-30"
194
+ reason = "Not reachable in our app"
195
+ ```
196
+
197
+ Every ignore entry must include an expiry date.
198
+
126
199
  ## CI example (GitHub Actions)
127
200
 
128
201
  ```yaml
@@ -131,25 +204,56 @@ on: [push, pull_request]
131
204
  jobs:
132
205
  scan:
133
206
  runs-on: ubuntu-latest
207
+ permissions:
208
+ contents: read
209
+ security-events: write
134
210
  steps:
135
- - uses: actions/checkout@v4
136
- - uses: actions/setup-node@v4
137
- with: { node-version: 20 }
138
- - run: npm ci
139
- - run: npx trawly scan --fail-on high --format json > trawly.json
211
+ - uses: actions/checkout@v6
212
+ # Pin to the reviewed release commit SHA instead of a mutable branch.
213
+ - uses: Arindam200/trawly@<full-length-commit-sha>
214
+ with:
215
+ fail-on: high
216
+ upload-sarif: "true"
217
+ env-scan: "true"
140
218
  - uses: actions/upload-artifact@v4
141
219
  if: always()
142
- with: { name: trawly-report, path: trawly.json }
220
+ with:
221
+ name: trawly-report
222
+ path: |
223
+ trawly.sarif
224
+ trawly.md
143
225
  ```
144
226
 
227
+ ## Testing
228
+
229
+ ```bash
230
+ npm test
231
+ npm run typecheck
232
+ npm run build
233
+
234
+ # Extra parser dialect corpus and generated invariant checks.
235
+ npm run test:corpus
236
+
237
+ # Live differential checks against npm, pnpm, Yarn classic, and Yarn Berry.
238
+ npm run test:differential
239
+
240
+ # Larger generated graphs and OSV reliability behavior.
241
+ npm run test:stress
242
+ ```
243
+
244
+ The optional `trawly-reliability` workflow can run the corpus, package-manager
245
+ differential, and stress layers on demand in GitHub Actions.
246
+
145
247
  ## Roadmap
146
248
 
147
- trawly v0 covers npm + OSV. Planned next:
249
+ Implemented in this branch:
148
250
 
149
251
  - pnpm and Yarn lockfile support
150
252
  - SARIF + Markdown reporters and a GitHub Action
151
253
  - Config file with ignore entries (with required expiry)
152
254
  - Baseline mode (fail only on new findings)
153
- - Risk signals: install scripts, unexpected registries, package age
255
+ - `init` onboarding command
256
+ - Policy presets: `ci`, `strict`, `library`, `app`
257
+ - `why` lockfile locator command
258
+ - Risk signals: install scripts, deprecated packages, unexpected registries, package age
154
259
  - Multi-ecosystem scanning via SBOM (SPDX, CycloneDX)
155
-