secretshield 0.3.2__tar.gz → 0.4.1__tar.gz

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.
Files changed (46) hide show
  1. {secretshield-0.3.2 → secretshield-0.4.1}/LICENSE +1 -1
  2. secretshield-0.4.1/PKG-INFO +353 -0
  3. secretshield-0.4.1/README.md +327 -0
  4. {secretshield-0.3.2 → secretshield-0.4.1}/pyproject.toml +5 -3
  5. {secretshield-0.3.2 → secretshield-0.4.1}/secretshield/__init__.py +1 -1
  6. secretshield-0.4.1/secretshield/baseline.py +56 -0
  7. {secretshield-0.3.2 → secretshield-0.4.1}/secretshield/cli.py +335 -42
  8. {secretshield-0.3.2 → secretshield-0.4.1}/secretshield/git/__init__.py +2 -0
  9. {secretshield-0.3.2 → secretshield-0.4.1}/secretshield/git/hooks.py +19 -0
  10. secretshield-0.4.1/secretshield/project_config.py +121 -0
  11. secretshield-0.4.1/secretshield.egg-info/PKG-INFO +353 -0
  12. {secretshield-0.3.2 → secretshield-0.4.1}/secretshield.egg-info/SOURCES.txt +6 -1
  13. secretshield-0.4.1/secretshield.egg-info/requires.txt +6 -0
  14. secretshield-0.4.1/tests/test_baseline.py +58 -0
  15. secretshield-0.4.1/tests/test_project_config.py +75 -0
  16. secretshield-0.4.1/tests/test_v040_cli_integration.py +219 -0
  17. secretshield-0.3.2/PKG-INFO +0 -515
  18. secretshield-0.3.2/README.md +0 -490
  19. secretshield-0.3.2/secretshield.egg-info/PKG-INFO +0 -515
  20. secretshield-0.3.2/secretshield.egg-info/requires.txt +0 -3
  21. {secretshield-0.3.2 → secretshield-0.4.1}/secretshield/autofix/__init__.py +0 -0
  22. {secretshield-0.3.2 → secretshield-0.4.1}/secretshield/autofix/env.py +0 -0
  23. {secretshield-0.3.2 → secretshield-0.4.1}/secretshield/autofix/fixer.py +0 -0
  24. {secretshield-0.3.2 → secretshield-0.4.1}/secretshield/autofix/gitignore.py +0 -0
  25. {secretshield-0.3.2 → secretshield-0.4.1}/secretshield/autofix/python.py +0 -0
  26. {secretshield-0.3.2 → secretshield-0.4.1}/secretshield/config.py +0 -0
  27. {secretshield-0.3.2 → secretshield-0.4.1}/secretshield/detector.py +0 -0
  28. {secretshield-0.3.2 → secretshield-0.4.1}/secretshield/github/__init__.py +0 -0
  29. {secretshield-0.3.2 → secretshield-0.4.1}/secretshield/github/actions.py +0 -0
  30. {secretshield-0.3.2 → secretshield-0.4.1}/secretshield/guardian.py +0 -0
  31. {secretshield-0.3.2 → secretshield-0.4.1}/secretshield/notifications.py +0 -0
  32. {secretshield-0.3.2 → secretshield-0.4.1}/secretshield/patterns.py +0 -0
  33. {secretshield-0.3.2 → secretshield-0.4.1}/secretshield/redactor.py +0 -0
  34. {secretshield-0.3.2 → secretshield-0.4.1}/secretshield.egg-info/dependency_links.txt +0 -0
  35. {secretshield-0.3.2 → secretshield-0.4.1}/secretshield.egg-info/entry_points.txt +0 -0
  36. {secretshield-0.3.2 → secretshield-0.4.1}/secretshield.egg-info/top_level.txt +0 -0
  37. {secretshield-0.3.2 → secretshield-0.4.1}/setup.cfg +0 -0
  38. {secretshield-0.3.2 → secretshield-0.4.1}/tests/test_autofix.py +0 -0
  39. {secretshield-0.3.2 → secretshield-0.4.1}/tests/test_detector.py +0 -0
  40. {secretshield-0.3.2 → secretshield-0.4.1}/tests/test_git_hooks.py +0 -0
  41. {secretshield-0.3.2 → secretshield-0.4.1}/tests/test_github_action.py +0 -0
  42. {secretshield-0.3.2 → secretshield-0.4.1}/tests/test_logging.py +0 -0
  43. {secretshield-0.3.2 → secretshield-0.4.1}/tests/test_redactor.py +0 -0
  44. {secretshield-0.3.2 → secretshield-0.4.1}/tests/test_scan.py +0 -0
  45. {secretshield-0.3.2 → secretshield-0.4.1}/tests/test_stdout.py +0 -0
  46. {secretshield-0.3.2 → secretshield-0.4.1}/tests/test_v030_cli_integration.py +0 -0
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2026 Sam3360
3
+ Copyright (c) 2026 Samarth Chugh (Sam3360)
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
@@ -0,0 +1,353 @@
1
+ Metadata-Version: 2.4
2
+ Name: secretshield
3
+ Version: 0.4.1
4
+ Summary: Detect, redact, and prevent secret exposure in Python apps, source code, and Git commits — runtime protection, multi-language scanning, auto-fix, and CI integration in one tool.
5
+ Author: Samarth Chugh (Sam3360)
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://github.com/Sam3360/secretshield
8
+ Project-URL: Repository, https://github.com/Sam3360/secretshield
9
+ Project-URL: Issues, https://github.com/Sam3360/secretshield/issues
10
+ Keywords: security,secrets,redaction,logging,stdout,credentials
11
+ Classifier: Development Status :: 3 - Alpha
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: Programming Language :: Python :: 3
14
+ Classifier: Programming Language :: Python :: 3.10
15
+ Classifier: Programming Language :: Python :: 3.11
16
+ Classifier: Programming Language :: Python :: 3.12
17
+ Classifier: Topic :: Security
18
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
19
+ Requires-Python: >=3.10
20
+ Description-Content-Type: text/markdown
21
+ License-File: LICENSE
22
+ Requires-Dist: tomli>=2.0; python_version < "3.11"
23
+ Provides-Extra: dev
24
+ Requires-Dist: pytest>=7.0; extra == "dev"
25
+ Dynamic: license-file
26
+
27
+ <div align="center">
28
+
29
+ # 🛡️ SecretShield
30
+
31
+ **Your secrets shouldn't end up in your terminal, your logs, or your commit history.**
32
+ **SecretShield makes sure they don't — automatically.**
33
+
34
+ [![PyPI version](https://img.shields.io/pypi/v/secretshield?color=blue)](https://pypi.org/project/secretshield/)
35
+ [![Python versions](https://img.shields.io/pypi/pyversions/secretshield)](https://pypi.org/project/secretshield/)
36
+ [![PyPI downloads](https://img.shields.io/pypi/dm/secretshield)](https://pypi.org/project/secretshield/)
37
+ [![License: MIT](https://img.shields.io/pypi/l/secretshield)](LICENSE)
38
+
39
+ [Install](#installation) · [Demo](#demo) · [Quick start](#quick-start) · [Features](#what-secretshield-does) · [Docs below](#cli-reference)
40
+
41
+ </div>
42
+
43
+ ---
44
+
45
+ ## The problem
46
+
47
+ You've done this. Everyone has.
48
+
49
+ ```python
50
+ print("API key:", api_key) # ...now it's in your terminal history
51
+ logger.info("Token: %s", token) # ...now it's in your log files
52
+ API_KEY = "sk-live-abc123..." # ...now it's about to get committed
53
+ ```
54
+
55
+ One `print()` left in from debugging. One log line that dumps a config
56
+ dict. One hardcoded key that slips past code review. That's usually all
57
+ it takes.
58
+
59
+ ## The fix
60
+
61
+ ```bash
62
+ pip install secretshield
63
+ ```
64
+
65
+ ```python
66
+ import secretshield
67
+
68
+ api_key = "sk-example1234567890abcdefFAKEKEY"
69
+ print("API key:", api_key)
70
+ ```
71
+
72
+ ```text
73
+ API key: ********
74
+ ⚠ secretshield: Potential secret detected and redacted.
75
+ ```
76
+
77
+ **No configuration. No code changes. Just `pip install` and `import`.**
78
+ The moment you import it, your terminal output, your logs — protected.
79
+
80
+ ## Demo
81
+
82
+ See SecretShield in action:
83
+
84
+ [![SecretShield Demo](https://img.youtube.com/vi/g95lNIhWsXM/maxresdefault.jpg)](https://youtu.be/g95lNIhWsXM)
85
+
86
+ **[▶ Watch the full demo on YouTube](https://youtu.be/g95lNIhWsXM)**
87
+
88
+ ## Quick start
89
+
90
+ ```bash
91
+ pip install secretshield
92
+ ```
93
+
94
+ Protect a running script:
95
+ ```python
96
+ import secretshield # that's it — stdout, stderr, and logging are now protected
97
+ ```
98
+
99
+ Scan an entire project for hardcoded secrets:
100
+ ```bash
101
+ secretshield scan .
102
+ ```
103
+
104
+ Set a whole project up in one step (config file + Git hook + CI):
105
+ ```bash
106
+ secretshield init
107
+ ```
108
+
109
+ ## What SecretShield does
110
+
111
+ SecretShield isn't just one trick — it's five layers that cover the
112
+ whole path a secret takes from your keyboard to a place you can't take
113
+ it back from:
114
+
115
+ | | |
116
+ |---|---|
117
+ | 🖥️ **Runtime protection** | Automatically redacts secrets from `stdout`, `stderr`, and `logging` the instant you `import secretshield` |
118
+ | 🔍 **Static scanning** | `secretshield scan .` finds hardcoded secrets across Python, JS/TS, HTML, YAML, `.env`, and more |
119
+ | 🔧 **Auto-Fix** | `scan . --fix` interactively moves a hardcoded secret into `.env` and rewrites your code to use it — safely, and only when it's unambiguous |
120
+ | 🪝 **Git pre-commit hook** | `install-hook` blocks a commit before a secret ever reaches your repo's history |
121
+ | ⚙️ **GitHub Actions** | `github-action` generates a workflow that scans every push and PR automatically |
122
+
123
+ All of it: **zero required dependencies, no telemetry, no network calls, nothing sent anywhere.** Everything happens locally, in your own process.
124
+
125
+ ## Why star this repo
126
+
127
+ If SecretShield has ever caught something before it hit your terminal
128
+ or your Git history — that's the whole point of the project working.
129
+ Starring it costs nothing and helps the next developer who's about to
130
+ `print()` an API key by accident actually find this before it's too
131
+ late.
132
+
133
+ ---
134
+
135
+ ## Installation
136
+
137
+ ```bash
138
+ pip install secretshield
139
+ ```
140
+
141
+ Requires Python 3.10+. No required third-party runtime dependencies
142
+ (a tiny `tomli` backport is pulled in automatically, but only on Python 3.10).
143
+
144
+ ## Basic usage
145
+
146
+ ```python
147
+ import secretshield
148
+
149
+ password = "hunter2-example-not-real"
150
+ print("Using password:", password)
151
+ ```
152
+
153
+ ```text
154
+ Using password: ********
155
+ ⚠ secretshield: Potential secret detected and redacted.
156
+ ```
157
+
158
+ Toggle protection manually if you need to:
159
+
160
+ ```python
161
+ import secretshield
162
+
163
+ secretshield.disable()
164
+ secretshield.enable() # idempotent, safe to call repeatedly
165
+ secretshield.is_enabled()
166
+ ```
167
+
168
+ Or use detection/redaction directly, without touching stdout at all:
169
+
170
+ ```python
171
+ from secretshield import detect, redact
172
+
173
+ detect("aws_key=AKIAABCDEFGHIJKLMNOP")
174
+ # [Match(start=8, end=28, value='AKIA...', kind='aws_access_key_id')]
175
+
176
+ redact("aws_key=AKIAABCDEFGHIJKLMNOP")
177
+ # ("aws_key=********", True)
178
+ ```
179
+
180
+ ## CLI reference
181
+
182
+ ### `secretshield init` — set a project up in one step
183
+
184
+ ```bash
185
+ secretshield init
186
+ ```
187
+
188
+ Detects your project, then interactively offers to create a config
189
+ file, install the Git hook, and generate the GitHub Actions workflow —
190
+ all in one pass instead of discovering each command separately.
191
+
192
+ ### `secretshield scan` — find hardcoded secrets
193
+
194
+ ```bash
195
+ secretshield scan . # scan a directory
196
+ secretshield scan app.py # scan a single file
197
+ secretshield scan . --json # machine-readable, CI-safe
198
+ secretshield scan . --fix # interactively move secrets to .env
199
+ secretshield scan --staged # would this commit introduce a secret?
200
+ secretshield scan --diff HEAD~1 # did my changes introduce a secret?
201
+ secretshield scan . --baseline # adopt SecretShield without fixing everything today
202
+ ```
203
+
204
+ Scans Python, JavaScript/TypeScript, HTML, CSS, Vue, Svelte, JSON,
205
+ YAML, TOML/INI, `.env` files, shell scripts, and more — treating each
206
+ as text and running the same detection engine regardless of language.
207
+ Automatically skips `.git/`, `node_modules/`, `.venv/`, binary files,
208
+ and obvious documentation placeholders like `your_api_key_here`.
209
+
210
+ ```text
211
+ SecretShield scan
212
+
213
+ ✗ src/app.js:82
214
+ Potential secret: Bearer token
215
+ Type: token
216
+
217
+ ✓ 143 files scanned
218
+ ✗ 1 potential secret(s) found
219
+
220
+ Exit code: 1
221
+ ```
222
+
223
+ ### `secretshield run` — protect a script without editing it
224
+
225
+ ```bash
226
+ secretshield run app.py
227
+ ```
228
+
229
+ ### `secretshield install-hook` / `uninstall-hook` — stop secrets before they're committed
230
+
231
+ ```bash
232
+ secretshield install-hook
233
+ ```
234
+
235
+ Scans **staged content** (not your whole working tree) before every
236
+ commit and blocks it if something looks like a secret. Never destroys
237
+ an existing pre-commit hook — backs it up and wraps it instead.
238
+
239
+ ### `secretshield github-action` — catch what slips past locally
240
+
241
+ ```bash
242
+ secretshield github-action
243
+ ```
244
+
245
+ Generates `.github/workflows/secretshield.yml`, scanning every push and
246
+ pull request automatically.
247
+
248
+ ## Configuration file
249
+
250
+ Project-wide scan settings live in `secretshield.toml` (generate one
251
+ with `secretshield init`):
252
+
253
+ ```toml
254
+ [scan]
255
+ entropy_threshold = 4.2
256
+
257
+ [scan.ignore]
258
+ paths = ["tests/fixtures/", "docs/examples/"]
259
+
260
+ [scan.include]
261
+ patterns = ["*.py", "*.js"]
262
+
263
+ [output]
264
+ format = "text"
265
+ ```
266
+
267
+ CLI flags always override the file.
268
+
269
+ ## Runtime configuration
270
+
271
+ ```python
272
+ import secretshield
273
+
274
+ secretshield.configure(
275
+ enabled=True, # master on/off switch
276
+ redact_with="********", # placeholder used in place of a secret
277
+ entropy_threshold=4.2, # bits/char threshold for generic detection
278
+ notify=True, # print the "potential secret" warning
279
+ )
280
+ ```
281
+
282
+ ## Detection methods
283
+
284
+ SecretShield combines two strategies:
285
+
286
+ 1. **Known-format pattern matching** — AWS keys, GitHub tokens,
287
+ OpenAI-style keys, Slack tokens, Stripe keys, Google API keys, JWTs,
288
+ bearer tokens, PEM private-key blocks, and labeled generic secrets
289
+ (`password =`, `api_key:`, etc.)
290
+ 2. **High-entropy detection** — catches random-looking secrets that
291
+ don't match a known format, used as a conservative supplement (not
292
+ the primary mechanism) to keep false positives low.
293
+
294
+ ## Architecture
295
+
296
+ ```text
297
+ secretshield/
298
+ ├── patterns.py, detector.py, redactor.py # detection & redaction engine
299
+ ├── guardian.py # stdout/stderr + logging protection
300
+ ├── config.py, notifications.py # runtime settings & safe warnings
301
+ ├── project_config.py, baseline.py # secretshield.toml, --baseline
302
+ ├── cli.py # command-line interface
303
+ ├── autofix/ # interactive scan --fix
304
+ ├── git/ # pre-commit hook
305
+ └── github/ # Actions workflow generation
306
+ ```
307
+
308
+ ## Testing
309
+
310
+ ```bash
311
+ pip install -e ".[dev]"
312
+ pytest
313
+ ```
314
+
315
+ 176+ tests covering detection, redaction, runtime protection, static
316
+ scanning across languages, Auto-Fix, Git hooks, and CI integration. All
317
+ secrets used in tests and examples are fake.
318
+
319
+ ## Limitations
320
+
321
+ Be honest about what this is and isn't:
322
+
323
+ - Runtime protection covers **this Python process's** `stdout`,
324
+ `stderr`, and `logging` — not screenshots, clipboard, arbitrary file
325
+ writes, other applications, or network traffic.
326
+ - **Auto-Fix (`--fix`)** only rewrites Python, and only unambiguous
327
+ simple assignments (checked via Python's own `ast` module, not a
328
+ regex). Anything less certain is reported but left untouched.
329
+ - The pre-commit hook needs `secretshield` resolvable on `PATH` at
330
+ commit time — keep your virtual environment active.
331
+
332
+ Treat SecretShield as a strong defense-in-depth safety net, not a
333
+ replacement for proper secret management (vaults, least-privilege
334
+ credentials, secret scanning in CI, etc.).
335
+
336
+ ## Security considerations
337
+
338
+ No network calls. No telemetry. Nothing sent anywhere — detection and
339
+ redaction happen entirely locally, in-process.
340
+
341
+ ## Contributing
342
+
343
+ Issues and PRs welcome. Please add tests for new detection patterns or
344
+ behavior changes, use only fake credentials in tests/examples, and run
345
+ `pytest` before opening a PR.
346
+
347
+ ## [☕](https://github.com/sponsors/Sam3360/) Get me a coffee
348
+
349
+ If you find this project useful, consider [supporting its development through GitHub Sponsors](https://github.com/sponsors/Sam3360/).
350
+
351
+ ## License
352
+
353
+ MIT — see [LICENSE](LICENSE).
@@ -0,0 +1,327 @@
1
+ <div align="center">
2
+
3
+ # 🛡️ SecretShield
4
+
5
+ **Your secrets shouldn't end up in your terminal, your logs, or your commit history.**
6
+ **SecretShield makes sure they don't — automatically.**
7
+
8
+ [![PyPI version](https://img.shields.io/pypi/v/secretshield?color=blue)](https://pypi.org/project/secretshield/)
9
+ [![Python versions](https://img.shields.io/pypi/pyversions/secretshield)](https://pypi.org/project/secretshield/)
10
+ [![PyPI downloads](https://img.shields.io/pypi/dm/secretshield)](https://pypi.org/project/secretshield/)
11
+ [![License: MIT](https://img.shields.io/pypi/l/secretshield)](LICENSE)
12
+
13
+ [Install](#installation) · [Demo](#demo) · [Quick start](#quick-start) · [Features](#what-secretshield-does) · [Docs below](#cli-reference)
14
+
15
+ </div>
16
+
17
+ ---
18
+
19
+ ## The problem
20
+
21
+ You've done this. Everyone has.
22
+
23
+ ```python
24
+ print("API key:", api_key) # ...now it's in your terminal history
25
+ logger.info("Token: %s", token) # ...now it's in your log files
26
+ API_KEY = "sk-live-abc123..." # ...now it's about to get committed
27
+ ```
28
+
29
+ One `print()` left in from debugging. One log line that dumps a config
30
+ dict. One hardcoded key that slips past code review. That's usually all
31
+ it takes.
32
+
33
+ ## The fix
34
+
35
+ ```bash
36
+ pip install secretshield
37
+ ```
38
+
39
+ ```python
40
+ import secretshield
41
+
42
+ api_key = "sk-example1234567890abcdefFAKEKEY"
43
+ print("API key:", api_key)
44
+ ```
45
+
46
+ ```text
47
+ API key: ********
48
+ ⚠ secretshield: Potential secret detected and redacted.
49
+ ```
50
+
51
+ **No configuration. No code changes. Just `pip install` and `import`.**
52
+ The moment you import it, your terminal output, your logs — protected.
53
+
54
+ ## Demo
55
+
56
+ See SecretShield in action:
57
+
58
+ [![SecretShield Demo](https://img.youtube.com/vi/g95lNIhWsXM/maxresdefault.jpg)](https://youtu.be/g95lNIhWsXM)
59
+
60
+ **[▶ Watch the full demo on YouTube](https://youtu.be/g95lNIhWsXM)**
61
+
62
+ ## Quick start
63
+
64
+ ```bash
65
+ pip install secretshield
66
+ ```
67
+
68
+ Protect a running script:
69
+ ```python
70
+ import secretshield # that's it — stdout, stderr, and logging are now protected
71
+ ```
72
+
73
+ Scan an entire project for hardcoded secrets:
74
+ ```bash
75
+ secretshield scan .
76
+ ```
77
+
78
+ Set a whole project up in one step (config file + Git hook + CI):
79
+ ```bash
80
+ secretshield init
81
+ ```
82
+
83
+ ## What SecretShield does
84
+
85
+ SecretShield isn't just one trick — it's five layers that cover the
86
+ whole path a secret takes from your keyboard to a place you can't take
87
+ it back from:
88
+
89
+ | | |
90
+ |---|---|
91
+ | 🖥️ **Runtime protection** | Automatically redacts secrets from `stdout`, `stderr`, and `logging` the instant you `import secretshield` |
92
+ | 🔍 **Static scanning** | `secretshield scan .` finds hardcoded secrets across Python, JS/TS, HTML, YAML, `.env`, and more |
93
+ | 🔧 **Auto-Fix** | `scan . --fix` interactively moves a hardcoded secret into `.env` and rewrites your code to use it — safely, and only when it's unambiguous |
94
+ | 🪝 **Git pre-commit hook** | `install-hook` blocks a commit before a secret ever reaches your repo's history |
95
+ | ⚙️ **GitHub Actions** | `github-action` generates a workflow that scans every push and PR automatically |
96
+
97
+ All of it: **zero required dependencies, no telemetry, no network calls, nothing sent anywhere.** Everything happens locally, in your own process.
98
+
99
+ ## Why star this repo
100
+
101
+ If SecretShield has ever caught something before it hit your terminal
102
+ or your Git history — that's the whole point of the project working.
103
+ Starring it costs nothing and helps the next developer who's about to
104
+ `print()` an API key by accident actually find this before it's too
105
+ late.
106
+
107
+ ---
108
+
109
+ ## Installation
110
+
111
+ ```bash
112
+ pip install secretshield
113
+ ```
114
+
115
+ Requires Python 3.10+. No required third-party runtime dependencies
116
+ (a tiny `tomli` backport is pulled in automatically, but only on Python 3.10).
117
+
118
+ ## Basic usage
119
+
120
+ ```python
121
+ import secretshield
122
+
123
+ password = "hunter2-example-not-real"
124
+ print("Using password:", password)
125
+ ```
126
+
127
+ ```text
128
+ Using password: ********
129
+ ⚠ secretshield: Potential secret detected and redacted.
130
+ ```
131
+
132
+ Toggle protection manually if you need to:
133
+
134
+ ```python
135
+ import secretshield
136
+
137
+ secretshield.disable()
138
+ secretshield.enable() # idempotent, safe to call repeatedly
139
+ secretshield.is_enabled()
140
+ ```
141
+
142
+ Or use detection/redaction directly, without touching stdout at all:
143
+
144
+ ```python
145
+ from secretshield import detect, redact
146
+
147
+ detect("aws_key=AKIAABCDEFGHIJKLMNOP")
148
+ # [Match(start=8, end=28, value='AKIA...', kind='aws_access_key_id')]
149
+
150
+ redact("aws_key=AKIAABCDEFGHIJKLMNOP")
151
+ # ("aws_key=********", True)
152
+ ```
153
+
154
+ ## CLI reference
155
+
156
+ ### `secretshield init` — set a project up in one step
157
+
158
+ ```bash
159
+ secretshield init
160
+ ```
161
+
162
+ Detects your project, then interactively offers to create a config
163
+ file, install the Git hook, and generate the GitHub Actions workflow —
164
+ all in one pass instead of discovering each command separately.
165
+
166
+ ### `secretshield scan` — find hardcoded secrets
167
+
168
+ ```bash
169
+ secretshield scan . # scan a directory
170
+ secretshield scan app.py # scan a single file
171
+ secretshield scan . --json # machine-readable, CI-safe
172
+ secretshield scan . --fix # interactively move secrets to .env
173
+ secretshield scan --staged # would this commit introduce a secret?
174
+ secretshield scan --diff HEAD~1 # did my changes introduce a secret?
175
+ secretshield scan . --baseline # adopt SecretShield without fixing everything today
176
+ ```
177
+
178
+ Scans Python, JavaScript/TypeScript, HTML, CSS, Vue, Svelte, JSON,
179
+ YAML, TOML/INI, `.env` files, shell scripts, and more — treating each
180
+ as text and running the same detection engine regardless of language.
181
+ Automatically skips `.git/`, `node_modules/`, `.venv/`, binary files,
182
+ and obvious documentation placeholders like `your_api_key_here`.
183
+
184
+ ```text
185
+ SecretShield scan
186
+
187
+ ✗ src/app.js:82
188
+ Potential secret: Bearer token
189
+ Type: token
190
+
191
+ ✓ 143 files scanned
192
+ ✗ 1 potential secret(s) found
193
+
194
+ Exit code: 1
195
+ ```
196
+
197
+ ### `secretshield run` — protect a script without editing it
198
+
199
+ ```bash
200
+ secretshield run app.py
201
+ ```
202
+
203
+ ### `secretshield install-hook` / `uninstall-hook` — stop secrets before they're committed
204
+
205
+ ```bash
206
+ secretshield install-hook
207
+ ```
208
+
209
+ Scans **staged content** (not your whole working tree) before every
210
+ commit and blocks it if something looks like a secret. Never destroys
211
+ an existing pre-commit hook — backs it up and wraps it instead.
212
+
213
+ ### `secretshield github-action` — catch what slips past locally
214
+
215
+ ```bash
216
+ secretshield github-action
217
+ ```
218
+
219
+ Generates `.github/workflows/secretshield.yml`, scanning every push and
220
+ pull request automatically.
221
+
222
+ ## Configuration file
223
+
224
+ Project-wide scan settings live in `secretshield.toml` (generate one
225
+ with `secretshield init`):
226
+
227
+ ```toml
228
+ [scan]
229
+ entropy_threshold = 4.2
230
+
231
+ [scan.ignore]
232
+ paths = ["tests/fixtures/", "docs/examples/"]
233
+
234
+ [scan.include]
235
+ patterns = ["*.py", "*.js"]
236
+
237
+ [output]
238
+ format = "text"
239
+ ```
240
+
241
+ CLI flags always override the file.
242
+
243
+ ## Runtime configuration
244
+
245
+ ```python
246
+ import secretshield
247
+
248
+ secretshield.configure(
249
+ enabled=True, # master on/off switch
250
+ redact_with="********", # placeholder used in place of a secret
251
+ entropy_threshold=4.2, # bits/char threshold for generic detection
252
+ notify=True, # print the "potential secret" warning
253
+ )
254
+ ```
255
+
256
+ ## Detection methods
257
+
258
+ SecretShield combines two strategies:
259
+
260
+ 1. **Known-format pattern matching** — AWS keys, GitHub tokens,
261
+ OpenAI-style keys, Slack tokens, Stripe keys, Google API keys, JWTs,
262
+ bearer tokens, PEM private-key blocks, and labeled generic secrets
263
+ (`password =`, `api_key:`, etc.)
264
+ 2. **High-entropy detection** — catches random-looking secrets that
265
+ don't match a known format, used as a conservative supplement (not
266
+ the primary mechanism) to keep false positives low.
267
+
268
+ ## Architecture
269
+
270
+ ```text
271
+ secretshield/
272
+ ├── patterns.py, detector.py, redactor.py # detection & redaction engine
273
+ ├── guardian.py # stdout/stderr + logging protection
274
+ ├── config.py, notifications.py # runtime settings & safe warnings
275
+ ├── project_config.py, baseline.py # secretshield.toml, --baseline
276
+ ├── cli.py # command-line interface
277
+ ├── autofix/ # interactive scan --fix
278
+ ├── git/ # pre-commit hook
279
+ └── github/ # Actions workflow generation
280
+ ```
281
+
282
+ ## Testing
283
+
284
+ ```bash
285
+ pip install -e ".[dev]"
286
+ pytest
287
+ ```
288
+
289
+ 176+ tests covering detection, redaction, runtime protection, static
290
+ scanning across languages, Auto-Fix, Git hooks, and CI integration. All
291
+ secrets used in tests and examples are fake.
292
+
293
+ ## Limitations
294
+
295
+ Be honest about what this is and isn't:
296
+
297
+ - Runtime protection covers **this Python process's** `stdout`,
298
+ `stderr`, and `logging` — not screenshots, clipboard, arbitrary file
299
+ writes, other applications, or network traffic.
300
+ - **Auto-Fix (`--fix`)** only rewrites Python, and only unambiguous
301
+ simple assignments (checked via Python's own `ast` module, not a
302
+ regex). Anything less certain is reported but left untouched.
303
+ - The pre-commit hook needs `secretshield` resolvable on `PATH` at
304
+ commit time — keep your virtual environment active.
305
+
306
+ Treat SecretShield as a strong defense-in-depth safety net, not a
307
+ replacement for proper secret management (vaults, least-privilege
308
+ credentials, secret scanning in CI, etc.).
309
+
310
+ ## Security considerations
311
+
312
+ No network calls. No telemetry. Nothing sent anywhere — detection and
313
+ redaction happen entirely locally, in-process.
314
+
315
+ ## Contributing
316
+
317
+ Issues and PRs welcome. Please add tests for new detection patterns or
318
+ behavior changes, use only fake credentials in tests/examples, and run
319
+ `pytest` before opening a PR.
320
+
321
+ ## [☕](https://github.com/sponsors/Sam3360/) Get me a coffee
322
+
323
+ If you find this project useful, consider [supporting its development through GitHub Sponsors](https://github.com/sponsors/Sam3360/).
324
+
325
+ ## License
326
+
327
+ MIT — see [LICENSE](LICENSE).
@@ -4,8 +4,8 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "secretshield"
7
- version = "0.3.2"
8
- description = "Detect and redact likely secrets before they reach Python's terminal output or logging system."
7
+ version = "0.4.1"
8
+ description = "Detect, redact, and prevent secret exposure in Python apps, source code, and Git commits — runtime protection, multi-language scanning, auto-fix, and CI integration in one tool."
9
9
  readme = "README.md"
10
10
  license = "MIT"
11
11
  requires-python = ">=3.10"
@@ -23,7 +23,9 @@ classifiers = [
23
23
  "Topic :: Security",
24
24
  "Topic :: Software Development :: Libraries :: Python Modules",
25
25
  ]
26
- dependencies = []
26
+ dependencies = [
27
+ "tomli>=2.0; python_version < \"3.11\"",
28
+ ]
27
29
 
28
30
  [project.optional-dependencies]
29
31
  dev = [