logshield-cli 0.5.0 → 0.6.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/CHANGELOG.md +18 -0
- package/README.md +45 -37
- package/dist/cli/index.cjs +61 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,23 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## v0.6.0
|
|
4
|
+
|
|
5
|
+
### Added
|
|
6
|
+
|
|
7
|
+
- Redact modern platform tokens (GitHub, Slack, npm, PyPI, SendGrid)
|
|
8
|
+
- Redact npmrc auth tokens (`:_authToken=...`)
|
|
9
|
+
- Redact private key blocks (PEM/OpenSSH, including ENCRYPTED PRIVATE KEY)
|
|
10
|
+
|
|
11
|
+
### Docs
|
|
12
|
+
|
|
13
|
+
- Clarified redaction coverage by mode (Default vs Strict) in README and docs
|
|
14
|
+
- Documented the 200KB input safety cap
|
|
15
|
+
|
|
16
|
+
### Notes
|
|
17
|
+
|
|
18
|
+
- No CLI flag changes
|
|
19
|
+
- This release may redact more secrets in default mode (intended)
|
|
20
|
+
|
|
3
21
|
## v0.5.0
|
|
4
22
|
|
|
5
23
|
### Security
|
package/README.md
CHANGED
|
@@ -46,7 +46,7 @@ After LogShield, the same logs are safe to share.
|
|
|
46
46
|
|
|
47
47
|
Use LogShield whenever logs leave your system:
|
|
48
48
|
|
|
49
|
-
- Before
|
|
49
|
+
- Before logs end up in CI output or artifacts
|
|
50
50
|
- Before attaching logs to GitHub issues
|
|
51
51
|
- Before sending logs to third-party support
|
|
52
52
|
- Before sharing logs in Slack or email
|
|
@@ -72,9 +72,9 @@ Use without --dry-run to apply.
|
|
|
72
72
|
|
|
73
73
|
Notes:
|
|
74
74
|
|
|
75
|
-
- The report is printed to stdout
|
|
75
|
+
- The report is printed to **stdout** (human-readable)
|
|
76
76
|
- No log content is echoed
|
|
77
|
-
-
|
|
77
|
+
- In non-`--dry-run` mode, sanitized logs/JSON are written to stdout; summaries/errors go to stderr
|
|
78
78
|
|
|
79
79
|
```bash
|
|
80
80
|
# Enforce redaction (sanitized output)
|
|
@@ -84,10 +84,6 @@ echo "email=test@example.com Authorization: Bearer abcdefghijklmnop" | logshield
|
|
|
84
84
|
- Prefer `--dry-run` first in CI to verify you are not over-redacting.
|
|
85
85
|
- Then switch to enforced mode once you are satisfied with the preview.
|
|
86
86
|
|
|
87
|
-
LogShield is a CLI tool that scans logs and redacts **real secrets**
|
|
88
|
-
(API keys, tokens, credentials) before logs are shared with others,
|
|
89
|
-
AI tools, CI systems, or public channels.
|
|
90
|
-
|
|
91
87
|
It is designed to be **predictable, conservative, and safe for production pipelines**.
|
|
92
88
|
|
|
93
89
|
---
|
|
@@ -104,24 +100,6 @@ They are deployed to **https://logshield.dev** via Vercel.
|
|
|
104
100
|
- GitHub: https://github.com/afria85/LogShield
|
|
105
101
|
- Sponsor: https://github.com/sponsors/afria85
|
|
106
102
|
|
|
107
|
-
## Local preview (website)
|
|
108
|
-
|
|
109
|
-
To preview the website on your computer:
|
|
110
|
-
|
|
111
|
-
```bash
|
|
112
|
-
npm run dev
|
|
113
|
-
```
|
|
114
|
-
|
|
115
|
-
To preview on a phone/tablet on the same Wi-Fi:
|
|
116
|
-
|
|
117
|
-
```bash
|
|
118
|
-
npm run dev:lan
|
|
119
|
-
```
|
|
120
|
-
|
|
121
|
-
Then open the printed LAN URL on your device.
|
|
122
|
-
|
|
123
|
-
---
|
|
124
|
-
|
|
125
103
|
## Why LogShield exists
|
|
126
104
|
|
|
127
105
|
Logs are frequently copied into:
|
|
@@ -154,7 +132,7 @@ The same input always produces the same output.
|
|
|
154
132
|
- No environment-dependent behavior
|
|
155
133
|
- Safe for CI, audits, and reproducibility
|
|
156
134
|
|
|
157
|
-
### 2.
|
|
135
|
+
### 2. Prefer precision over recall
|
|
158
136
|
|
|
159
137
|
LogShield must **not** redact non-secrets.
|
|
160
138
|
|
|
@@ -220,6 +198,21 @@ If a file is not provided and input is piped, LogShield automatically reads from
|
|
|
220
198
|
|
|
221
199
|
Note: the npm package ships the CLI only; there is no supported JS API surface.
|
|
222
200
|
|
|
201
|
+
### Limits
|
|
202
|
+
|
|
203
|
+
- Maximum input size: **200KB** (safety cap). Oversized input exits with code `2`.
|
|
204
|
+
|
|
205
|
+
|
|
206
|
+
### Windows note
|
|
207
|
+
|
|
208
|
+
If `logshield` is not found after a global install, ensure your npm global bin directory is on `PATH`.
|
|
209
|
+
|
|
210
|
+
Check it with:
|
|
211
|
+
|
|
212
|
+
- `npm prefix -g` (add this directory to PATH)
|
|
213
|
+
|
|
214
|
+
Restart your terminal after updating PATH.
|
|
215
|
+
|
|
223
216
|
---
|
|
224
217
|
|
|
225
218
|
## CLI Flags
|
|
@@ -264,7 +257,7 @@ logshield scan app.log
|
|
|
264
257
|
cat app.log | logshield scan
|
|
265
258
|
```
|
|
266
259
|
|
|
267
|
-
`--stdin` is optional; piped input is auto-detected.
|
|
260
|
+
`--stdin` is optional; piped input is auto-detected. Use `--stdin` to force reading from stdin in TTY/paste workflows.
|
|
268
261
|
|
|
269
262
|
---
|
|
270
263
|
|
|
@@ -333,7 +326,7 @@ jobs:
|
|
|
333
326
|
|
|
334
327
|
- uses: actions/setup-node@v4
|
|
335
328
|
with:
|
|
336
|
-
node-version:
|
|
329
|
+
node-version: 22
|
|
337
330
|
|
|
338
331
|
- run: npm install -g logshield-cli
|
|
339
332
|
|
|
@@ -425,16 +418,32 @@ Notes:
|
|
|
425
418
|
|
|
426
419
|
## What gets redacted
|
|
427
420
|
|
|
428
|
-
|
|
421
|
+
LogShield uses a fixed, deterministic rule set. The exact coverage depends on the selected mode.
|
|
422
|
+
|
|
423
|
+
### Default mode (recommended)
|
|
429
424
|
|
|
430
|
-
- Passwords (
|
|
431
|
-
- API key headers
|
|
432
|
-
-
|
|
425
|
+
- Passwords (quoted and JSON forms)
|
|
426
|
+
- API key headers (e.g. `x-api-key: ...`)
|
|
427
|
+
- API keys (e.g. `api_key=...`, `api-key: ...`)
|
|
428
|
+
- Authorization Bearer tokens
|
|
433
429
|
- JWTs
|
|
430
|
+
- GitHub tokens (`ghp_`, `gho_`, `ghu_`, `ghs_`, `ghr_`, and `github_pat_...`)
|
|
431
|
+
- Slack tokens (`xox*` and `xapp-...`)
|
|
432
|
+
- npm access tokens (`npm_...`)
|
|
433
|
+
- npmrc auth tokens (`:_authToken=...`)
|
|
434
|
+
- PyPI API tokens (`pypi-...`)
|
|
435
|
+
- SendGrid API keys (`SG.<...>.<...>`)
|
|
436
|
+
- Private key blocks (PEM/OpenSSH)
|
|
434
437
|
- Emails
|
|
435
438
|
- URLs with embedded credentials
|
|
436
|
-
- Database credentials (including redis
|
|
437
|
-
- Cloud
|
|
439
|
+
- Database URL credentials (including `redis://...` and `mssql://...`)
|
|
440
|
+
- Cloud credentials in explicit labeled forms (e.g. `AWS_SECRET_ACCESS_KEY=...`)
|
|
441
|
+
|
|
442
|
+
### Strict mode (adds)
|
|
443
|
+
|
|
444
|
+
- Stripe secret keys (e.g. `sk_live_...`, `sk_test_...`)
|
|
445
|
+
- AWS access keys (`AKIA...`)
|
|
446
|
+
- AWS secret keys (strict fallback)
|
|
438
447
|
- Credit card numbers (Luhn-validated)
|
|
439
448
|
|
|
440
449
|
---
|
|
@@ -460,7 +469,7 @@ Depending on rules and mode:
|
|
|
460
469
|
LogShield guarantees:
|
|
461
470
|
|
|
462
471
|
- Deterministic output
|
|
463
|
-
- Stable behavior within the current minor line **v0.
|
|
472
|
+
- Stable behavior within the current minor line **v0.6.x**
|
|
464
473
|
- No runtime dependencies
|
|
465
474
|
- Snapshot-tested and contract-tested
|
|
466
475
|
- No telemetry
|
|
@@ -490,8 +499,7 @@ It is a **last-line safety net**, not a primary defense.
|
|
|
490
499
|
|
|
491
500
|
## License
|
|
492
501
|
|
|
493
|
-
Apache-2.0
|
|
494
|
-
---
|
|
502
|
+
Apache-2.0 — see `LICENSE`.
|
|
495
503
|
|
|
496
504
|
## Contributing
|
|
497
505
|
|
package/dist/cli/index.cjs
CHANGED
|
@@ -157,6 +157,66 @@ var tokenRules;
|
|
|
157
157
|
var init_tokens = __esm({
|
|
158
158
|
"src/rules/tokens.ts"() {
|
|
159
159
|
tokenRules = [
|
|
160
|
+
// Multi-line private key blocks (PEM/OpenSSH). Run early to avoid leaking
|
|
161
|
+
// partial material through other rules.
|
|
162
|
+
{
|
|
163
|
+
name: "PRIVATE_KEY_BLOCK",
|
|
164
|
+
pattern: /-----BEGIN\s+(?:(?:RSA|EC|DSA)\s+)?(?:ENCRYPTED\s+)?PRIVATE\s+KEY-----[\s\S]*?-----END\s+(?:(?:RSA|EC|DSA)\s+)?(?:ENCRYPTED\s+)?PRIVATE\s+KEY-----/gi,
|
|
165
|
+
replace: () => "<REDACTED_PRIVATE_KEY_BLOCK>"
|
|
166
|
+
},
|
|
167
|
+
{
|
|
168
|
+
name: "OPENSSH_PRIVATE_KEY_BLOCK",
|
|
169
|
+
pattern: /-----BEGIN OPENSSH PRIVATE KEY-----[\s\S]*?-----END OPENSSH PRIVATE KEY-----/g,
|
|
170
|
+
replace: () => "<REDACTED_PRIVATE_KEY_BLOCK>"
|
|
171
|
+
},
|
|
172
|
+
{
|
|
173
|
+
name: "PRIVATE_KEY_HEADER",
|
|
174
|
+
pattern: /-----BEGIN\s+(?:(?:RSA|EC|DSA)\s+)?(?:ENCRYPTED\s+)?PRIVATE\s+KEY-----|-----BEGIN OPENSSH PRIVATE KEY-----/gi,
|
|
175
|
+
replace: () => "<REDACTED_PRIVATE_KEY_HEADER>"
|
|
176
|
+
},
|
|
177
|
+
// Modern platform tokens (prefix-anchored, low false-positive).
|
|
178
|
+
{
|
|
179
|
+
name: "GITHUB_TOKEN",
|
|
180
|
+
pattern: /\b(?:ghp|gho|ghu|ghs|ghr)_[A-Za-z0-9]{36,255}\b/g,
|
|
181
|
+
replace: () => "<REDACTED_GITHUB_TOKEN>"
|
|
182
|
+
},
|
|
183
|
+
{
|
|
184
|
+
name: "GITHUB_FINE_GRAINED_TOKEN",
|
|
185
|
+
pattern: /\bgithub_pat_[A-Za-z0-9]{22}_[A-Za-z0-9]{59}\b/g,
|
|
186
|
+
replace: () => "<REDACTED_GITHUB_TOKEN>"
|
|
187
|
+
},
|
|
188
|
+
{
|
|
189
|
+
name: "SLACK_TOKEN",
|
|
190
|
+
pattern: /\bxox(?:b|p|a|s|r)-[A-Za-z0-9-]{10,250}\b/g,
|
|
191
|
+
replace: () => "<REDACTED_SLACK_TOKEN>"
|
|
192
|
+
},
|
|
193
|
+
{
|
|
194
|
+
name: "SLACK_APP_TOKEN",
|
|
195
|
+
pattern: /\bxapp-\d-[A-Za-z0-9-]{10,250}\b/g,
|
|
196
|
+
replace: () => "<REDACTED_SLACK_TOKEN>"
|
|
197
|
+
},
|
|
198
|
+
{
|
|
199
|
+
name: "NPM_TOKEN",
|
|
200
|
+
pattern: /\bnpm_[A-Za-z0-9]{36}\b/g,
|
|
201
|
+
replace: () => "<REDACTED_NPM_TOKEN>"
|
|
202
|
+
},
|
|
203
|
+
{
|
|
204
|
+
name: "NPMRC_AUTH_TOKEN",
|
|
205
|
+
// .npmrc-style auth token, commonly seen as:
|
|
206
|
+
// //registry.npmjs.org/:_authToken=...
|
|
207
|
+
pattern: /(:_authToken\s*=\s*)([^\s\r\n]+)/gi,
|
|
208
|
+
replace: (_match, _ctx, groups) => `${groups[0]}<REDACTED_NPM_TOKEN>`
|
|
209
|
+
},
|
|
210
|
+
{
|
|
211
|
+
name: "PYPI_TOKEN",
|
|
212
|
+
pattern: /\bpypi-[A-Za-z0-9_-]{85,200}\b/g,
|
|
213
|
+
replace: () => "<REDACTED_PYPI_TOKEN>"
|
|
214
|
+
},
|
|
215
|
+
{
|
|
216
|
+
name: "SENDGRID_API_KEY",
|
|
217
|
+
pattern: /\bSG\.[A-Za-z0-9_-]{22}\.[A-Za-z0-9_-]{43}\b/g,
|
|
218
|
+
replace: () => "<REDACTED_SENDGRID_KEY>"
|
|
219
|
+
},
|
|
160
220
|
{
|
|
161
221
|
name: "JWT",
|
|
162
222
|
pattern: /\beyJ[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\b/g,
|
|
@@ -535,7 +595,7 @@ var ALLOWED_FLAGS = /* @__PURE__ */ new Set([
|
|
|
535
595
|
"--help"
|
|
536
596
|
]);
|
|
537
597
|
function getVersion() {
|
|
538
|
-
return true ? "0.
|
|
598
|
+
return true ? "0.6.0" : "unknown";
|
|
539
599
|
}
|
|
540
600
|
function printHelp() {
|
|
541
601
|
process.stdout.write(`Usage: logshield scan [file]
|