@fentz26/envcp 1.1.0 → 1.2.0-exp.8d5b91b
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 +65 -421
- package/VERSION +1 -0
- package/dist/adapters/base.d.ts +31 -3
- package/dist/adapters/base.d.ts.map +1 -1
- package/dist/adapters/base.js +235 -26
- package/dist/adapters/base.js.map +1 -1
- package/dist/adapters/gemini.d.ts +1 -1
- package/dist/adapters/gemini.d.ts.map +1 -1
- package/dist/adapters/gemini.js +12 -7
- package/dist/adapters/gemini.js.map +1 -1
- package/dist/adapters/openai.d.ts +1 -1
- package/dist/adapters/openai.d.ts.map +1 -1
- package/dist/adapters/openai.js +14 -9
- package/dist/adapters/openai.js.map +1 -1
- package/dist/adapters/rest.d.ts +3 -1
- package/dist/adapters/rest.d.ts.map +1 -1
- package/dist/adapters/rest.js +99 -15
- package/dist/adapters/rest.js.map +1 -1
- package/dist/cli/index.js +678 -138
- package/dist/cli/index.js.map +1 -1
- package/dist/config/config-guard.d.ts.map +1 -1
- package/dist/config/config-guard.js +3 -2
- package/dist/config/config-guard.js.map +1 -1
- package/dist/config/config-hmac.d.ts +5 -0
- package/dist/config/config-hmac.d.ts.map +1 -0
- package/dist/config/config-hmac.js +29 -0
- package/dist/config/config-hmac.js.map +1 -0
- package/dist/config/manager.d.ts +20 -2
- package/dist/config/manager.d.ts.map +1 -1
- package/dist/config/manager.js +103 -26
- package/dist/config/manager.js.map +1 -1
- package/dist/mcp/server.d.ts +1 -1
- package/dist/mcp/server.d.ts.map +1 -1
- package/dist/mcp/server.js +8 -4
- package/dist/mcp/server.js.map +1 -1
- package/dist/server/unified.d.ts +4 -1
- package/dist/server/unified.d.ts.map +1 -1
- package/dist/server/unified.js +108 -39
- package/dist/server/unified.js.map +1 -1
- package/dist/service/config.d.ts +21 -0
- package/dist/service/config.d.ts.map +1 -0
- package/dist/service/config.js +94 -0
- package/dist/service/config.js.map +1 -0
- package/dist/service/generators.d.ts +14 -0
- package/dist/service/generators.d.ts.map +1 -0
- package/dist/service/generators.js +92 -0
- package/dist/service/generators.js.map +1 -0
- package/dist/service/index.d.ts +23 -0
- package/dist/service/index.d.ts.map +1 -0
- package/dist/service/index.js +215 -0
- package/dist/service/index.js.map +1 -0
- package/dist/service/platform.d.ts +5 -0
- package/dist/service/platform.d.ts.map +1 -0
- package/dist/service/platform.js +25 -0
- package/dist/service/platform.js.map +1 -0
- package/dist/storage/index.d.ts +52 -10
- package/dist/storage/index.d.ts.map +1 -1
- package/dist/storage/index.js +350 -31
- package/dist/storage/index.js.map +1 -1
- package/dist/types.d.ts +574 -14
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +79 -2
- package/dist/types.js.map +1 -1
- package/dist/utils/crypto.d.ts +9 -0
- package/dist/utils/crypto.d.ts.map +1 -1
- package/dist/utils/crypto.js +88 -19
- package/dist/utils/crypto.js.map +1 -1
- package/dist/utils/fs.d.ts +1 -0
- package/dist/utils/fs.d.ts.map +1 -1
- package/dist/utils/fs.js +12 -0
- package/dist/utils/fs.js.map +1 -1
- package/dist/utils/hsm.d.ts +82 -0
- package/dist/utils/hsm.d.ts.map +1 -0
- package/dist/utils/hsm.js +344 -0
- package/dist/utils/hsm.js.map +1 -0
- package/dist/utils/http.d.ts.map +1 -1
- package/dist/utils/http.js +14 -4
- package/dist/utils/http.js.map +1 -1
- package/dist/utils/keychain.d.ts.map +1 -1
- package/dist/utils/keychain.js +0 -8
- package/dist/utils/keychain.js.map +1 -1
- package/dist/utils/lock.d.ts +1 -1
- package/dist/utils/lock.d.ts.map +1 -1
- package/dist/utils/lock.js +4 -2
- package/dist/utils/lock.js.map +1 -1
- package/dist/utils/lockout.d.ts +56 -0
- package/dist/utils/lockout.d.ts.map +1 -0
- package/dist/utils/lockout.js +209 -0
- package/dist/utils/lockout.js.map +1 -0
- package/dist/utils/prompt.d.ts +13 -0
- package/dist/utils/prompt.d.ts.map +1 -0
- package/dist/utils/prompt.js +124 -0
- package/dist/utils/prompt.js.map +1 -0
- package/dist/utils/secure-memory.d.ts +20 -0
- package/dist/utils/secure-memory.d.ts.map +1 -0
- package/dist/utils/secure-memory.js +122 -0
- package/dist/utils/secure-memory.js.map +1 -0
- package/dist/utils/session.d.ts.map +1 -1
- package/dist/utils/session.js +14 -4
- package/dist/utils/session.js.map +1 -1
- package/dist/utils/update-checker.d.ts +1 -1
- package/dist/utils/update-checker.d.ts.map +1 -1
- package/dist/utils/update-checker.js +7 -5
- package/dist/utils/update-checker.js.map +1 -1
- package/dist/vault/index.d.ts +2 -0
- package/dist/vault/index.d.ts.map +1 -1
- package/dist/vault/index.js +12 -2
- package/dist/vault/index.js.map +1 -1
- package/dist/version.d.ts +2 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +8 -0
- package/dist/version.js.map +1 -0
- package/package.json +18 -9
- package/scripts/sync-version.js +88 -0
- package/scripts/install.sh +0 -54
package/README.md
CHANGED
|
@@ -1,11 +1,23 @@
|
|
|
1
1
|
|
|
2
2
|
|
|
3
3
|
<p align="center">
|
|
4
|
-
<a href="https://envcp.
|
|
4
|
+
<a href="https://envcp.org/docs"><img src="./assets/logo-ascii.png" alt="EnvCP" width="100%"></a>
|
|
5
5
|
</p>
|
|
6
6
|
|
|
7
7
|
<p align="center">
|
|
8
|
-
<
|
|
8
|
+
<a href="https://www.npmjs.com/package/@fentz26/envcp"><img src="https://img.shields.io/npm/v/%40fentz26%2Fenvcp?style=flat-square&color=000000&labelColor=000000&label=version" alt="npm version"></a>
|
|
9
|
+
<a href="https://www.npmjs.com/package/@fentz26/envcp"><img src="https://img.shields.io/npm/dt/%40fentz26%2Fenvcp?style=flat-square&color=000000&labelColor=000000&label=downloads" alt="npm downloads"></a>
|
|
10
|
+
<a href="https://www.npmjs.com/package/@fentz26/envcp"><img src="https://img.shields.io/npm/unpacked-size/%40fentz26%2Fenvcp?style=flat-square&color=000000&labelColor=000000&label=size" alt="npm size"></a>
|
|
11
|
+
<a href="https://github.com/fentz26/EnvCP/actions"><img src="https://img.shields.io/github/actions/workflow/status/fentz26/EnvCP/ci.yml?style=flat-square&color=000000&labelColor=000000&label=ci" alt="CI"></a>
|
|
12
|
+
<a href="https://codecov.io/github/fentz26/EnvCP"><img src="https://img.shields.io/codecov/c/github/fentz26/EnvCP?style=flat-square&color=000000&labelColor=000000&label=coverage&token=FKMIN74O9C" alt="codecov"></a>
|
|
13
|
+
<a href="https://github.com/fentz26/EnvCP/blob/main/LICENSE"><img src="https://img.shields.io/badge/license-SAL%20v1.0-000000?style=flat-square&labelColor=000000" alt="license"></a>
|
|
14
|
+
<a href="https://github.com/fentz26/EnvCP/releases"><img src="https://img.shields.io/badge/SLSA-3-000000?style=flat-square&labelColor=000000" alt="SLSA Level 3"></a>
|
|
15
|
+
<a href="https://nodejs.org"><img src="https://img.shields.io/node/v/%40fentz26%2Fenvcp?style=flat-square&color=000000&labelColor=000000&label=node" alt="node version"></a>
|
|
16
|
+
<a href="https://github.com/fentz26/EnvCP"><img src="https://badgen.net/badge/lines/41k/000000?labelColor=000000" alt="lines"></a>
|
|
17
|
+
</p>
|
|
18
|
+
|
|
19
|
+
<p align="center">
|
|
20
|
+
<strong>Secure secrets for AI agents — local, encrypted, reference-only.</strong>
|
|
9
21
|
</p>
|
|
10
22
|
|
|
11
23
|
<p align="center">
|
|
@@ -20,85 +32,22 @@
|
|
|
20
32
|
</p>
|
|
21
33
|
|
|
22
34
|
<p align="center">
|
|
23
|
-
<a href="
|
|
24
|
-
|
|
25
|
-
<a href="
|
|
26
|
-
<a href="https://github.com/fentz26/EnvCP/actions"><img src="https://img.shields.io/github/actions/workflow/status/fentz26/EnvCP/ci.yml?style=flat-square&color=000000&labelColor=000000&label=ci" alt="CI"></a>
|
|
27
|
-
<a href="https://github.com/fentz26/EnvCP/blob/main/LICENSE"><img src="https://img.shields.io/badge/license-SAL%20v1.0-000000?style=flat-square&labelColor=000000" alt="license"></a>
|
|
28
|
-
<a href="https://github.com/fentz26/EnvCP/releases"><img src="https://img.shields.io/badge/SLSA-3-000000?style=flat-square&labelColor=000000" alt="SLSA Level 3"></a>
|
|
29
|
-
<a href="https://nodejs.org"><img src="https://img.shields.io/node/v/%40fentz26%2Fenvcp?style=flat-square&color=000000&labelColor=000000&label=node" alt="node version"></a>
|
|
35
|
+
<a href="vscode://anthropic.claude-code/add-mcp?name=envcp&config=eyJjb21tYW5kIjoibnB4IiwiYXJncyI6WyIteSIsIkBmZW50ejI2L2VudmNwIiwic2VydmUiLCItLW1vZGUiLCJtY3AiXX0%3D"><img src="https://img.shields.io/badge/VS_Code-Add_MCP-000000?style=flat-square&logo=visualstudiocode&logoColor=white&labelColor=000000" alt="Add to VS Code"></a>
|
|
36
|
+
|
|
37
|
+
<a href="vscode-insiders://anthropic.claude-code/add-mcp?name=envcp&config=eyJjb21tYW5kIjoibnB4IiwiYXJncyI6WyIteSIsIkBmZW50ejI2L2VudmNwIiwic2VydmUiLCItLW1vZGUiLCJtY3AiXX0%3D"><img src="https://img.shields.io/badge/VS_Code_Insiders-Add_MCP-000000?style=flat-square&logo=visualstudiocode&logoColor=white&labelColor=000000" alt="Add to VS Code Insiders"></a>
|
|
30
38
|
</p>
|
|
31
39
|
|
|
32
40
|
<p align="center">
|
|
33
41
|
<a href="https://cursor.com/en/install-mcp?name=envcp&config=eyJjb21tYW5kIjoibnB4IiwiYXJncyI6WyIteSIsIkBmZW50ejI2L2VudmNwIiwic2VydmUiLCItLW1vZGUiLCJtY3AiXX0%3D"><img src="https://cursor.com/deeplink/mcp-install-dark.svg" alt="Add to Cursor"></a>
|
|
42
|
+
|
|
34
43
|
</p>
|
|
35
44
|
|
|
36
45
|
<p align="center">
|
|
37
|
-
|
|
38
|
-
|
|
46
|
+
Secure environment variable management for AI-assisted coding.<br>
|
|
47
|
+
MCP server that lets AI reference your secrets by name — never by value.
|
|
39
48
|
</p>
|
|
40
49
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
### npm
|
|
44
|
-
|
|
45
|
-
```bash
|
|
46
|
-
npm install -g @fentz26/envcp
|
|
47
|
-
```
|
|
48
|
-
|
|
49
|
-
### pip (Python)
|
|
50
|
-
|
|
51
|
-
```bash
|
|
52
|
-
pip install envcp
|
|
53
|
-
```
|
|
54
|
-
> [!NOTE]
|
|
55
|
-
> Requires Node.js 18+ to be installed.
|
|
56
|
-
|
|
57
|
-
### Use without installing
|
|
58
|
-
|
|
59
|
-
```bash
|
|
60
|
-
npx @fentz26/envcp init
|
|
61
|
-
```
|
|
62
|
-
|
|
63
|
-
## Quick Start
|
|
64
|
-
|
|
65
|
-
```bash
|
|
66
|
-
# 1. Initialize in your project
|
|
67
|
-
envcp init
|
|
68
|
-
|
|
69
|
-
# 2. Add your secrets
|
|
70
|
-
envcp add API_KEY --value "your-secret-key"
|
|
71
|
-
envcp add DATABASE_URL --value "postgres://..."
|
|
72
|
-
|
|
73
|
-
# 3. Start the server (auto-detects client type)
|
|
74
|
-
envcp serve --mode auto --port 3456
|
|
75
|
-
```
|
|
76
|
-
|
|
77
|
-
## Basic CLI Commands
|
|
78
|
-
|
|
79
|
-
```bash
|
|
80
|
-
# Variable Management
|
|
81
|
-
envcp add <name> [options] # Add a variable
|
|
82
|
-
envcp list [--show-values] # List variables
|
|
83
|
-
envcp get <name> # Get a variable
|
|
84
|
-
envcp remove <name> # Remove a variable
|
|
85
|
-
|
|
86
|
-
# Vault Management
|
|
87
|
-
envcp vault --global init|add|list|get|delete # Operate on global vault
|
|
88
|
-
envcp vault --project init|add|list|get|delete # Operate on project vault
|
|
89
|
-
envcp vault --name <name> init|add|list|get|delete # Named vaults
|
|
90
|
-
envcp vault-switch <name> # Switch active vault (global, project, or named)
|
|
91
|
-
envcp vault-list # List all available vaults
|
|
92
|
-
|
|
93
|
-
# Session Management
|
|
94
|
-
envcp unlock # Unlock with password
|
|
95
|
-
envcp lock # Lock immediately
|
|
96
|
-
envcp status # Check session status
|
|
97
|
-
|
|
98
|
-
# Sync and Export
|
|
99
|
-
envcp sync # Sync to .env file
|
|
100
|
-
envcp export [--format env|json|yaml]
|
|
101
|
-
```
|
|
50
|
+
---
|
|
102
51
|
|
|
103
52
|
## Why EnvCP?
|
|
104
53
|
|
|
@@ -111,383 +60,78 @@ envcp export [--format env|json|yaml]
|
|
|
111
60
|
|
|
112
61
|
---
|
|
113
62
|
|
|
114
|
-
##
|
|
115
|
-
|
|
116
|
-
EnvCP is built with security-first principles:
|
|
63
|
+
## What's New in v1.2.0
|
|
117
64
|
|
|
118
|
-
- **
|
|
119
|
-
- **
|
|
120
|
-
- **
|
|
65
|
+
- **Rust Core Library**: AES-256-GCM encryption, Argon2id key derivation, and HMAC-SHA256 implemented in Rust for maximum performance and security
|
|
66
|
+
- **Memory Hardening**: Zero-sensitive memory, prevent swapping, core dump protection
|
|
67
|
+
- **Brute-Force Protection**: Progressive delays and permanent lockout after repeated failures
|
|
68
|
+
- **Email/Webhook Notifications**: Alert on security events (lockouts, unlocks)
|
|
69
|
+
- **Auto-Startup System Service**: Install as systemd/launchd/Windows service for always-on availability
|
|
70
|
+
- **API Key Enforcement**: Stricter validation when AI access is enabled
|
|
71
|
+
- **Config File Integrity Protection**: HMAC-SHA256 signatures detect tampering
|
|
72
|
+
- **Release Channels**: Latest, Experimental, and Canary channels for different risk profiles
|
|
73
|
+
- **Python Native Binding**: `pip install envcp-core` for Python applications without Node.js
|
|
74
|
+
- **Security Audit Fixes**: All High and Medium severity findings addressed (CORS bypass, backup auto-restore, Windows injection, etc.)
|
|
121
75
|
|
|
122
|
-
### Verifying Releases
|
|
123
76
|
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
```bash
|
|
127
|
-
# Download the release tarball and provenance
|
|
128
|
-
gh release download v1.0.9 --pattern '*.tgz' --pattern 'multiple.intoto.jsonl'
|
|
129
|
-
|
|
130
|
-
# Verify the release
|
|
131
|
-
slsa-verifier verify-artifact \
|
|
132
|
-
--provenance-path multiple.intoto.jsonl \
|
|
133
|
-
--source-uri github.com/fentz26/EnvCP \
|
|
134
|
-
fentz26-envcp-1.0.9.tgz
|
|
135
|
-
```
|
|
136
|
-
|
|
137
|
-
This confirms:
|
|
138
|
-
- The release was built from the official source
|
|
139
|
-
- The build process was tamper-resistant
|
|
140
|
-
- The artifact hasn't been modified after the build
|
|
141
|
-
|
|
142
|
-
---
|
|
143
|
-
|
|
144
|
-
## Integration Guides
|
|
145
|
-
|
|
146
|
-
### Claude Desktop / Cursor / Cline (MCP)
|
|
147
|
-
|
|
148
|
-
Add to your MCP config file:
|
|
149
|
-
|
|
150
|
-
```json
|
|
151
|
-
{
|
|
152
|
-
"mcpServers": {
|
|
153
|
-
"envcp": {
|
|
154
|
-
"command": "npx",
|
|
155
|
-
"args": ["@fentz26/envcp", "serve", "--mode", "mcp"]
|
|
156
|
-
}
|
|
157
|
-
}
|
|
158
|
-
}
|
|
159
|
-
```
|
|
160
|
-
|
|
161
|
-
### Augment Code / Auggie CLI
|
|
162
|
-
|
|
163
|
-
**Via Auggie CLI:**
|
|
164
|
-
|
|
165
|
-
```bash
|
|
166
|
-
auggie mcp add-json envcp '{"type":"stdio","command":"npx","args":["-y","@fentz26/envcp","serve","--mode","mcp"]}'
|
|
167
|
-
```
|
|
168
|
-
|
|
169
|
-
**Via Augment Settings (VS Code / JetBrains):**
|
|
170
|
-
|
|
171
|
-
Import this JSON in the MCP section:
|
|
172
|
-
|
|
173
|
-
```json
|
|
174
|
-
{
|
|
175
|
-
"mcpServers": {
|
|
176
|
-
"envcp": {
|
|
177
|
-
"command": "npx",
|
|
178
|
-
"args": ["-y", "@fentz26/envcp", "serve", "--mode", "mcp"]
|
|
179
|
-
}
|
|
180
|
-
}
|
|
181
|
-
}
|
|
182
|
-
```
|
|
183
|
-
|
|
184
|
-
### ChatGPT / OpenAI API
|
|
185
|
-
|
|
186
|
-
```bash
|
|
187
|
-
envcp serve --mode openai --port 3456 --api-key your-secret-key
|
|
188
|
-
```
|
|
189
|
-
|
|
190
|
-
```python
|
|
191
|
-
import openai
|
|
192
|
-
|
|
193
|
-
client = openai.OpenAI(
|
|
194
|
-
base_url="http://localhost:3456/v1",
|
|
195
|
-
api_key="your-secret-key"
|
|
196
|
-
)
|
|
197
|
-
|
|
198
|
-
# Call a function
|
|
199
|
-
result = client.post("/functions/call", json={
|
|
200
|
-
"name": "envcp_get",
|
|
201
|
-
"arguments": {"name": "API_KEY"}
|
|
202
|
-
})
|
|
203
|
-
```
|
|
204
|
-
|
|
205
|
-
### Gemini / Google AI
|
|
206
|
-
|
|
207
|
-
```bash
|
|
208
|
-
envcp serve --mode gemini --port 3456 --api-key your-secret-key
|
|
209
|
-
```
|
|
210
|
-
|
|
211
|
-
```python
|
|
212
|
-
import requests
|
|
213
|
-
|
|
214
|
-
# Get available tools
|
|
215
|
-
tools = requests.get(
|
|
216
|
-
"http://localhost:3456/v1/tools",
|
|
217
|
-
headers={"X-Goog-Api-Key": "your-secret-key"}
|
|
218
|
-
).json()
|
|
219
|
-
|
|
220
|
-
# Call a function
|
|
221
|
-
result = requests.post(
|
|
222
|
-
"http://localhost:3456/v1/functions/call",
|
|
223
|
-
headers={"X-Goog-Api-Key": "your-secret-key"},
|
|
224
|
-
json={"name": "envcp_get", "args": {"name": "API_KEY"}}
|
|
225
|
-
).json()
|
|
226
|
-
```
|
|
227
|
-
|
|
228
|
-
### Local LLMs (Ollama, LM Studio)
|
|
229
|
-
|
|
230
|
-
```bash
|
|
231
|
-
# OpenAI-compatible (works with most local LLM tools)
|
|
232
|
-
envcp serve --mode openai --port 3456
|
|
233
|
-
|
|
234
|
-
# Or universal REST
|
|
235
|
-
envcp serve --mode rest --port 3456
|
|
236
|
-
```
|
|
237
|
-
|
|
238
|
-
Configure your LLM tool to use `http://localhost:3456` as the tool server.
|
|
239
|
-
|
|
240
|
-
### REST API (Universal)
|
|
241
|
-
|
|
242
|
-
```bash
|
|
243
|
-
envcp serve --mode rest --port 3456 --api-key your-secret-key
|
|
244
|
-
```
|
|
245
|
-
|
|
246
|
-
Endpoints:
|
|
247
|
-
|
|
248
|
-
```
|
|
249
|
-
GET /api/health - Health check
|
|
250
|
-
GET /api/variables - List variables
|
|
251
|
-
GET /api/variables/:name - Get variable
|
|
252
|
-
POST /api/variables - Create variable
|
|
253
|
-
PUT /api/variables/:name - Update variable
|
|
254
|
-
DELETE /api/variables/:name - Delete variable
|
|
255
|
-
POST /api/sync - Sync to .env
|
|
256
|
-
POST /api/run - Run command with env vars
|
|
257
|
-
GET /api/tools - List available tools
|
|
258
|
-
POST /api/tools/:name - Call tool by name
|
|
259
|
-
```
|
|
260
|
-
|
|
261
|
-
```bash
|
|
262
|
-
# List variables
|
|
263
|
-
curl -H "X-API-Key: your-secret-key" http://localhost:3456/api/variables
|
|
264
|
-
|
|
265
|
-
# Get a variable
|
|
266
|
-
curl -H "X-API-Key: your-secret-key" http://localhost:3456/api/variables/API_KEY
|
|
267
|
-
|
|
268
|
-
# Create a variable
|
|
269
|
-
curl -X POST -H "X-API-Key: your-secret-key" \
|
|
270
|
-
-H "Content-Type: application/json" \
|
|
271
|
-
-d '{"name": "NEW_VAR", "value": "secret123"}' \
|
|
272
|
-
http://localhost:3456/api/variables
|
|
273
|
-
```
|
|
274
|
-
|
|
275
|
-
## Server Modes
|
|
276
|
-
|
|
277
|
-
| Mode | Description | Use Case |
|
|
278
|
-
|------|-------------|----------|
|
|
279
|
-
| `auto` | Auto-detect client from headers | Universal (recommended for HTTP) |
|
|
280
|
-
| `mcp` | Model Context Protocol (stdio) | Claude Desktop, Cursor, Cline |
|
|
281
|
-
| `rest` | REST API (HTTP) | Any HTTP client, custom integrations |
|
|
282
|
-
| `openai` | OpenAI function calling format | ChatGPT, GPT-4 API, OpenAI-compatible tools |
|
|
283
|
-
| `gemini` | Google function calling format | Gemini, Google AI |
|
|
284
|
-
| `all` | All HTTP protocols on same port | Multiple clients |
|
|
285
|
-
|
|
286
|
-
```bash
|
|
287
|
-
envcp serve [options]
|
|
288
|
-
--mode, -m Server mode: mcp, rest, openai, gemini, all, auto
|
|
289
|
-
--port HTTP port (default: 3456)
|
|
290
|
-
--host HTTP host (default: 127.0.0.1)
|
|
291
|
-
--api-key, -k API key for authentication
|
|
292
|
-
--password, -p Encryption password
|
|
293
|
-
```
|
|
77
|
+
## Quick Start
|
|
294
78
|
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
| Platform | Support | Protocol |
|
|
298
|
-
|----------|---------|----------|
|
|
299
|
-
| Claude Desktop | Native | MCP |
|
|
300
|
-
| Claude Code | Native | MCP |
|
|
301
|
-
| Cursor | Native | MCP |
|
|
302
|
-
| Cline (VS Code) | Native | MCP |
|
|
303
|
-
| Continue.dev | Native | MCP |
|
|
304
|
-
| Zed Editor | Native | MCP |
|
|
305
|
-
| ChatGPT | Via API | OpenAI Function Calling |
|
|
306
|
-
| GPT-4 API | Via API | OpenAI Function Calling |
|
|
307
|
-
| Gemini | Via API | Google Function Calling |
|
|
308
|
-
| Gemini API | Via API | Google Function Calling |
|
|
309
|
-
| Local LLMs (Ollama) | Via API | REST / OpenAI-compatible |
|
|
310
|
-
| LM Studio | Via API | REST / OpenAI-compatible |
|
|
311
|
-
| Open WebUI | Via API | REST |
|
|
312
|
-
| Any HTTP Client | Via API | REST |
|
|
313
|
-
|
|
314
|
-
## Available Tools
|
|
315
|
-
|
|
316
|
-
All protocols expose the same tools:
|
|
317
|
-
|
|
318
|
-
| Tool | Description |
|
|
319
|
-
|------|-------------|
|
|
320
|
-
| `envcp_list` | List variable names (not values) |
|
|
321
|
-
| `envcp_get` | Get a variable (masked by default, `variable_password` required for protected vars) |
|
|
322
|
-
| `envcp_set` | Create/update a variable (supports `protect`, `unprotect`, `variable_password`) |
|
|
323
|
-
| `envcp_delete` | Delete a variable |
|
|
324
|
-
| `envcp_sync` | Sync to .env file |
|
|
325
|
-
| `envcp_run` | Run command with env vars injected |
|
|
326
|
-
| `envcp_check_access` | Check if variable is accessible |
|
|
327
|
-
|
|
328
|
-
## Global Vault
|
|
329
|
-
|
|
330
|
-
Share secrets across multiple projects with a global vault at `~/.envcp/store.enc`:
|
|
79
|
+
Install and initialize:
|
|
331
80
|
|
|
332
81
|
```bash
|
|
333
|
-
|
|
334
|
-
envcp vault
|
|
335
|
-
|
|
336
|
-
# Add a shared secret
|
|
337
|
-
envcp vault --global add SHARED_API_KEY --value "secret123"
|
|
338
|
-
|
|
339
|
-
# Switch to global vault
|
|
340
|
-
envcp vault-switch global
|
|
341
|
-
|
|
342
|
-
# List all vaults
|
|
343
|
-
envcp vault-list
|
|
82
|
+
npm install -g @fentz26/envcp
|
|
83
|
+
envcp init # project vault: ./envcp.yaml + ./.envcp/
|
|
84
|
+
# or: envcp init --global # global vault: ~/.envcp/config.yaml + ~/.envcp/
|
|
344
85
|
```
|
|
345
86
|
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
Create separate vaults for different contexts:
|
|
87
|
+
Add your secrets (you'll set a vault password on first use):
|
|
349
88
|
|
|
350
89
|
```bash
|
|
351
|
-
|
|
352
|
-
envcp vault --name work init
|
|
353
|
-
envcp vault --name work add WORK_API_KEY --value "work-secret"
|
|
354
|
-
|
|
355
|
-
# Switch between vaults
|
|
356
|
-
envcp vault-switch work
|
|
357
|
-
envcp vault-switch project # Back to project vault
|
|
90
|
+
envcp add API_KEY --value "your-secret-key"
|
|
358
91
|
```
|
|
359
92
|
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
Add an extra layer of security with per-variable passwords:
|
|
93
|
+
Start the MCP server for AI tools:
|
|
363
94
|
|
|
364
95
|
```bash
|
|
365
|
-
|
|
366
|
-
envcp_set name=SECRET value=mysecret protect=true variable_password=mypass
|
|
367
|
-
|
|
368
|
-
# Get a protected variable (requires password)
|
|
369
|
-
envcp_get name=SECRET variable_password=mypass
|
|
370
|
-
|
|
371
|
-
# Remove protection
|
|
372
|
-
envcp_set name=SECRET unprotect=true variable_password=mypass
|
|
373
|
-
```
|
|
374
|
-
|
|
375
|
-
Protected variables use Argon2id + AES-256-GCM encryption with a variable-specific key.
|
|
376
|
-
|
|
377
|
-
## Configuration (envcp.yaml)
|
|
378
|
-
|
|
379
|
-
```yaml
|
|
380
|
-
version: "1.0"
|
|
381
|
-
project: my-project
|
|
382
|
-
|
|
383
|
-
# Vault configuration
|
|
384
|
-
vault:
|
|
385
|
-
default: project # or "global" to use global vault by default
|
|
386
|
-
global_path: .envcp/store.enc # path relative to home directory
|
|
387
|
-
|
|
388
|
-
storage:
|
|
389
|
-
path: .envcp/store.enc
|
|
390
|
-
encrypted: true
|
|
391
|
-
algorithm: aes-256-gcm
|
|
392
|
-
|
|
393
|
-
session:
|
|
394
|
-
enabled: true
|
|
395
|
-
timeout_minutes: 30
|
|
396
|
-
max_extensions: 5
|
|
397
|
-
|
|
398
|
-
access:
|
|
399
|
-
allow_ai_read: true
|
|
400
|
-
allow_ai_write: false
|
|
401
|
-
allow_ai_active_check: false # Prevent AI from proactively listing
|
|
402
|
-
require_variable_password: false # Require password for all protected variables
|
|
403
|
-
require_confirmation: true
|
|
404
|
-
blacklist_patterns:
|
|
405
|
-
- "*_SECRET"
|
|
406
|
-
- "*_PRIVATE"
|
|
407
|
-
- "ADMIN_*"
|
|
408
|
-
|
|
409
|
-
password:
|
|
410
|
-
min_length: 8 # Default minimum
|
|
411
|
-
require_complexity: false
|
|
412
|
-
allow_numeric_only: false
|
|
413
|
-
|
|
414
|
-
sync:
|
|
415
|
-
enabled: true
|
|
416
|
-
target: .env
|
|
417
|
-
exclude:
|
|
418
|
-
- "*_PRIVATE"
|
|
419
|
-
- "*_SECRET"
|
|
420
|
-
```
|
|
421
|
-
|
|
422
|
-
## AI Access Control
|
|
423
|
-
|
|
424
|
-
### Disable Active Checking
|
|
425
|
-
|
|
426
|
-
Prevent AI from proactively listing your variables:
|
|
427
|
-
|
|
428
|
-
```yaml
|
|
429
|
-
access:
|
|
430
|
-
allow_ai_active_check: false
|
|
431
|
-
```
|
|
432
|
-
|
|
433
|
-
### Blacklist Patterns
|
|
434
|
-
|
|
435
|
-
Block AI from accessing sensitive variables:
|
|
436
|
-
|
|
437
|
-
```yaml
|
|
438
|
-
access:
|
|
439
|
-
blacklist_patterns:
|
|
440
|
-
- "*_SECRET"
|
|
441
|
-
- "*_PRIVATE"
|
|
442
|
-
- "ADMIN_*"
|
|
443
|
-
- "ROOT_*"
|
|
96
|
+
envcp serve
|
|
444
97
|
```
|
|
445
98
|
|
|
446
|
-
|
|
99
|
+
`envcp serve` walks up from the current directory looking for an
|
|
100
|
+
`envcp.yaml`; if none is found, it falls back to `~/.envcp/config.yaml`.
|
|
101
|
+
This means MCP clients launched from arbitrary working directories will
|
|
102
|
+
still find the vault and an active session. Use `--global` to skip the
|
|
103
|
+
project lookup entirely.
|
|
447
104
|
|
|
448
|
-
|
|
105
|
+
Your AI can now **reference** secrets by name without ever seeing the values. Full guide: [SETUP.md](SETUP.md)
|
|
449
106
|
|
|
450
|
-
|
|
451
|
-
- **Key Derivation**: Argon2id (64 MB memory, 3 passes, parallelism 1)
|
|
452
|
-
- **Salt**: 16 bytes per encryption (random)
|
|
453
|
-
- **IV**: 16 bytes per encryption (random)
|
|
454
|
-
- **Auth Tag**: 16 bytes for integrity verification
|
|
455
|
-
- **Legacy**: existing v1 stores (PBKDF2) are automatically read and re-encrypted on next write
|
|
456
|
-
|
|
457
|
-
### MCP (stdio) Authentication
|
|
458
|
-
|
|
459
|
-
The MCP server runs over stdio — it is only accessible to processes on your local machine that spawn it. No network port is opened in MCP mode; security is enforced by OS process isolation.
|
|
107
|
+
---
|
|
460
108
|
|
|
461
|
-
|
|
109
|
+
## Documentation
|
|
462
110
|
|
|
463
|
-
|
|
111
|
+
| Guide | Description |
|
|
112
|
+
|-------|-------------|
|
|
113
|
+
| [Setup Guide](SETUP.md) | Installation, CLI reference, integrations, configuration |
|
|
114
|
+
| [Verification](VERIFICATION.md) | SLSA 3 provenance verification — npm, GitHub CLI, slsa-verifier |
|
|
115
|
+
| [Security Policy](SECURITY.md) | Vulnerability reporting, encryption details, best practices |
|
|
464
116
|
|
|
465
|
-
|
|
466
|
-
envcp serve --mode rest --api-key your-secret-key
|
|
467
|
-
```
|
|
117
|
+
---
|
|
468
118
|
|
|
469
|
-
|
|
119
|
+
## Security & Supply Chain
|
|
470
120
|
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
121
|
+
- **SLSA Level 3** — Build provenance for supply chain integrity ([verify →](VERIFICATION.md))
|
|
122
|
+
- **Encrypted at rest** — AES-256-GCM with Argon2id key derivation
|
|
123
|
+
- **Local-only** — Your secrets never leave your machine
|
|
124
|
+
- **SHA-pinned CI** — All GitHub Actions pinned to immutable commit SHAs
|
|
125
|
+
- **Signed npm releases** — `npm audit signatures` verifiable from v1.2.0+
|
|
476
126
|
|
|
477
|
-
## Best Practices
|
|
478
127
|
|
|
479
|
-
1. **Never commit `.envcp/`** — Add to `.gitignore`
|
|
480
|
-
2. **Use API keys for HTTP modes** — Protect your server endpoints
|
|
481
|
-
3. **Disable `allow_ai_active_check`** — Prevent AI from probing for variables
|
|
482
|
-
4. **Use blacklist patterns** — Block sensitive variable patterns
|
|
483
|
-
5. **Use `auto` mode for HTTP** — Let EnvCP detect the client type
|
|
484
|
-
6. **Review access logs** — Check `.envcp/logs/` regularly
|
|
485
128
|
|
|
486
129
|
## License
|
|
487
130
|
|
|
488
|
-
SAL v1.0 — See LICENSE file for details.
|
|
131
|
+
SAL v1.0 — See [LICENSE](LICENSE) file for details.
|
|
489
132
|
|
|
490
133
|
## Support
|
|
491
|
-
|
|
134
|
+
|
|
135
|
+
- Email: contact@envcp.org
|
|
492
136
|
- GitHub Issues: https://github.com/fentz26/EnvCP/issues
|
|
493
|
-
- Documentation: https://envcp.
|
|
137
|
+
- Documentation: https://envcp.org/docs
|
package/VERSION
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
1.2.0-exp.772c5eb
|
package/dist/adapters/base.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { StorageManager, LogManager } from '../storage/index.js';
|
|
2
|
-
import { EnvCPConfig, ToolDefinition } from '../types.js';
|
|
2
|
+
import { EnvCPConfig, ToolDefinition, LogsRole } from '../types.js';
|
|
3
3
|
import { SessionManager } from '../utils/session.js';
|
|
4
4
|
export declare abstract class BaseAdapter {
|
|
5
5
|
protected storage: StorageManager;
|
|
@@ -8,13 +8,28 @@ export declare abstract class BaseAdapter {
|
|
|
8
8
|
protected config: EnvCPConfig;
|
|
9
9
|
protected projectPath: string;
|
|
10
10
|
protected tools: Map<string, ToolDefinition>;
|
|
11
|
-
constructor(config: EnvCPConfig, projectPath: string, password?: string, vaultPath?: string);
|
|
11
|
+
constructor(config: EnvCPConfig, projectPath: string, password?: string, vaultPath?: string, sessionPath?: string);
|
|
12
12
|
protected abstract registerTools(): void;
|
|
13
13
|
protected registerDefaultTools(): void;
|
|
14
|
+
protected readLogs(args: {
|
|
15
|
+
date?: string;
|
|
16
|
+
operation?: string;
|
|
17
|
+
variable?: string;
|
|
18
|
+
source?: string;
|
|
19
|
+
success?: boolean;
|
|
20
|
+
tail?: number;
|
|
21
|
+
}): Promise<{
|
|
22
|
+
entries: import('../types.js').OperationLog[];
|
|
23
|
+
count: number;
|
|
24
|
+
role: LogsRole;
|
|
25
|
+
}>;
|
|
14
26
|
init(): Promise<void>;
|
|
15
27
|
protected ensurePassword(): Promise<void>;
|
|
16
28
|
getToolDefinitions(): ToolDefinition[];
|
|
17
|
-
|
|
29
|
+
protected currentClientId: string;
|
|
30
|
+
callTool(name: string, params: Record<string, unknown>, clientId?: string): Promise<unknown>;
|
|
31
|
+
protected resolveLogsRole(clientId: string): LogsRole;
|
|
32
|
+
protected logEvent(entry: import('../types.js').OperationLog): Promise<void>;
|
|
18
33
|
protected listVariables(args: {
|
|
19
34
|
tags?: string[];
|
|
20
35
|
}): Promise<{
|
|
@@ -54,6 +69,7 @@ export declare abstract class BaseAdapter {
|
|
|
54
69
|
success: boolean;
|
|
55
70
|
message: string;
|
|
56
71
|
}>;
|
|
72
|
+
private canonicalizeEnvPath;
|
|
57
73
|
protected syncToEnv(): Promise<{
|
|
58
74
|
success: boolean;
|
|
59
75
|
message: string;
|
|
@@ -74,6 +90,18 @@ export declare abstract class BaseAdapter {
|
|
|
74
90
|
}>;
|
|
75
91
|
private parseCommand;
|
|
76
92
|
private validateCommand;
|
|
93
|
+
/**
|
|
94
|
+
* Detects destructive rm invocations targeting the root filesystem.
|
|
95
|
+
* Checks for recursive (-r/--recursive) + any arg that resolves to /, including
|
|
96
|
+
* path-equivalent variants like //, /./, /../ (normalized before comparison).
|
|
97
|
+
*/
|
|
98
|
+
private checkRootDelete;
|
|
99
|
+
/**
|
|
100
|
+
* Validates that a critical environment variable value is safe.
|
|
101
|
+
* Rejects HOME/TMPDIR set to root, and PATH entries containing `..` as a path segment.
|
|
102
|
+
* OWASP A01:2025 – CWE-22 (Path Traversal) via environment variable manipulation
|
|
103
|
+
*/
|
|
104
|
+
private validateEnvVarValue;
|
|
77
105
|
protected runCommand(args: {
|
|
78
106
|
command: string;
|
|
79
107
|
variables: string[];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"base.d.ts","sourceRoot":"","sources":["../../src/adapters/base.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,UAAU,
|
|
1
|
+
{"version":3,"file":"base.d.ts","sourceRoot":"","sources":["../../src/adapters/base.ts"],"names":[],"mappings":"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"}
|