gitrupt 0.1.0__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.
- gitrupt-0.1.0/LICENSE +23 -0
- gitrupt-0.1.0/PKG-INFO +342 -0
- gitrupt-0.1.0/README.md +279 -0
- gitrupt-0.1.0/pyproject.toml +76 -0
- gitrupt-0.1.0/setup.cfg +4 -0
- gitrupt-0.1.0/src/gitrupt/__init__.py +13 -0
- gitrupt-0.1.0/src/gitrupt/cli.py +546 -0
- gitrupt-0.1.0/src/gitrupt/config.py +269 -0
- gitrupt-0.1.0/src/gitrupt/git.py +590 -0
- gitrupt-0.1.0/src/gitrupt/hooks/__init__.py +7 -0
- gitrupt-0.1.0/src/gitrupt/hooks/install.py +255 -0
- gitrupt-0.1.0/src/gitrupt/hooks/pre_commit.py +103 -0
- gitrupt-0.1.0/src/gitrupt/hooks/pre_push.py +178 -0
- gitrupt-0.1.0/src/gitrupt/models.py +190 -0
- gitrupt-0.1.0/src/gitrupt/policy.py +36 -0
- gitrupt-0.1.0/src/gitrupt/reporting.py +316 -0
- gitrupt-0.1.0/src/gitrupt/risk.py +197 -0
- gitrupt-0.1.0/src/gitrupt/scanner.py +117 -0
- gitrupt-0.1.0/src/gitrupt/scanners/__init__.py +17 -0
- gitrupt-0.1.0/src/gitrupt/scanners/adapters.py +166 -0
- gitrupt-0.1.0/src/gitrupt/scanners/base.py +113 -0
- gitrupt-0.1.0/src/gitrupt/scanners/binaries.py +185 -0
- gitrupt-0.1.0/src/gitrupt/scanners/code_rules/__init__.py +36 -0
- gitrupt-0.1.0/src/gitrupt/scanners/code_rules/base.py +27 -0
- gitrupt-0.1.0/src/gitrupt/scanners/code_rules/go.py +65 -0
- gitrupt-0.1.0/src/gitrupt/scanners/code_rules/javascript.py +106 -0
- gitrupt-0.1.0/src/gitrupt/scanners/code_rules/php.py +71 -0
- gitrupt-0.1.0/src/gitrupt/scanners/code_rules/powershell.py +85 -0
- gitrupt-0.1.0/src/gitrupt/scanners/code_rules/python.py +153 -0
- gitrupt-0.1.0/src/gitrupt/scanners/code_rules/ruby.py +76 -0
- gitrupt-0.1.0/src/gitrupt/scanners/code_rules/rust.py +41 -0
- gitrupt-0.1.0/src/gitrupt/scanners/code_rules/shell.py +112 -0
- gitrupt-0.1.0/src/gitrupt/scanners/dependencies.py +244 -0
- gitrupt-0.1.0/src/gitrupt/scanners/ecosystems/__init__.py +30 -0
- gitrupt-0.1.0/src/gitrupt/scanners/ecosystems/base.py +60 -0
- gitrupt-0.1.0/src/gitrupt/scanners/ecosystems/node.py +128 -0
- gitrupt-0.1.0/src/gitrupt/scanners/ecosystems/python.py +157 -0
- gitrupt-0.1.0/src/gitrupt/scanners/entropy.py +123 -0
- gitrupt-0.1.0/src/gitrupt/scanners/forbidden_files.py +201 -0
- gitrupt-0.1.0/src/gitrupt/scanners/malware.py +219 -0
- gitrupt-0.1.0/src/gitrupt/scanners/osv_client.py +221 -0
- gitrupt-0.1.0/src/gitrupt/scanners/registry.py +66 -0
- gitrupt-0.1.0/src/gitrupt/scanners/secret_rules.py +368 -0
- gitrupt-0.1.0/src/gitrupt/scanners/secrets.py +558 -0
- gitrupt-0.1.0/src/gitrupt/scanners/suspicious_code.py +208 -0
- gitrupt-0.1.0/src/gitrupt/scanners/yara_loader.py +65 -0
- gitrupt-0.1.0/src/gitrupt/scanners/yara_rules_builtin.py +141 -0
- gitrupt-0.1.0/src/gitrupt.egg-info/PKG-INFO +342 -0
- gitrupt-0.1.0/src/gitrupt.egg-info/SOURCES.txt +51 -0
- gitrupt-0.1.0/src/gitrupt.egg-info/dependency_links.txt +1 -0
- gitrupt-0.1.0/src/gitrupt.egg-info/entry_points.txt +2 -0
- gitrupt-0.1.0/src/gitrupt.egg-info/requires.txt +18 -0
- gitrupt-0.1.0/src/gitrupt.egg-info/top_level.txt +1 -0
gitrupt-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Gitrupt is released under the MIT License.
|
|
4
|
+
|
|
5
|
+
Copyright (c) 2026 Gitrupt Contributors
|
|
6
|
+
|
|
7
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
8
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
9
|
+
in the Software without restriction, including without limitation the rights
|
|
10
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
11
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
12
|
+
furnished to do so, subject to the following conditions:
|
|
13
|
+
|
|
14
|
+
The above copyright notice and this permission notice shall be included in all
|
|
15
|
+
copies or substantial portions of the Software.
|
|
16
|
+
|
|
17
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
18
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
19
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
20
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
21
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
22
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
23
|
+
SOFTWARE.
|
gitrupt-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,342 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: gitrupt
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: A local Git security firewall for secrets, suspicious code, malware heuristics, and dependency vulnerability checks
|
|
5
|
+
License: MIT License
|
|
6
|
+
|
|
7
|
+
Gitrupt is released under the MIT License.
|
|
8
|
+
|
|
9
|
+
Copyright (c) 2026 Gitrupt Contributors
|
|
10
|
+
|
|
11
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
12
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
13
|
+
in the Software without restriction, including without limitation the rights
|
|
14
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
15
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
16
|
+
furnished to do so, subject to the following conditions:
|
|
17
|
+
|
|
18
|
+
The above copyright notice and this permission notice shall be included in all
|
|
19
|
+
copies or substantial portions of the Software.
|
|
20
|
+
|
|
21
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
22
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
23
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
24
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
25
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
26
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
27
|
+
SOFTWARE.
|
|
28
|
+
|
|
29
|
+
Project-URL: Homepage, https://github.com/gitrupt/gitrupt
|
|
30
|
+
Project-URL: Repository, https://github.com/gitrupt/gitrupt
|
|
31
|
+
Project-URL: Issues, https://github.com/gitrupt/gitrupt/issues
|
|
32
|
+
Project-URL: Documentation, https://github.com/gitrupt/gitrupt/blob/main/docs/architecture.md
|
|
33
|
+
Keywords: git,security,secrets,pre-commit,pre-push,malware,suspicious-code,dependency-scanning,firewall
|
|
34
|
+
Classifier: Development Status :: 3 - Alpha
|
|
35
|
+
Classifier: Environment :: Console
|
|
36
|
+
Classifier: Intended Audience :: Developers
|
|
37
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
38
|
+
Classifier: Operating System :: OS Independent
|
|
39
|
+
Classifier: Programming Language :: Python :: 3
|
|
40
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
41
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
42
|
+
Classifier: Topic :: Security
|
|
43
|
+
Classifier: Topic :: Software Development :: Version Control :: Git
|
|
44
|
+
Requires-Python: >=3.11
|
|
45
|
+
Description-Content-Type: text/markdown
|
|
46
|
+
License-File: LICENSE
|
|
47
|
+
Requires-Dist: typer>=0.12.0
|
|
48
|
+
Requires-Dist: pydantic>=2.0.0
|
|
49
|
+
Requires-Dist: pyyaml>=6.0
|
|
50
|
+
Requires-Dist: rich>=13.0.0
|
|
51
|
+
Provides-Extra: malware
|
|
52
|
+
Requires-Dist: yara-python>=4.3.0; extra == "malware"
|
|
53
|
+
Provides-Extra: all
|
|
54
|
+
Requires-Dist: yara-python>=4.3.0; extra == "all"
|
|
55
|
+
Provides-Extra: dev
|
|
56
|
+
Requires-Dist: pytest>=7.4.0; extra == "dev"
|
|
57
|
+
Requires-Dist: pytest-cov>=4.1.0; extra == "dev"
|
|
58
|
+
Requires-Dist: ruff>=0.1.0; extra == "dev"
|
|
59
|
+
Requires-Dist: mypy>=1.5.0; extra == "dev"
|
|
60
|
+
Requires-Dist: types-PyYAML>=6.0; extra == "dev"
|
|
61
|
+
Requires-Dist: yara-python>=4.3.0; extra == "dev"
|
|
62
|
+
Dynamic: license-file
|
|
63
|
+
|
|
64
|
+
# Gitrupt 🛡️
|
|
65
|
+
|
|
66
|
+
Gitrupt is a local Git security firewall that protects repositories from secrets, suspicious code, malware-style binaries, and vulnerable dependencies before they reach a commit or push.
|
|
67
|
+
|
|
68
|
+
It runs at the Git hook boundary and evaluates staged or outgoing content against a policy you control in a repository-level `.gitrupt.yml` file.
|
|
69
|
+
|
|
70
|
+
---
|
|
71
|
+
|
|
72
|
+
## Features
|
|
73
|
+
|
|
74
|
+
- 🔒 **Forbidden file blocking** — `.env`, `.env.*`, `*.pem`, `*.key`, `credentials.json`, and more
|
|
75
|
+
- 🔑 **Secret detection** — AWS keys, GitHub tokens, private keys, API keys, database URLs, JWTs, and more
|
|
76
|
+
- 📊 **Entropy-based detection** — calibrated Shannon entropy checks for likely secret material
|
|
77
|
+
- 🧠 **Suspicious code heuristics** — flags dangerous patterns in added lines across common languages
|
|
78
|
+
- 🦠 **Native malware checks** — EICAR signatures, binary heuristics, packer markers, and optional YARA matching
|
|
79
|
+
- 📦 **Dependency scanning** — OSV-backed vulnerability checks for Python and Node manifests when enabled
|
|
80
|
+
- 🪝 **Hook coverage** — pre-commit is installed by default; pre-push is available as an optional extra layer
|
|
81
|
+
- 🔐 **Local-first privacy** — default execution stays on the machine; networked checks are opt-in
|
|
82
|
+
|
|
83
|
+
---
|
|
84
|
+
|
|
85
|
+
## Quick Start
|
|
86
|
+
|
|
87
|
+
```bash
|
|
88
|
+
pip install gitrupt
|
|
89
|
+
|
|
90
|
+
cd your-repository
|
|
91
|
+
gitrupt init
|
|
92
|
+
|
|
93
|
+
# Protect staged commits
|
|
94
|
+
git commit -m "feat: my change"
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
Optional push-time protection:
|
|
98
|
+
|
|
99
|
+
```bash
|
|
100
|
+
gitrupt init --with-push
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
---
|
|
104
|
+
|
|
105
|
+
## Installation
|
|
106
|
+
|
|
107
|
+
Requires Python 3.11+ and Git.
|
|
108
|
+
|
|
109
|
+
```bash
|
|
110
|
+
pip install gitrupt
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
---
|
|
114
|
+
|
|
115
|
+
## Usage
|
|
116
|
+
|
|
117
|
+
### Initialize protection
|
|
118
|
+
|
|
119
|
+
```bash
|
|
120
|
+
gitrupt init
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
Installs the Gitrupt pre-commit hook in the current Git repository.
|
|
124
|
+
|
|
125
|
+
### Install push firewall
|
|
126
|
+
|
|
127
|
+
```bash
|
|
128
|
+
gitrupt init --with-push
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
Adds a pre-push hook that scans outgoing commits before they leave the machine.
|
|
132
|
+
|
|
133
|
+
### Check status
|
|
134
|
+
|
|
135
|
+
```bash
|
|
136
|
+
gitrupt status
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
Shows whether Gitrupt is installed and active.
|
|
140
|
+
|
|
141
|
+
### Manual scan
|
|
142
|
+
|
|
143
|
+
```bash
|
|
144
|
+
gitrupt scan --staged # scan staged changes (pre-commit behavior)
|
|
145
|
+
gitrupt scan --push # scan outgoing commits (pre-push behavior)
|
|
146
|
+
gitrupt scan # scan the working tree
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
### Show configuration
|
|
150
|
+
|
|
151
|
+
```bash
|
|
152
|
+
gitrupt config
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
### Remove protection
|
|
156
|
+
|
|
157
|
+
```bash
|
|
158
|
+
gitrupt uninstall
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
---
|
|
162
|
+
|
|
163
|
+
## Configuration
|
|
164
|
+
|
|
165
|
+
Gitrupt reads a repository-level `.gitrupt.yml` file. The current schema supports the scanner toggles, denial rules, allowlists, entropy tuning, suspicious-code tuning, malware settings, dependency settings, and policy overrides.
|
|
166
|
+
|
|
167
|
+
```yaml
|
|
168
|
+
version: 1
|
|
169
|
+
mode: strict
|
|
170
|
+
|
|
171
|
+
scan:
|
|
172
|
+
secrets: true
|
|
173
|
+
threats: true
|
|
174
|
+
suspicious_code: false
|
|
175
|
+
dependencies: false
|
|
176
|
+
|
|
177
|
+
rules:
|
|
178
|
+
forbidden_paths:
|
|
179
|
+
- ".env"
|
|
180
|
+
- ".env.*"
|
|
181
|
+
- "*.pem"
|
|
182
|
+
- "*.key"
|
|
183
|
+
- "*.p12"
|
|
184
|
+
- "*.pfx"
|
|
185
|
+
- "credentials.json"
|
|
186
|
+
- "service-account.json"
|
|
187
|
+
- "*.secret"
|
|
188
|
+
forbidden_extensions:
|
|
189
|
+
- ".scr"
|
|
190
|
+
- ".exe"
|
|
191
|
+
max_file_size_mb: 50.0
|
|
192
|
+
|
|
193
|
+
allow:
|
|
194
|
+
paths:
|
|
195
|
+
- ".env.example"
|
|
196
|
+
- "tests/fixtures/**"
|
|
197
|
+
- "docs/**"
|
|
198
|
+
|
|
199
|
+
suppressions:
|
|
200
|
+
rules: []
|
|
201
|
+
files: []
|
|
202
|
+
paths: []
|
|
203
|
+
|
|
204
|
+
entropy:
|
|
205
|
+
enabled: true
|
|
206
|
+
threshold: 4.5
|
|
207
|
+
min_length: 20
|
|
208
|
+
|
|
209
|
+
suspicious_code:
|
|
210
|
+
min_confidence: 0.6
|
|
211
|
+
languages:
|
|
212
|
+
- python
|
|
213
|
+
- javascript
|
|
214
|
+
- shell
|
|
215
|
+
- powershell
|
|
216
|
+
- php
|
|
217
|
+
- ruby
|
|
218
|
+
- go
|
|
219
|
+
|
|
220
|
+
malware:
|
|
221
|
+
use_yara: true
|
|
222
|
+
max_file_size_mb: 50.0
|
|
223
|
+
custom_yara_dirs: []
|
|
224
|
+
|
|
225
|
+
dependencies:
|
|
226
|
+
ecosystems:
|
|
227
|
+
- python
|
|
228
|
+
- node
|
|
229
|
+
offline: false
|
|
230
|
+
timeout_seconds: 10.0
|
|
231
|
+
cache_ttl_hours: 24
|
|
232
|
+
|
|
233
|
+
policy:
|
|
234
|
+
low: allow
|
|
235
|
+
medium: warn
|
|
236
|
+
high: block
|
|
237
|
+
critical: block
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
Valid modes are `strict`, `permissive`, and `warn-only`.
|
|
241
|
+
|
|
242
|
+
---
|
|
243
|
+
|
|
244
|
+
## How It Works
|
|
245
|
+
|
|
246
|
+
```text
|
|
247
|
+
Developer
|
|
248
|
+
↓
|
|
249
|
+
Git commit / git push
|
|
250
|
+
↓
|
|
251
|
+
Git hook (pre-commit and optional pre-push)
|
|
252
|
+
↓
|
|
253
|
+
Gitrupt scanner pipeline
|
|
254
|
+
↓
|
|
255
|
+
Forbidden file checks + secret scans + entropy checks
|
|
256
|
+
↓
|
|
257
|
+
Suspicious code checks + malware heuristics + dependency OSV scans
|
|
258
|
+
↓
|
|
259
|
+
Risk engine + policy decision
|
|
260
|
+
↓
|
|
261
|
+
ALLOW / WARN / BLOCK
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
---
|
|
265
|
+
|
|
266
|
+
## Security Report Example
|
|
267
|
+
|
|
268
|
+
When a commit is blocked, Gitrupt reports the file, severity, detector, and guidance:
|
|
269
|
+
|
|
270
|
+
```text
|
|
271
|
+
🛡️ Gitrupt
|
|
272
|
+
|
|
273
|
+
COMMIT BLOCKED
|
|
274
|
+
|
|
275
|
+
CRITICAL .env
|
|
276
|
+
Environment file is prohibited.
|
|
277
|
+
Remove this file from staging: git restore --staged .env
|
|
278
|
+
|
|
279
|
+
HIGH backend/config.py:18
|
|
280
|
+
Possible AWS credential detected.
|
|
281
|
+
Move credentials to environment variables.
|
|
282
|
+
|
|
283
|
+
Fix the findings above and try again.
|
|
284
|
+
To override (not recommended): git commit --no-verify
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
---
|
|
288
|
+
|
|
289
|
+
## Hook Safety
|
|
290
|
+
|
|
291
|
+
Gitrupt never silently destroys existing Git hooks.
|
|
292
|
+
|
|
293
|
+
If a hook already exists, Gitrupt preserves it and wraps it so your original behavior still runs after Gitrupt completes.
|
|
294
|
+
|
|
295
|
+
---
|
|
296
|
+
|
|
297
|
+
## Privacy
|
|
298
|
+
|
|
299
|
+
By default, Gitrupt runs locally. Repository content stays on the machine unless you explicitly enable networked checks.
|
|
300
|
+
|
|
301
|
+
- Native scanning runs locally
|
|
302
|
+
- Dependency OSV queries are only used when the dependency scanner is enabled and `offline` is `false`
|
|
303
|
+
- Third-party adapters remain optional and are only used when configured
|
|
304
|
+
- Secret findings are redacted before reporting
|
|
305
|
+
|
|
306
|
+
---
|
|
307
|
+
|
|
308
|
+
## Limitations
|
|
309
|
+
|
|
310
|
+
Git allows bypassing client-side hooks:
|
|
311
|
+
|
|
312
|
+
```bash
|
|
313
|
+
git commit --no-verify
|
|
314
|
+
```
|
|
315
|
+
|
|
316
|
+
Gitrupt logs this but cannot prevent it at the client level alone. For organizational enforcement, use CI/CD controls and repository-level policy enforcement.
|
|
317
|
+
|
|
318
|
+
---
|
|
319
|
+
|
|
320
|
+
## Roadmap
|
|
321
|
+
|
|
322
|
+
Gitrupt continues to expand beyond the initial MVP scope with optional integrations and workflow hardening.
|
|
323
|
+
|
|
324
|
+
- Native suspicious-code detection
|
|
325
|
+
- Malware heuristics and YARA support
|
|
326
|
+
- Dependency vulnerability scanning with OSV
|
|
327
|
+
- Optional pre-push firewall protection
|
|
328
|
+
- Additional external adapters and reporting formats
|
|
329
|
+
|
|
330
|
+
---
|
|
331
|
+
|
|
332
|
+
## Contributing
|
|
333
|
+
|
|
334
|
+
See [CONTRIBUTING.md](CONTRIBUTING.md).
|
|
335
|
+
|
|
336
|
+
## Security
|
|
337
|
+
|
|
338
|
+
See [SECURITY.md](SECURITY.md) for vulnerability reporting.
|
|
339
|
+
|
|
340
|
+
## License
|
|
341
|
+
|
|
342
|
+
MIT License — see [LICENSE](LICENSE).
|
gitrupt-0.1.0/README.md
ADDED
|
@@ -0,0 +1,279 @@
|
|
|
1
|
+
# Gitrupt 🛡️
|
|
2
|
+
|
|
3
|
+
Gitrupt is a local Git security firewall that protects repositories from secrets, suspicious code, malware-style binaries, and vulnerable dependencies before they reach a commit or push.
|
|
4
|
+
|
|
5
|
+
It runs at the Git hook boundary and evaluates staged or outgoing content against a policy you control in a repository-level `.gitrupt.yml` file.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Features
|
|
10
|
+
|
|
11
|
+
- 🔒 **Forbidden file blocking** — `.env`, `.env.*`, `*.pem`, `*.key`, `credentials.json`, and more
|
|
12
|
+
- 🔑 **Secret detection** — AWS keys, GitHub tokens, private keys, API keys, database URLs, JWTs, and more
|
|
13
|
+
- 📊 **Entropy-based detection** — calibrated Shannon entropy checks for likely secret material
|
|
14
|
+
- 🧠 **Suspicious code heuristics** — flags dangerous patterns in added lines across common languages
|
|
15
|
+
- 🦠 **Native malware checks** — EICAR signatures, binary heuristics, packer markers, and optional YARA matching
|
|
16
|
+
- 📦 **Dependency scanning** — OSV-backed vulnerability checks for Python and Node manifests when enabled
|
|
17
|
+
- 🪝 **Hook coverage** — pre-commit is installed by default; pre-push is available as an optional extra layer
|
|
18
|
+
- 🔐 **Local-first privacy** — default execution stays on the machine; networked checks are opt-in
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
## Quick Start
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
pip install gitrupt
|
|
26
|
+
|
|
27
|
+
cd your-repository
|
|
28
|
+
gitrupt init
|
|
29
|
+
|
|
30
|
+
# Protect staged commits
|
|
31
|
+
git commit -m "feat: my change"
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
Optional push-time protection:
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
gitrupt init --with-push
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
---
|
|
41
|
+
|
|
42
|
+
## Installation
|
|
43
|
+
|
|
44
|
+
Requires Python 3.11+ and Git.
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
pip install gitrupt
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
---
|
|
51
|
+
|
|
52
|
+
## Usage
|
|
53
|
+
|
|
54
|
+
### Initialize protection
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
gitrupt init
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
Installs the Gitrupt pre-commit hook in the current Git repository.
|
|
61
|
+
|
|
62
|
+
### Install push firewall
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
gitrupt init --with-push
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
Adds a pre-push hook that scans outgoing commits before they leave the machine.
|
|
69
|
+
|
|
70
|
+
### Check status
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
gitrupt status
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
Shows whether Gitrupt is installed and active.
|
|
77
|
+
|
|
78
|
+
### Manual scan
|
|
79
|
+
|
|
80
|
+
```bash
|
|
81
|
+
gitrupt scan --staged # scan staged changes (pre-commit behavior)
|
|
82
|
+
gitrupt scan --push # scan outgoing commits (pre-push behavior)
|
|
83
|
+
gitrupt scan # scan the working tree
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
### Show configuration
|
|
87
|
+
|
|
88
|
+
```bash
|
|
89
|
+
gitrupt config
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
### Remove protection
|
|
93
|
+
|
|
94
|
+
```bash
|
|
95
|
+
gitrupt uninstall
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
---
|
|
99
|
+
|
|
100
|
+
## Configuration
|
|
101
|
+
|
|
102
|
+
Gitrupt reads a repository-level `.gitrupt.yml` file. The current schema supports the scanner toggles, denial rules, allowlists, entropy tuning, suspicious-code tuning, malware settings, dependency settings, and policy overrides.
|
|
103
|
+
|
|
104
|
+
```yaml
|
|
105
|
+
version: 1
|
|
106
|
+
mode: strict
|
|
107
|
+
|
|
108
|
+
scan:
|
|
109
|
+
secrets: true
|
|
110
|
+
threats: true
|
|
111
|
+
suspicious_code: false
|
|
112
|
+
dependencies: false
|
|
113
|
+
|
|
114
|
+
rules:
|
|
115
|
+
forbidden_paths:
|
|
116
|
+
- ".env"
|
|
117
|
+
- ".env.*"
|
|
118
|
+
- "*.pem"
|
|
119
|
+
- "*.key"
|
|
120
|
+
- "*.p12"
|
|
121
|
+
- "*.pfx"
|
|
122
|
+
- "credentials.json"
|
|
123
|
+
- "service-account.json"
|
|
124
|
+
- "*.secret"
|
|
125
|
+
forbidden_extensions:
|
|
126
|
+
- ".scr"
|
|
127
|
+
- ".exe"
|
|
128
|
+
max_file_size_mb: 50.0
|
|
129
|
+
|
|
130
|
+
allow:
|
|
131
|
+
paths:
|
|
132
|
+
- ".env.example"
|
|
133
|
+
- "tests/fixtures/**"
|
|
134
|
+
- "docs/**"
|
|
135
|
+
|
|
136
|
+
suppressions:
|
|
137
|
+
rules: []
|
|
138
|
+
files: []
|
|
139
|
+
paths: []
|
|
140
|
+
|
|
141
|
+
entropy:
|
|
142
|
+
enabled: true
|
|
143
|
+
threshold: 4.5
|
|
144
|
+
min_length: 20
|
|
145
|
+
|
|
146
|
+
suspicious_code:
|
|
147
|
+
min_confidence: 0.6
|
|
148
|
+
languages:
|
|
149
|
+
- python
|
|
150
|
+
- javascript
|
|
151
|
+
- shell
|
|
152
|
+
- powershell
|
|
153
|
+
- php
|
|
154
|
+
- ruby
|
|
155
|
+
- go
|
|
156
|
+
|
|
157
|
+
malware:
|
|
158
|
+
use_yara: true
|
|
159
|
+
max_file_size_mb: 50.0
|
|
160
|
+
custom_yara_dirs: []
|
|
161
|
+
|
|
162
|
+
dependencies:
|
|
163
|
+
ecosystems:
|
|
164
|
+
- python
|
|
165
|
+
- node
|
|
166
|
+
offline: false
|
|
167
|
+
timeout_seconds: 10.0
|
|
168
|
+
cache_ttl_hours: 24
|
|
169
|
+
|
|
170
|
+
policy:
|
|
171
|
+
low: allow
|
|
172
|
+
medium: warn
|
|
173
|
+
high: block
|
|
174
|
+
critical: block
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
Valid modes are `strict`, `permissive`, and `warn-only`.
|
|
178
|
+
|
|
179
|
+
---
|
|
180
|
+
|
|
181
|
+
## How It Works
|
|
182
|
+
|
|
183
|
+
```text
|
|
184
|
+
Developer
|
|
185
|
+
↓
|
|
186
|
+
Git commit / git push
|
|
187
|
+
↓
|
|
188
|
+
Git hook (pre-commit and optional pre-push)
|
|
189
|
+
↓
|
|
190
|
+
Gitrupt scanner pipeline
|
|
191
|
+
↓
|
|
192
|
+
Forbidden file checks + secret scans + entropy checks
|
|
193
|
+
↓
|
|
194
|
+
Suspicious code checks + malware heuristics + dependency OSV scans
|
|
195
|
+
↓
|
|
196
|
+
Risk engine + policy decision
|
|
197
|
+
↓
|
|
198
|
+
ALLOW / WARN / BLOCK
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
---
|
|
202
|
+
|
|
203
|
+
## Security Report Example
|
|
204
|
+
|
|
205
|
+
When a commit is blocked, Gitrupt reports the file, severity, detector, and guidance:
|
|
206
|
+
|
|
207
|
+
```text
|
|
208
|
+
🛡️ Gitrupt
|
|
209
|
+
|
|
210
|
+
COMMIT BLOCKED
|
|
211
|
+
|
|
212
|
+
CRITICAL .env
|
|
213
|
+
Environment file is prohibited.
|
|
214
|
+
Remove this file from staging: git restore --staged .env
|
|
215
|
+
|
|
216
|
+
HIGH backend/config.py:18
|
|
217
|
+
Possible AWS credential detected.
|
|
218
|
+
Move credentials to environment variables.
|
|
219
|
+
|
|
220
|
+
Fix the findings above and try again.
|
|
221
|
+
To override (not recommended): git commit --no-verify
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
---
|
|
225
|
+
|
|
226
|
+
## Hook Safety
|
|
227
|
+
|
|
228
|
+
Gitrupt never silently destroys existing Git hooks.
|
|
229
|
+
|
|
230
|
+
If a hook already exists, Gitrupt preserves it and wraps it so your original behavior still runs after Gitrupt completes.
|
|
231
|
+
|
|
232
|
+
---
|
|
233
|
+
|
|
234
|
+
## Privacy
|
|
235
|
+
|
|
236
|
+
By default, Gitrupt runs locally. Repository content stays on the machine unless you explicitly enable networked checks.
|
|
237
|
+
|
|
238
|
+
- Native scanning runs locally
|
|
239
|
+
- Dependency OSV queries are only used when the dependency scanner is enabled and `offline` is `false`
|
|
240
|
+
- Third-party adapters remain optional and are only used when configured
|
|
241
|
+
- Secret findings are redacted before reporting
|
|
242
|
+
|
|
243
|
+
---
|
|
244
|
+
|
|
245
|
+
## Limitations
|
|
246
|
+
|
|
247
|
+
Git allows bypassing client-side hooks:
|
|
248
|
+
|
|
249
|
+
```bash
|
|
250
|
+
git commit --no-verify
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
Gitrupt logs this but cannot prevent it at the client level alone. For organizational enforcement, use CI/CD controls and repository-level policy enforcement.
|
|
254
|
+
|
|
255
|
+
---
|
|
256
|
+
|
|
257
|
+
## Roadmap
|
|
258
|
+
|
|
259
|
+
Gitrupt continues to expand beyond the initial MVP scope with optional integrations and workflow hardening.
|
|
260
|
+
|
|
261
|
+
- Native suspicious-code detection
|
|
262
|
+
- Malware heuristics and YARA support
|
|
263
|
+
- Dependency vulnerability scanning with OSV
|
|
264
|
+
- Optional pre-push firewall protection
|
|
265
|
+
- Additional external adapters and reporting formats
|
|
266
|
+
|
|
267
|
+
---
|
|
268
|
+
|
|
269
|
+
## Contributing
|
|
270
|
+
|
|
271
|
+
See [CONTRIBUTING.md](CONTRIBUTING.md).
|
|
272
|
+
|
|
273
|
+
## Security
|
|
274
|
+
|
|
275
|
+
See [SECURITY.md](SECURITY.md) for vulnerability reporting.
|
|
276
|
+
|
|
277
|
+
## License
|
|
278
|
+
|
|
279
|
+
MIT License — see [LICENSE](LICENSE).
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=68", "wheel"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "gitrupt"
|
|
7
|
+
version = "0.1.0"
|
|
8
|
+
description = "A local Git security firewall for secrets, suspicious code, malware heuristics, and dependency vulnerability checks"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
license = { file = "LICENSE" }
|
|
11
|
+
requires-python = ">=3.11"
|
|
12
|
+
keywords = ["git", "security", "secrets", "pre-commit", "pre-push", "malware", "suspicious-code", "dependency-scanning", "firewall"]
|
|
13
|
+
classifiers = [
|
|
14
|
+
"Development Status :: 3 - Alpha",
|
|
15
|
+
"Environment :: Console",
|
|
16
|
+
"Intended Audience :: Developers",
|
|
17
|
+
"License :: OSI Approved :: MIT License",
|
|
18
|
+
"Operating System :: OS Independent",
|
|
19
|
+
"Programming Language :: Python :: 3",
|
|
20
|
+
"Programming Language :: Python :: 3.11",
|
|
21
|
+
"Programming Language :: Python :: 3.12",
|
|
22
|
+
"Topic :: Security",
|
|
23
|
+
"Topic :: Software Development :: Version Control :: Git",
|
|
24
|
+
]
|
|
25
|
+
dependencies = [
|
|
26
|
+
"typer>=0.12.0",
|
|
27
|
+
"pydantic>=2.0.0",
|
|
28
|
+
"pyyaml>=6.0",
|
|
29
|
+
"rich>=13.0.0",
|
|
30
|
+
]
|
|
31
|
+
|
|
32
|
+
[project.optional-dependencies]
|
|
33
|
+
malware = ["yara-python>=4.3.0"]
|
|
34
|
+
all = ["yara-python>=4.3.0"]
|
|
35
|
+
dev = [
|
|
36
|
+
"pytest>=7.4.0",
|
|
37
|
+
"pytest-cov>=4.1.0",
|
|
38
|
+
"ruff>=0.1.0",
|
|
39
|
+
"mypy>=1.5.0",
|
|
40
|
+
"types-PyYAML>=6.0",
|
|
41
|
+
"yara-python>=4.3.0",
|
|
42
|
+
]
|
|
43
|
+
|
|
44
|
+
[project.scripts]
|
|
45
|
+
gitrupt = "gitrupt.cli:app"
|
|
46
|
+
|
|
47
|
+
[project.urls]
|
|
48
|
+
Homepage = "https://github.com/gitrupt/gitrupt"
|
|
49
|
+
Repository = "https://github.com/gitrupt/gitrupt"
|
|
50
|
+
Issues = "https://github.com/gitrupt/gitrupt/issues"
|
|
51
|
+
Documentation = "https://github.com/gitrupt/gitrupt/blob/main/docs/architecture.md"
|
|
52
|
+
|
|
53
|
+
[tool.setuptools.packages.find]
|
|
54
|
+
where = ["src"]
|
|
55
|
+
|
|
56
|
+
[tool.setuptools.package-dir]
|
|
57
|
+
"" = "src"
|
|
58
|
+
|
|
59
|
+
[tool.pytest.ini_options]
|
|
60
|
+
testpaths = ["tests"]
|
|
61
|
+
python_files = ["test_*.py", "*_test.py"]
|
|
62
|
+
python_classes = ["Test*"]
|
|
63
|
+
python_functions = ["test_*"]
|
|
64
|
+
addopts = "-v --tb=short"
|
|
65
|
+
|
|
66
|
+
[tool.ruff]
|
|
67
|
+
target-version = "py311"
|
|
68
|
+
line-length = 100
|
|
69
|
+
|
|
70
|
+
[tool.ruff.lint]
|
|
71
|
+
select = ["E", "F", "W", "I", "N", "UP"]
|
|
72
|
+
|
|
73
|
+
[tool.mypy]
|
|
74
|
+
python_version = "3.11"
|
|
75
|
+
strict = true
|
|
76
|
+
ignore_missing_imports = true
|
gitrupt-0.1.0/setup.cfg
ADDED