dotvet 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.
- dotvet-0.1.0/LICENSE +21 -0
- dotvet-0.1.0/PKG-INFO +239 -0
- dotvet-0.1.0/README.md +217 -0
- dotvet-0.1.0/dotvet/__init__.py +26 -0
- dotvet-0.1.0/dotvet/cli.py +239 -0
- dotvet-0.1.0/dotvet/fixer.py +138 -0
- dotvet-0.1.0/dotvet/generator.py +123 -0
- dotvet-0.1.0/dotvet/hook.py +44 -0
- dotvet-0.1.0/dotvet/scanner.py +160 -0
- dotvet-0.1.0/dotvet/validator.py +253 -0
- dotvet-0.1.0/dotvet.egg-info/PKG-INFO +239 -0
- dotvet-0.1.0/dotvet.egg-info/SOURCES.txt +16 -0
- dotvet-0.1.0/dotvet.egg-info/dependency_links.txt +1 -0
- dotvet-0.1.0/dotvet.egg-info/entry_points.txt +3 -0
- dotvet-0.1.0/dotvet.egg-info/top_level.txt +1 -0
- dotvet-0.1.0/pyproject.toml +50 -0
- dotvet-0.1.0/setup.cfg +4 -0
- dotvet-0.1.0/setup.py +32 -0
dotvet-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 dotvet contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
dotvet-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
|
+
Name: dotvet
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Zero-config environment variable security scanner & quality gate.
|
|
5
|
+
Home-page: https://github.com/mrtag08/dotvet
|
|
6
|
+
Author: dotvet maintainers
|
|
7
|
+
Author-email: maintainers@dotvet.dev
|
|
8
|
+
License: MIT
|
|
9
|
+
Platform: UNKNOWN
|
|
10
|
+
Classifier: Development Status :: 4 - Beta
|
|
11
|
+
Classifier: Environment :: Console
|
|
12
|
+
Classifier: Intended Audience :: Developers
|
|
13
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
14
|
+
Classifier: Programming Language :: Python :: 3
|
|
15
|
+
Classifier: Topic :: Security
|
|
16
|
+
Classifier: Topic :: Software Development :: Quality Assurance
|
|
17
|
+
Requires-Python: >=3.8
|
|
18
|
+
Description-Content-Type: text/markdown
|
|
19
|
+
License-File: LICENSE
|
|
20
|
+
|
|
21
|
+
<div align="center">
|
|
22
|
+
|
|
23
|
+
# dotvet 🛡️
|
|
24
|
+
|
|
25
|
+
**Zero-config environment variable security scanner & quality gate.**
|
|
26
|
+
|
|
27
|
+
*Validate presence, ban dangerous placeholders, and enforce secret entropy before deploying to production.*
|
|
28
|
+
|
|
29
|
+
[](https://www.npmjs.com/package/dotvet)
|
|
30
|
+
[](https://pypi.org/project/dotvet/)
|
|
31
|
+
[](LICENSE)
|
|
32
|
+
[](#why-zero-dependencies)
|
|
33
|
+
|
|
34
|
+
</div>
|
|
35
|
+
|
|
36
|
+
---
|
|
37
|
+
|
|
38
|
+
## ⚡ The Problem: `dotenv-safe` Is Not Safe
|
|
39
|
+
|
|
40
|
+
Most tools (`dotenv-safe`, `envalid`, `zod`) only verify that a variable **exists**:
|
|
41
|
+
|
|
42
|
+
```env
|
|
43
|
+
# Passes dotenv-safe with flying colors:
|
|
44
|
+
JWT_SECRET=changeme
|
|
45
|
+
API_KEY=your-secret-here
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
In production, **a weak secret is worse than a missing secret**. Undersized JWT secrets (< 32 characters) allow attackers to forge tokens with HS256 brute-force dictionaries in seconds.
|
|
49
|
+
|
|
50
|
+
**`dotvet` does what other linters don't:**
|
|
51
|
+
1. 🔍 **Zero config**: Auto-scans your codebase (`process.env.X`, `os.environ.get('X')`, `os.getenv('X')`, `import.meta.env.X`, etc.) to find every environment variable you actually reference.
|
|
52
|
+
2. 🚫 **Placeholder eradication**: Detects and bans dummy defaults like `"changeme"`, `"your-secret-here"`, `"dummy"`, `"admin"`, or `"123456"`.
|
|
53
|
+
3. 🔐 **JWT-aware strictness**: Any secret matching `JWT` or `JWT_SECRET` must be at least **32 characters (256-bit)** or `dotvet` halts the build.
|
|
54
|
+
4. 🎲 **Entropy calculation**: Audits sensitive keys using Shannon entropy to catch repetitive and trivial strings.
|
|
55
|
+
5. 📜 **Schema generation**: Generates `.env.schema.json` and `.env.example` in a single command.
|
|
56
|
+
6. 🌐 **Dual-ecosystem & zero dependencies**: Works natively across Node.js (`npx dotvet`) and Python (`pip install dotvet`) with **zero third-party dependencies**.
|
|
57
|
+
|
|
58
|
+
---
|
|
59
|
+
|
|
60
|
+
## 🚀 Quickstart
|
|
61
|
+
|
|
62
|
+
### In Node.js / TypeScript Projects
|
|
63
|
+
Run immediately without installing:
|
|
64
|
+
```bash
|
|
65
|
+
npx dotvet
|
|
66
|
+
```
|
|
67
|
+
Or install as a dev dependency:
|
|
68
|
+
```bash
|
|
69
|
+
npm install --save-dev dotvet
|
|
70
|
+
# or
|
|
71
|
+
pnpm add -D dotvet
|
|
72
|
+
# or
|
|
73
|
+
yarn add -D dotvet
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
### In Python Projects
|
|
77
|
+
```bash
|
|
78
|
+
pip install dotvet
|
|
79
|
+
dotvet
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
---
|
|
83
|
+
|
|
84
|
+
## 💻 CLI Commands
|
|
85
|
+
|
|
86
|
+
### 1. `dotvet` / `dotvet check` (Default)
|
|
87
|
+
Audits `.env` against variables referenced in your code:
|
|
88
|
+
```bash
|
|
89
|
+
npx dotvet
|
|
90
|
+
# or
|
|
91
|
+
dotvet check --env .env.production
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
**Example Output:**
|
|
95
|
+
```
|
|
96
|
+
dotvet v0.1.0 — Auditing environment variables in /projects/my-app
|
|
97
|
+
Environment file: .env (found) | Found 4 vars in code
|
|
98
|
+
|
|
99
|
+
WARN .env (GITIGNORE_MISSING)
|
|
100
|
+
.env is present but not explicitly listed in .gitignore. Risk of committing secrets to Git!
|
|
101
|
+
Fix: Add ".env" to your .gitignore file.
|
|
102
|
+
|
|
103
|
+
FAIL JWT_SECRET (JWT_UNDERSIZED)
|
|
104
|
+
JWT secret JWT_SECRET length is only 18 chars (minimum 32 characters required for HMAC-SHA256). Weak JWT secrets can be forged in seconds!
|
|
105
|
+
Referenced at:
|
|
106
|
+
• src/auth.ts:12 → const token = jwt.sign(payload, process.env.JWT_SECRET);
|
|
107
|
+
Fix: Generate a 32+ char secret: "openssl rand -base64 32"
|
|
108
|
+
|
|
109
|
+
FAIL DATABASE_URL (PLACEHOLDER_SECRET)
|
|
110
|
+
Variable DATABASE_URL is set to placeholder "changeme". This is dangerous for production!
|
|
111
|
+
Referenced at:
|
|
112
|
+
• src/db.ts:4 → const pool = new Pool({ connectionString: process.env.DATABASE_URL });
|
|
113
|
+
Fix: Replace the placeholder with a secure, generated value.
|
|
114
|
+
|
|
115
|
+
PASSED CHECKS (2):
|
|
116
|
+
✔ PORT
|
|
117
|
+
✔ REDIS_URL
|
|
118
|
+
|
|
119
|
+
FAILURE Found 2 errors and 1 warning.
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
---
|
|
123
|
+
|
|
124
|
+
### 2. `dotvet scan`
|
|
125
|
+
Inspects your entire codebase and maps out where every environment variable is used:
|
|
126
|
+
```bash
|
|
127
|
+
npx dotvet scan
|
|
128
|
+
```
|
|
129
|
+
Output:
|
|
130
|
+
```
|
|
131
|
+
dotvet scan — Discovered 3 environment variables:
|
|
132
|
+
|
|
133
|
+
DATABASE_URL (2 usages)
|
|
134
|
+
↳ src/db.ts:4
|
|
135
|
+
↳ src/migrate.ts:10
|
|
136
|
+
JWT_SECRET (1 usage)
|
|
137
|
+
↳ src/auth.ts:12
|
|
138
|
+
PORT (1 usage)
|
|
139
|
+
↳ src/server.ts:8
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
---
|
|
143
|
+
|
|
144
|
+
### 3. `dotvet generate`
|
|
145
|
+
Automatically generates a `.env.example` file and `.env.schema.json` contract based on variables discovered across your codebase:
|
|
146
|
+
```bash
|
|
147
|
+
npx dotvet generate
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
---
|
|
151
|
+
|
|
152
|
+
## 🛡️ Security Rules
|
|
153
|
+
|
|
154
|
+
| Rule | Severity | Description |
|
|
155
|
+
| :--- | :--- | :--- |
|
|
156
|
+
| `MISSING_ENV_VAR` | **FAIL** | Variable referenced in code is absent from `.env` and environment. |
|
|
157
|
+
| `EMPTY_ENV_VAR` | **FAIL** | Variable is defined in `.env` but has an empty string value. |
|
|
158
|
+
| `PLACEHOLDER_SECRET` | **FAIL** | Value matches known placeholder strings (`"changeme"`, `"your-secret-here"`, `"dummy"`). |
|
|
159
|
+
| `JWT_UNDERSIZED` | **FAIL** | JWT secret is under 32 characters (violates minimum 256-bit requirement for HS256). |
|
|
160
|
+
| `LOW_ENTROPY_SECRET` | **WARN** / **FAIL** | Sensitive key has Shannon entropy < 2.5 bits/char (repeating or sequential keys). |
|
|
161
|
+
| `GITIGNORE_MISSING` | **WARN** | `.env` exists in directory but is not tracked in `.gitignore`. |
|
|
162
|
+
|
|
163
|
+
---
|
|
164
|
+
|
|
165
|
+
## ⚙️ Options & Flags
|
|
166
|
+
|
|
167
|
+
| Flag | Default | Description |
|
|
168
|
+
| :--- | :--- | :--- |
|
|
169
|
+
| `--env <path>` | `.env` | Path to environment file to audit |
|
|
170
|
+
| `--strict` | `false` | Treat warnings as hard errors (non-zero exit) |
|
|
171
|
+
| `--ci` | `false` | Emits GitHub Actions annotations (`::error file=...`) |
|
|
172
|
+
| `--json` | `false` | Emits machine-readable JSON output |
|
|
173
|
+
| `-h, --help` | | Show usage help |
|
|
174
|
+
| `-v, --version`| | Display version |
|
|
175
|
+
|
|
176
|
+
---
|
|
177
|
+
|
|
178
|
+
## 🤖 CI / CD Integration (GitHub Actions)
|
|
179
|
+
|
|
180
|
+
Add `dotvet` as a gate in your pull request workflow:
|
|
181
|
+
|
|
182
|
+
```yaml
|
|
183
|
+
name: Security & Env Quality Gate
|
|
184
|
+
|
|
185
|
+
on: [push, pull_request]
|
|
186
|
+
|
|
187
|
+
jobs:
|
|
188
|
+
env-audit:
|
|
189
|
+
runs-on: ubuntu-latest
|
|
190
|
+
steps:
|
|
191
|
+
- uses: actions/checkout@v4
|
|
192
|
+
- uses: actions/setup-node@v4
|
|
193
|
+
with:
|
|
194
|
+
node-version: 20
|
|
195
|
+
|
|
196
|
+
# Runs zero-config audit; fails PR if secrets are weak, missing, or placeholders
|
|
197
|
+
- name: Run dotvet
|
|
198
|
+
run: npx dotvet --ci --strict
|
|
199
|
+
env:
|
|
200
|
+
# Provide your mock test secrets
|
|
201
|
+
JWT_SECRET: "ci_valid_32_character_long_secret_key_12345"
|
|
202
|
+
DATABASE_URL: "postgresql://ci:ci@localhost:5432/test"
|
|
203
|
+
PORT: "3000"
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
---
|
|
207
|
+
|
|
208
|
+
## 📦 Publishing Tonight
|
|
209
|
+
|
|
210
|
+
### Publish to npm
|
|
211
|
+
```bash
|
|
212
|
+
npm publish --access public
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
### Publish to PyPI
|
|
216
|
+
```bash
|
|
217
|
+
python3 -m pip install --upgrade build twine
|
|
218
|
+
python3 -m build
|
|
219
|
+
python3 -m twine upload dist/*
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
---
|
|
223
|
+
|
|
224
|
+
## 🔒 Why Zero Dependencies?
|
|
225
|
+
|
|
226
|
+
Recent attacks on the open-source supply chain (such as the ChainDrop worm) demonstrated how deeply nested dependencies can introduce backdoors into developer tooling.
|
|
227
|
+
|
|
228
|
+
`dotvet` is designed from the ground up with **0 runtime dependencies** in both Node.js and Python. It runs exclusively using native language standard libraries, guaranteeing:
|
|
229
|
+
- Sub-200ms cold startup in CI.
|
|
230
|
+
- Zero transitive supply chain attack surface.
|
|
231
|
+
- Immunity to package manager lifecycle hook breaking changes (e.g. npm v12).
|
|
232
|
+
|
|
233
|
+
---
|
|
234
|
+
|
|
235
|
+
## 📄 License
|
|
236
|
+
|
|
237
|
+
MIT © 2026 dotvet contributors
|
|
238
|
+
|
|
239
|
+
|
dotvet-0.1.0/README.md
ADDED
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
<div align="center">
|
|
2
|
+
|
|
3
|
+
# dotvet 🛡️
|
|
4
|
+
|
|
5
|
+
**Zero-config environment variable security scanner & quality gate.**
|
|
6
|
+
|
|
7
|
+
*Validate presence, ban dangerous placeholders, and enforce secret entropy before deploying to production.*
|
|
8
|
+
|
|
9
|
+
[](https://www.npmjs.com/package/dotvet)
|
|
10
|
+
[](https://pypi.org/project/dotvet/)
|
|
11
|
+
[](LICENSE)
|
|
12
|
+
[](#why-zero-dependencies)
|
|
13
|
+
|
|
14
|
+
</div>
|
|
15
|
+
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
## ⚡ The Problem: `dotenv-safe` Is Not Safe
|
|
19
|
+
|
|
20
|
+
Most tools (`dotenv-safe`, `envalid`, `zod`) only verify that a variable **exists**:
|
|
21
|
+
|
|
22
|
+
```env
|
|
23
|
+
# Passes dotenv-safe with flying colors:
|
|
24
|
+
JWT_SECRET=changeme
|
|
25
|
+
API_KEY=your-secret-here
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
In production, **a weak secret is worse than a missing secret**. Undersized JWT secrets (< 32 characters) allow attackers to forge tokens with HS256 brute-force dictionaries in seconds.
|
|
29
|
+
|
|
30
|
+
**`dotvet` does what other linters don't:**
|
|
31
|
+
1. 🔍 **Zero config**: Auto-scans your codebase (`process.env.X`, `os.environ.get('X')`, `os.getenv('X')`, `import.meta.env.X`, etc.) to find every environment variable you actually reference.
|
|
32
|
+
2. 🚫 **Placeholder eradication**: Detects and bans dummy defaults like `"changeme"`, `"your-secret-here"`, `"dummy"`, `"admin"`, or `"123456"`.
|
|
33
|
+
3. 🔐 **JWT-aware strictness**: Any secret matching `JWT` or `JWT_SECRET` must be at least **32 characters (256-bit)** or `dotvet` halts the build.
|
|
34
|
+
4. 🎲 **Entropy calculation**: Audits sensitive keys using Shannon entropy to catch repetitive and trivial strings.
|
|
35
|
+
5. 📜 **Schema generation**: Generates `.env.schema.json` and `.env.example` in a single command.
|
|
36
|
+
6. 🌐 **Dual-ecosystem & zero dependencies**: Works natively across Node.js (`npx dotvet`) and Python (`pip install dotvet`) with **zero third-party dependencies**.
|
|
37
|
+
|
|
38
|
+
---
|
|
39
|
+
|
|
40
|
+
## 🚀 Quickstart
|
|
41
|
+
|
|
42
|
+
### In Node.js / TypeScript Projects
|
|
43
|
+
Run immediately without installing:
|
|
44
|
+
```bash
|
|
45
|
+
npx dotvet
|
|
46
|
+
```
|
|
47
|
+
Or install as a dev dependency:
|
|
48
|
+
```bash
|
|
49
|
+
npm install --save-dev dotvet
|
|
50
|
+
# or
|
|
51
|
+
pnpm add -D dotvet
|
|
52
|
+
# or
|
|
53
|
+
yarn add -D dotvet
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
### In Python Projects
|
|
57
|
+
```bash
|
|
58
|
+
pip install dotvet
|
|
59
|
+
dotvet
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
---
|
|
63
|
+
|
|
64
|
+
## 💻 CLI Commands
|
|
65
|
+
|
|
66
|
+
### 1. `dotvet` / `dotvet check` (Default)
|
|
67
|
+
Audits `.env` against variables referenced in your code:
|
|
68
|
+
```bash
|
|
69
|
+
npx dotvet
|
|
70
|
+
# or
|
|
71
|
+
dotvet check --env .env.production
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
**Example Output:**
|
|
75
|
+
```
|
|
76
|
+
dotvet v0.1.0 — Auditing environment variables in /projects/my-app
|
|
77
|
+
Environment file: .env (found) | Found 4 vars in code
|
|
78
|
+
|
|
79
|
+
WARN .env (GITIGNORE_MISSING)
|
|
80
|
+
.env is present but not explicitly listed in .gitignore. Risk of committing secrets to Git!
|
|
81
|
+
Fix: Add ".env" to your .gitignore file.
|
|
82
|
+
|
|
83
|
+
FAIL JWT_SECRET (JWT_UNDERSIZED)
|
|
84
|
+
JWT secret JWT_SECRET length is only 18 chars (minimum 32 characters required for HMAC-SHA256). Weak JWT secrets can be forged in seconds!
|
|
85
|
+
Referenced at:
|
|
86
|
+
• src/auth.ts:12 → const token = jwt.sign(payload, process.env.JWT_SECRET);
|
|
87
|
+
Fix: Generate a 32+ char secret: "openssl rand -base64 32"
|
|
88
|
+
|
|
89
|
+
FAIL DATABASE_URL (PLACEHOLDER_SECRET)
|
|
90
|
+
Variable DATABASE_URL is set to placeholder "changeme". This is dangerous for production!
|
|
91
|
+
Referenced at:
|
|
92
|
+
• src/db.ts:4 → const pool = new Pool({ connectionString: process.env.DATABASE_URL });
|
|
93
|
+
Fix: Replace the placeholder with a secure, generated value.
|
|
94
|
+
|
|
95
|
+
PASSED CHECKS (2):
|
|
96
|
+
✔ PORT
|
|
97
|
+
✔ REDIS_URL
|
|
98
|
+
|
|
99
|
+
FAILURE Found 2 errors and 1 warning.
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
---
|
|
103
|
+
|
|
104
|
+
### 2. `dotvet scan`
|
|
105
|
+
Inspects your entire codebase and maps out where every environment variable is used:
|
|
106
|
+
```bash
|
|
107
|
+
npx dotvet scan
|
|
108
|
+
```
|
|
109
|
+
Output:
|
|
110
|
+
```
|
|
111
|
+
dotvet scan — Discovered 3 environment variables:
|
|
112
|
+
|
|
113
|
+
DATABASE_URL (2 usages)
|
|
114
|
+
↳ src/db.ts:4
|
|
115
|
+
↳ src/migrate.ts:10
|
|
116
|
+
JWT_SECRET (1 usage)
|
|
117
|
+
↳ src/auth.ts:12
|
|
118
|
+
PORT (1 usage)
|
|
119
|
+
↳ src/server.ts:8
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
---
|
|
123
|
+
|
|
124
|
+
### 3. `dotvet generate`
|
|
125
|
+
Automatically generates a `.env.example` file and `.env.schema.json` contract based on variables discovered across your codebase:
|
|
126
|
+
```bash
|
|
127
|
+
npx dotvet generate
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
---
|
|
131
|
+
|
|
132
|
+
## 🛡️ Security Rules
|
|
133
|
+
|
|
134
|
+
| Rule | Severity | Description |
|
|
135
|
+
| :--- | :--- | :--- |
|
|
136
|
+
| `MISSING_ENV_VAR` | **FAIL** | Variable referenced in code is absent from `.env` and environment. |
|
|
137
|
+
| `EMPTY_ENV_VAR` | **FAIL** | Variable is defined in `.env` but has an empty string value. |
|
|
138
|
+
| `PLACEHOLDER_SECRET` | **FAIL** | Value matches known placeholder strings (`"changeme"`, `"your-secret-here"`, `"dummy"`). |
|
|
139
|
+
| `JWT_UNDERSIZED` | **FAIL** | JWT secret is under 32 characters (violates minimum 256-bit requirement for HS256). |
|
|
140
|
+
| `LOW_ENTROPY_SECRET` | **WARN** / **FAIL** | Sensitive key has Shannon entropy < 2.5 bits/char (repeating or sequential keys). |
|
|
141
|
+
| `GITIGNORE_MISSING` | **WARN** | `.env` exists in directory but is not tracked in `.gitignore`. |
|
|
142
|
+
|
|
143
|
+
---
|
|
144
|
+
|
|
145
|
+
## ⚙️ Options & Flags
|
|
146
|
+
|
|
147
|
+
| Flag | Default | Description |
|
|
148
|
+
| :--- | :--- | :--- |
|
|
149
|
+
| `--env <path>` | `.env` | Path to environment file to audit |
|
|
150
|
+
| `--strict` | `false` | Treat warnings as hard errors (non-zero exit) |
|
|
151
|
+
| `--ci` | `false` | Emits GitHub Actions annotations (`::error file=...`) |
|
|
152
|
+
| `--json` | `false` | Emits machine-readable JSON output |
|
|
153
|
+
| `-h, --help` | | Show usage help |
|
|
154
|
+
| `-v, --version`| | Display version |
|
|
155
|
+
|
|
156
|
+
---
|
|
157
|
+
|
|
158
|
+
## 🤖 CI / CD Integration (GitHub Actions)
|
|
159
|
+
|
|
160
|
+
Add `dotvet` as a gate in your pull request workflow:
|
|
161
|
+
|
|
162
|
+
```yaml
|
|
163
|
+
name: Security & Env Quality Gate
|
|
164
|
+
|
|
165
|
+
on: [push, pull_request]
|
|
166
|
+
|
|
167
|
+
jobs:
|
|
168
|
+
env-audit:
|
|
169
|
+
runs-on: ubuntu-latest
|
|
170
|
+
steps:
|
|
171
|
+
- uses: actions/checkout@v4
|
|
172
|
+
- uses: actions/setup-node@v4
|
|
173
|
+
with:
|
|
174
|
+
node-version: 20
|
|
175
|
+
|
|
176
|
+
# Runs zero-config audit; fails PR if secrets are weak, missing, or placeholders
|
|
177
|
+
- name: Run dotvet
|
|
178
|
+
run: npx dotvet --ci --strict
|
|
179
|
+
env:
|
|
180
|
+
# Provide your mock test secrets
|
|
181
|
+
JWT_SECRET: "ci_valid_32_character_long_secret_key_12345"
|
|
182
|
+
DATABASE_URL: "postgresql://ci:ci@localhost:5432/test"
|
|
183
|
+
PORT: "3000"
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
---
|
|
187
|
+
|
|
188
|
+
## 📦 Publishing Tonight
|
|
189
|
+
|
|
190
|
+
### Publish to npm
|
|
191
|
+
```bash
|
|
192
|
+
npm publish --access public
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
### Publish to PyPI
|
|
196
|
+
```bash
|
|
197
|
+
python3 -m pip install --upgrade build twine
|
|
198
|
+
python3 -m build
|
|
199
|
+
python3 -m twine upload dist/*
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
---
|
|
203
|
+
|
|
204
|
+
## 🔒 Why Zero Dependencies?
|
|
205
|
+
|
|
206
|
+
Recent attacks on the open-source supply chain (such as the ChainDrop worm) demonstrated how deeply nested dependencies can introduce backdoors into developer tooling.
|
|
207
|
+
|
|
208
|
+
`dotvet` is designed from the ground up with **0 runtime dependencies** in both Node.js and Python. It runs exclusively using native language standard libraries, guaranteeing:
|
|
209
|
+
- Sub-200ms cold startup in CI.
|
|
210
|
+
- Zero transitive supply chain attack surface.
|
|
211
|
+
- Immunity to package manager lifecycle hook breaking changes (e.g. npm v12).
|
|
212
|
+
|
|
213
|
+
---
|
|
214
|
+
|
|
215
|
+
## 📄 License
|
|
216
|
+
|
|
217
|
+
MIT © 2026 dotvet contributors
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"""dotvet: Zero-Config Environment Variable Security Scanner & Quality Gate."""
|
|
2
|
+
|
|
3
|
+
__version__ = "0.1.0"
|
|
4
|
+
|
|
5
|
+
from .scanner import scan_codebase, scan_file, find_files
|
|
6
|
+
from .validator import validate_env, parse_dotenv, calculate_entropy, is_placeholder
|
|
7
|
+
from .generator import generate_env_example, generate_schema, write_generated_files
|
|
8
|
+
from .fixer import fix_env, generate_secure_secret
|
|
9
|
+
from .hook import install_git_hook
|
|
10
|
+
|
|
11
|
+
__all__ = [
|
|
12
|
+
"scan_codebase",
|
|
13
|
+
"scan_file",
|
|
14
|
+
"find_files",
|
|
15
|
+
"validate_env",
|
|
16
|
+
"parse_dotenv",
|
|
17
|
+
"calculate_entropy",
|
|
18
|
+
"is_placeholder",
|
|
19
|
+
"generate_env_example",
|
|
20
|
+
"generate_schema",
|
|
21
|
+
"write_generated_files",
|
|
22
|
+
"fix_env",
|
|
23
|
+
"generate_secure_secret",
|
|
24
|
+
"install_git_hook",
|
|
25
|
+
"__version__",
|
|
26
|
+
]
|