logshield-cli 0.3.1 → 0.3.2
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 +52 -23
- package/dist/cli/index.cjs +18 -7
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
# ?? LogShield
|
|
2
|
+
|
|
3
|
+
LogShield is a CLI tool to **redact real sensitive data from logs** before sharing them with others, AI tools, CI systems, or public channels.
|
|
3
4
|
|
|
4
|
-
|
|
5
|
+
It is designed to be **deterministic**, **safe by default**, and free of runtime dependencies.
|
|
5
6
|
|
|
6
|
-
Designed to be safe by default, deterministic, and free of runtime dependencies.
|
|
7
7
|
---
|
|
8
8
|
|
|
9
9
|
## Install
|
|
@@ -22,41 +22,55 @@ Scan a log file:
|
|
|
22
22
|
logshield scan app.log
|
|
23
23
|
```
|
|
24
24
|
|
|
25
|
-
Scan from stdin:
|
|
25
|
+
Scan from stdin (auto-detected):
|
|
26
26
|
|
|
27
27
|
```bash
|
|
28
28
|
cat app.log | logshield scan
|
|
29
29
|
```
|
|
30
30
|
|
|
31
|
-
|
|
31
|
+
Explicit stdin mode:
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
cat app.log | logshield scan --stdin
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
Strict mode (more aggressive redaction):
|
|
32
38
|
|
|
33
39
|
```bash
|
|
34
40
|
logshield scan app.log --strict
|
|
35
41
|
```
|
|
36
42
|
|
|
37
|
-
JSON output:
|
|
43
|
+
JSON output (machine-readable):
|
|
38
44
|
|
|
39
45
|
```bash
|
|
40
46
|
logshield scan app.log --json
|
|
41
47
|
```
|
|
42
48
|
|
|
43
|
-
|
|
49
|
+
Print summary to stderr:
|
|
44
50
|
|
|
45
51
|
```bash
|
|
46
52
|
logshield scan app.log --summary
|
|
47
53
|
```
|
|
48
54
|
|
|
55
|
+
Fail CI if any secret is detected:
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
logshield scan app.log --strict --fail-on-detect
|
|
59
|
+
```
|
|
60
|
+
|
|
49
61
|
---
|
|
50
62
|
|
|
51
63
|
## What Gets Redacted
|
|
52
64
|
|
|
53
|
-
-
|
|
54
|
-
-
|
|
65
|
+
- Passwords (`password=...`, DB URLs)
|
|
66
|
+
- API keys (query params, headers)
|
|
55
67
|
- JWT tokens
|
|
56
|
-
- `Bearer <TOKEN>`
|
|
57
|
-
- Stripe keys
|
|
58
|
-
- Cloud credentials (AWS
|
|
59
|
-
-
|
|
68
|
+
- `Authorization: Bearer <TOKEN>`
|
|
69
|
+
- Stripe secret keys
|
|
70
|
+
- Cloud credentials (AWS access & secret keys)
|
|
71
|
+
- OAuth access & refresh tokens
|
|
72
|
+
- Credit cards (Luhn-validated, strict mode)
|
|
73
|
+
- URLs (sanitized to avoid leaking endpoints)
|
|
60
74
|
|
|
61
75
|
---
|
|
62
76
|
|
|
@@ -65,24 +79,29 @@ logshield scan app.log --summary
|
|
|
65
79
|
### Default (recommended)
|
|
66
80
|
|
|
67
81
|
- Conservative
|
|
68
|
-
-
|
|
69
|
-
-
|
|
82
|
+
- Very low false positives
|
|
83
|
+
- Preserves debugging context
|
|
70
84
|
|
|
71
85
|
### Strict
|
|
72
86
|
|
|
73
|
-
- Aggressive
|
|
74
87
|
- Security-first
|
|
75
|
-
-
|
|
88
|
+
- Redacts more aggressively
|
|
89
|
+
- Suitable for CI, support bundles, and AI sharing
|
|
76
90
|
|
|
77
91
|
---
|
|
78
92
|
|
|
79
93
|
## Design Guarantees
|
|
80
94
|
|
|
81
|
-
|
|
95
|
+
These guarantees are **locked for v0.3.x**:
|
|
96
|
+
|
|
97
|
+
- Deterministic output (same input ? same output)
|
|
82
98
|
- Zero runtime dependencies
|
|
83
|
-
- Snapshot-tested & contract-tested
|
|
84
99
|
- No network calls
|
|
85
|
-
- No telemetry
|
|
100
|
+
- No telemetry or tracking
|
|
101
|
+
- Snapshot-tested & contract-tested
|
|
102
|
+
- Fixed rule order (token ? credential ? cloud ? CC ? URL ? custom)
|
|
103
|
+
|
|
104
|
+
When in doubt, LogShield prefers **not** to redact.
|
|
86
105
|
|
|
87
106
|
---
|
|
88
107
|
|
|
@@ -94,8 +113,18 @@ cat server.log | logshield scan --strict --summary
|
|
|
94
113
|
|
|
95
114
|
---
|
|
96
115
|
|
|
97
|
-
##
|
|
116
|
+
## Non-goals
|
|
98
117
|
|
|
99
|
-
|
|
118
|
+
LogShield is **not**:
|
|
119
|
+
|
|
120
|
+
- A DLP system
|
|
121
|
+
- A runtime security monitor
|
|
122
|
+
- A replacement for secret rotation
|
|
123
|
+
|
|
124
|
+
It is a **last-line safety net**, not a primary defense.
|
|
100
125
|
|
|
101
126
|
---
|
|
127
|
+
|
|
128
|
+
## License
|
|
129
|
+
|
|
130
|
+
ISC
|
package/dist/cli/index.cjs
CHANGED
|
@@ -380,17 +380,19 @@ var { printSummary: printSummary2 } = (init_summary(), __toCommonJS(summary_expo
|
|
|
380
380
|
var { sanitizeLog: sanitizeLog2 } = (init_sanitizeLog(), __toCommonJS(sanitizeLog_exports));
|
|
381
381
|
var rawArgs = process.argv.slice(2);
|
|
382
382
|
function getVersion() {
|
|
383
|
-
return true ? "0.3.
|
|
383
|
+
return true ? "0.3.2" : "unknown";
|
|
384
384
|
}
|
|
385
385
|
function printHelp() {
|
|
386
386
|
process.stdout.write(`Usage: logshield scan [file]
|
|
387
387
|
|
|
388
388
|
Options:
|
|
389
|
-
--strict
|
|
390
|
-
--
|
|
391
|
-
--
|
|
392
|
-
--
|
|
393
|
-
--
|
|
389
|
+
--strict Aggressive redaction
|
|
390
|
+
--stdin Read input from STDIN explicitly
|
|
391
|
+
--fail-on-detect Exit with code 1 if any redaction occurs
|
|
392
|
+
--json JSON output
|
|
393
|
+
--summary Print summary
|
|
394
|
+
--version Print version
|
|
395
|
+
--help Show help
|
|
394
396
|
`);
|
|
395
397
|
}
|
|
396
398
|
function parseArgs(args) {
|
|
@@ -424,13 +426,22 @@ async function main() {
|
|
|
424
426
|
const strict = flags.has("--strict");
|
|
425
427
|
const json = flags.has("--json");
|
|
426
428
|
const summary = flags.has("--summary");
|
|
429
|
+
const stdin = flags.has("--stdin");
|
|
430
|
+
const failOnDetect = flags.has("--fail-on-detect");
|
|
431
|
+
if (stdin && file) {
|
|
432
|
+
process.stderr.write("Cannot use --stdin with file argument\n");
|
|
433
|
+
process.exit(1);
|
|
434
|
+
}
|
|
427
435
|
try {
|
|
428
|
-
const input = await readInput2(file);
|
|
436
|
+
const input = await readInput2(stdin ? void 0 : file);
|
|
429
437
|
const result = sanitizeLog2(input, { strict });
|
|
430
438
|
writeOutput2(result, { json });
|
|
431
439
|
if (summary) {
|
|
432
440
|
printSummary2(result.matches);
|
|
433
441
|
}
|
|
442
|
+
if (failOnDetect && result.matches.length > 0) {
|
|
443
|
+
process.exit(1);
|
|
444
|
+
}
|
|
434
445
|
process.exit(0);
|
|
435
446
|
} catch (err) {
|
|
436
447
|
process.stderr.write(err?.message || "Unexpected error");
|