logshield-cli 0.2.0 → 0.2.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 +57 -75
- package/dist/cli/index.cjs +15 -3
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,119 +1,101 @@
|
|
|
1
|
+
---
|
|
1
2
|
# LogShield
|
|
2
3
|
|
|
3
|
-
**
|
|
4
|
-
|
|
5
|
-
LogShield is a lightweight, developer-focused utility to automatically redact secrets, tokens, credentials, and sensitive data from logs before they are stored, shared, or shipped.
|
|
6
|
-
|
|
7
|
-
It is designed to be:
|
|
8
|
-
- **Deterministic** – predictable behavior, no AI, no guesswork
|
|
9
|
-
- **Safe by default** – minimal false positives in default mode
|
|
10
|
-
- **Strict when needed** – aggressive redaction via `strict` mode
|
|
11
|
-
- **Composable** – rule-based engine, easy to extend
|
|
4
|
+
LogShield is a CLI tool to **redact sensitive data from logs** before sharing them with others, AI tools, or public channels.
|
|
12
5
|
|
|
6
|
+
Designed to be safe by default, deterministic, and free of runtime dependencies.
|
|
13
7
|
---
|
|
14
8
|
|
|
15
|
-
##
|
|
9
|
+
## Install
|
|
16
10
|
|
|
17
|
-
|
|
11
|
+
```bash
|
|
12
|
+
npm install -g logshield-cli
|
|
13
|
+
```
|
|
18
14
|
|
|
19
|
-
|
|
20
|
-
- Compromise production systems
|
|
21
|
-
- Invalidate compliance (GDPR, SOC2)
|
|
22
|
-
- Burn trust instantly
|
|
15
|
+
---
|
|
23
16
|
|
|
24
|
-
|
|
17
|
+
## Usage
|
|
25
18
|
|
|
26
|
-
|
|
19
|
+
Scan a log file:
|
|
27
20
|
|
|
28
|
-
|
|
21
|
+
```bash
|
|
22
|
+
logshield scan app.log
|
|
23
|
+
```
|
|
29
24
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
- Redacts common secrets:
|
|
33
|
-
- API keys
|
|
34
|
-
- Passwords
|
|
35
|
-
- JWT tokens
|
|
36
|
-
- Bearer tokens
|
|
37
|
-
- Stripe keys
|
|
38
|
-
- Cloud credentials (AWS, etc.)
|
|
39
|
-
- Credit cards (Luhn-validated)
|
|
40
|
-
- Two modes:
|
|
41
|
-
- **Default**: conservative, low false positives
|
|
42
|
-
- **Strict**: aggressive, security-first
|
|
43
|
-
- Snapshot-tested, contract-tested
|
|
44
|
-
- Zero runtime dependencies
|
|
25
|
+
Scan from stdin:
|
|
45
26
|
|
|
46
|
-
|
|
27
|
+
```bash
|
|
28
|
+
cat app.log | logshield scan
|
|
29
|
+
```
|
|
47
30
|
|
|
48
|
-
|
|
31
|
+
Strict mode (more aggressive):
|
|
49
32
|
|
|
50
33
|
```bash
|
|
51
|
-
|
|
34
|
+
logshield scan app.log --strict
|
|
52
35
|
```
|
|
53
36
|
|
|
54
|
-
|
|
37
|
+
JSON output:
|
|
55
38
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
39
|
+
```bash
|
|
40
|
+
logshield scan app.log --json
|
|
41
|
+
```
|
|
59
42
|
|
|
60
|
-
|
|
61
|
-
import { sanitizeLog } from "logshield";
|
|
43
|
+
Summary only (printed to stderr):
|
|
62
44
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
// password=<REDACTED_PASSWORD>
|
|
45
|
+
```bash
|
|
46
|
+
logshield scan app.log --summary
|
|
66
47
|
```
|
|
67
48
|
|
|
68
|
-
|
|
49
|
+
---
|
|
69
50
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
51
|
+
## What Gets Redacted
|
|
52
|
+
|
|
53
|
+
- API keys
|
|
54
|
+
- Passwords
|
|
55
|
+
- JWT tokens
|
|
56
|
+
- `Bearer <TOKEN>` (always redacted)
|
|
57
|
+
- Stripe keys
|
|
58
|
+
- Cloud credentials (AWS, etc.)
|
|
59
|
+
- Credit cards (Luhn-validated)
|
|
73
60
|
|
|
74
61
|
---
|
|
75
62
|
|
|
76
|
-
##
|
|
63
|
+
## Modes
|
|
77
64
|
|
|
78
|
-
###
|
|
65
|
+
### Default (recommended)
|
|
79
66
|
|
|
80
|
-
|
|
67
|
+
- Conservative
|
|
68
|
+
- Low false positives
|
|
69
|
+
- Safe for sharing logs publicly
|
|
81
70
|
|
|
82
|
-
|
|
83
|
-
{
|
|
84
|
-
output: string;
|
|
85
|
-
matches: {
|
|
86
|
-
rule: string;
|
|
87
|
-
match: string;
|
|
88
|
-
}[];
|
|
89
|
-
}
|
|
90
|
-
```
|
|
71
|
+
### Strict
|
|
91
72
|
|
|
92
|
-
-
|
|
93
|
-
-
|
|
73
|
+
- Aggressive
|
|
74
|
+
- Security-first
|
|
75
|
+
- May redact more than necessary
|
|
94
76
|
|
|
95
77
|
---
|
|
96
78
|
|
|
97
|
-
## Design
|
|
79
|
+
## Design Guarantees
|
|
98
80
|
|
|
99
|
-
-
|
|
100
|
-
-
|
|
101
|
-
-
|
|
102
|
-
|
|
103
|
-
|
|
81
|
+
- Deterministic output
|
|
82
|
+
- Zero runtime dependencies
|
|
83
|
+
- Snapshot-tested & contract-tested
|
|
84
|
+
- No network calls
|
|
85
|
+
- No telemetry
|
|
104
86
|
|
|
105
87
|
---
|
|
106
88
|
|
|
107
|
-
##
|
|
89
|
+
## Example
|
|
108
90
|
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
- Pro ruleset (enterprise patterns)
|
|
91
|
+
```bash
|
|
92
|
+
cat server.log | logshield scan --strict --summary
|
|
93
|
+
```
|
|
113
94
|
|
|
114
95
|
---
|
|
115
96
|
|
|
116
97
|
## License
|
|
117
98
|
|
|
118
|
-
|
|
99
|
+
ISC
|
|
119
100
|
|
|
101
|
+
---
|
package/dist/cli/index.cjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
|
|
2
|
+
#!/usr/bin/env node
|
|
3
3
|
"use strict";
|
|
4
4
|
var __create = Object.create;
|
|
5
5
|
var __defProp = Object.defineProperty;
|
|
@@ -347,14 +347,26 @@ var init_sanitizeLog = __esm({
|
|
|
347
347
|
});
|
|
348
348
|
|
|
349
349
|
// src/cli/index.ts
|
|
350
|
+
var import_fs = require("fs");
|
|
351
|
+
var import_path = __toESM(require("path"));
|
|
350
352
|
var { readInput: readInput2 } = (init_readInput(), __toCommonJS(readInput_exports));
|
|
351
353
|
var { writeOutput: writeOutput2 } = (init_writeOutput(), __toCommonJS(writeOutput_exports));
|
|
352
354
|
var { printSummary: printSummary2 } = (init_summary(), __toCommonJS(summary_exports));
|
|
353
355
|
var { sanitizeLog: sanitizeLog2 } = (init_sanitizeLog(), __toCommonJS(sanitizeLog_exports));
|
|
356
|
+
var __dirname = import_path.default.dirname(process.argv[1]);
|
|
354
357
|
var args = process.argv.slice(2);
|
|
355
358
|
function hasFlag(flag) {
|
|
356
359
|
return args.includes(flag);
|
|
357
360
|
}
|
|
361
|
+
function getVersion() {
|
|
362
|
+
try {
|
|
363
|
+
const pkgPath = import_path.default.resolve(__dirname, "../../package.json");
|
|
364
|
+
const pkg = JSON.parse((0, import_fs.readFileSync)(pkgPath, "utf8"));
|
|
365
|
+
return pkg.version;
|
|
366
|
+
} catch {
|
|
367
|
+
return "unknown";
|
|
368
|
+
}
|
|
369
|
+
}
|
|
358
370
|
function getFileArg() {
|
|
359
371
|
const file = args[1];
|
|
360
372
|
if (!file || file.startsWith("--")) return void 0;
|
|
@@ -374,7 +386,7 @@ Options:
|
|
|
374
386
|
process.exit(0);
|
|
375
387
|
}
|
|
376
388
|
if (hasFlag("--version")) {
|
|
377
|
-
|
|
389
|
+
console.log(`logshield v${getVersion()}`);
|
|
378
390
|
process.exit(0);
|
|
379
391
|
}
|
|
380
392
|
const command = args[0];
|
|
@@ -394,7 +406,7 @@ Options:
|
|
|
394
406
|
printSummary2(result.matches);
|
|
395
407
|
}
|
|
396
408
|
} catch (err) {
|
|
397
|
-
process.stderr.write(err
|
|
409
|
+
process.stderr.write(err?.message || "Unexpected error");
|
|
398
410
|
process.stderr.write("\n");
|
|
399
411
|
process.exit(2);
|
|
400
412
|
}
|