envpkt 0.2.0 → 0.4.0
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 +245 -144
- package/dist/cli.js +656 -297
- package/dist/index.d.ts +54 -7
- package/dist/index.js +215 -80
- package/package.json +1 -1
- package/schemas/envpkt.schema.json +42 -3
package/README.md
CHANGED
|
@@ -3,25 +3,60 @@
|
|
|
3
3
|
[](https://github.com/jordanburke/envpkt/actions/workflows/node.js.yml)
|
|
4
4
|
[](https://www.npmjs.com/package/envpkt)
|
|
5
5
|
|
|
6
|
-
|
|
6
|
+
**Credentials your agents actually understand.**
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
Structured metadata for every secret — capabilities, constraints, expiration, and fleet health — so agents operate within their boundaries instead of flying blind.
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
Every credential in your system gets an `envpkt.toml` entry describing _what service it authenticates to_, _what it's allowed to do_, _when it expires_, and _how to rotate it_. Your agents query this metadata via MCP to understand their operating constraints. Your operators audit credential health across entire agent fleets. The secrets themselves stay where they belong — in your secrets manager, encrypted at rest, or injected at runtime — never in the agent's conversation context.
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
## MCP Integration
|
|
13
13
|
|
|
14
|
-
|
|
15
|
-
- Get warnings before secrets expire
|
|
16
|
-
- Detect stale or orphaned credentials
|
|
17
|
-
- Understand what capabilities each secret grants
|
|
18
|
-
- Automate rotation workflows
|
|
19
|
-
- Share secret metadata across agents via a central catalog
|
|
14
|
+
envpkt ships an [MCP](https://modelcontextprotocol.io/) server that gives AI agents structured awareness of their credentials. Add it to Claude, Cursor, VS Code, or any MCP-compatible client:
|
|
20
15
|
|
|
21
|
-
|
|
16
|
+
```json
|
|
17
|
+
{
|
|
18
|
+
"mcpServers": {
|
|
19
|
+
"envpkt": {
|
|
20
|
+
"command": "envpkt",
|
|
21
|
+
"args": ["mcp"]
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
### Tools
|
|
28
|
+
|
|
29
|
+
| Tool | Description |
|
|
30
|
+
| ------------------ | ------------------------------------------------------- |
|
|
31
|
+
| `getPacketHealth` | Get overall health status with per-secret audit results |
|
|
32
|
+
| `listCapabilities` | List agent and per-secret capabilities |
|
|
33
|
+
| `getSecretMeta` | Get metadata for a specific secret by key |
|
|
34
|
+
| `checkExpiration` | Check expiration status and days remaining |
|
|
35
|
+
| `getEnvMeta` | Get metadata for environment defaults and drift status |
|
|
36
|
+
|
|
37
|
+
### Resources
|
|
38
|
+
|
|
39
|
+
| URI | Description |
|
|
40
|
+
| ----------------------- | --------------------------------- |
|
|
41
|
+
| `envpkt://health` | Current credential health summary |
|
|
42
|
+
| `envpkt://capabilities` | Agent and secret capabilities |
|
|
43
|
+
|
|
44
|
+
The MCP server exposes metadata only — it does not have access to secret values. See [Security Model](#security-model) for details.
|
|
45
|
+
|
|
46
|
+
## Security Model
|
|
47
|
+
|
|
48
|
+
envpkt operates a three-tier trust model. Each tier has different guarantees, and we're explicit about what each one protects against.
|
|
49
|
+
|
|
50
|
+
**Tier 1: MCP metadata (agent-facing)** — The MCP server never returns raw credential values. This isn't a policy choice — architecturally, the server reads `envpkt.toml` which contains metadata (service names, capabilities, expiration dates, rotation URLs) but never plaintext secrets. The agent gets structured awareness of its constraints without any secret material entering the LLM context window. Prompt injection attacks cannot leak what isn't there.
|
|
51
|
+
|
|
52
|
+
**Tier 2: Runtime injection (process-facing)** — `boot()` resolves secrets (from sealed packets, fnox, or environment variables) and injects them into `process.env` at startup, outside the LLM context. This is the same trust model as every Node.js application that reads from `.env`, except now secrets are encrypted at rest, scoped per-agent, and auditable. This is defense-in-depth against prompt injection — the most common attack vector — but it is not a hard boundary against agents with code execution capabilities.
|
|
53
|
+
|
|
54
|
+
**Tier 3: Shell-level agents** — Agents with shell access (Claude Code, Devin, etc.) can read environment variables directly. Prevention isn't possible at this tier. envpkt provides encrypted storage, scoped access, and audit trails — because when prevention isn't possible, visibility is what matters.
|
|
22
55
|
|
|
23
56
|
## Quick Start
|
|
24
57
|
|
|
58
|
+
Start where your credentials already are — environment variables — and graduate to encrypted, per-agent-scoped metadata.
|
|
59
|
+
|
|
25
60
|
```bash
|
|
26
61
|
# Install
|
|
27
62
|
npm install -g envpkt
|
|
@@ -51,7 +86,7 @@ Every project gets one `envpkt.toml` that describes its credentials. Here's a mi
|
|
|
51
86
|
|
|
52
87
|
version = 1
|
|
53
88
|
|
|
54
|
-
[
|
|
89
|
+
[secret.API_KEY]
|
|
55
90
|
service = "stripe"
|
|
56
91
|
```
|
|
57
92
|
|
|
@@ -74,7 +109,7 @@ stale_warning_days = 90
|
|
|
74
109
|
require_expiration = true
|
|
75
110
|
require_service = true
|
|
76
111
|
|
|
77
|
-
[
|
|
112
|
+
[secret.STRIPE_SECRET_KEY]
|
|
78
113
|
service = "stripe"
|
|
79
114
|
purpose = "Process customer payments and manage subscriptions"
|
|
80
115
|
capabilities = ["charges:write", "subscriptions:write"]
|
|
@@ -83,7 +118,7 @@ expires = "2027-01-15"
|
|
|
83
118
|
rotation_url = "https://dashboard.stripe.com/apikeys"
|
|
84
119
|
source = "vault"
|
|
85
120
|
|
|
86
|
-
[
|
|
121
|
+
[secret.DATABASE_URL]
|
|
87
122
|
service = "postgres"
|
|
88
123
|
purpose = "Read/write access to the billing database"
|
|
89
124
|
capabilities = ["SELECT", "INSERT", "UPDATE"]
|
|
@@ -93,13 +128,81 @@ rotation_url = "https://wiki.internal/runbooks/rotate-db-creds"
|
|
|
93
128
|
source = "vault"
|
|
94
129
|
```
|
|
95
130
|
|
|
131
|
+
For non-secret configuration defaults (runtime mode, log levels, etc.), use `[env.*]`:
|
|
132
|
+
|
|
133
|
+
```toml
|
|
134
|
+
[env.NODE_ENV]
|
|
135
|
+
value = "production"
|
|
136
|
+
purpose = "Runtime environment mode"
|
|
137
|
+
comment = "Override to 'development' for local testing"
|
|
138
|
+
|
|
139
|
+
[env.LOG_LEVEL]
|
|
140
|
+
value = "info"
|
|
141
|
+
purpose = "Application log verbosity"
|
|
142
|
+
```
|
|
143
|
+
|
|
96
144
|
See [`examples/`](./examples/) for more configurations.
|
|
97
145
|
|
|
98
|
-
##
|
|
146
|
+
## Sealed Packets
|
|
147
|
+
|
|
148
|
+
Sealed packets embed age-encrypted secret values directly in `envpkt.toml`. This makes your config fully self-contained — no external secrets backend needed at runtime.
|
|
149
|
+
|
|
150
|
+
### Setup
|
|
151
|
+
|
|
152
|
+
```bash
|
|
153
|
+
# Generate an age keypair
|
|
154
|
+
age-keygen -o identity.txt
|
|
155
|
+
# public key: age1ql3z7hjy54pw3hyww5ayyfg7zqgvc7w3j2elw8zmrj2kg5sfn9aqmcac8p
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
Add the public key to your config and the identity file to `.gitignore`:
|
|
159
|
+
|
|
160
|
+
```toml
|
|
161
|
+
[agent]
|
|
162
|
+
name = "my-agent"
|
|
163
|
+
recipient = "age1ql3z7hjy54pw3hyww5ayyfg7zqgvc7w3j2elw8zmrj2kg5sfn9aqmcac8p"
|
|
164
|
+
identity = "identity.txt"
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
The `identity` path supports `~` expansion and environment variables (`$VAR`, `${VAR}`), so you can use paths like `~/keys/identity.txt` or `$KEYS_DIR/identity.txt`. Relative paths are resolved from the config file's directory.
|
|
168
|
+
|
|
169
|
+
### Seal
|
|
170
|
+
|
|
171
|
+
```bash
|
|
172
|
+
envpkt seal
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
Each secret gets an `encrypted_value` field with age-armored ciphertext. The TOML (including ciphertext) is safe to commit.
|
|
176
|
+
|
|
177
|
+
### Boot
|
|
178
|
+
|
|
179
|
+
At runtime, sealed values are automatically decrypted:
|
|
180
|
+
|
|
181
|
+
```typescript
|
|
182
|
+
import { boot } from "envpkt"
|
|
183
|
+
|
|
184
|
+
const result = boot() // decrypts sealed values, injects into process.env
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
Mixed mode is supported — sealed values take priority, with fnox as fallback for keys without `encrypted_value`.
|
|
188
|
+
|
|
189
|
+
## Fleet Management
|
|
190
|
+
|
|
191
|
+
When you're running multiple agents, `envpkt fleet` scans a directory tree for `envpkt.toml` files and aggregates credential health across your entire fleet.
|
|
192
|
+
|
|
193
|
+
```bash
|
|
194
|
+
envpkt fleet # Scan current directory (depth 3)
|
|
195
|
+
envpkt fleet -d /opt/agents # Scan specific directory
|
|
196
|
+
envpkt fleet --depth 5 # Increase scan depth
|
|
197
|
+
envpkt fleet --format json # JSON output
|
|
198
|
+
envpkt fleet --status critical # Filter agents by health status
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
### Shared Catalog
|
|
99
202
|
|
|
100
203
|
When multiple agents consume the same secrets, a **shared catalog** prevents metadata duplication. Define secret metadata once in a central file, then have each agent reference it.
|
|
101
204
|
|
|
102
|
-
|
|
205
|
+
#### Catalog file (`infra/envpkt.toml`)
|
|
103
206
|
|
|
104
207
|
```toml
|
|
105
208
|
version = 1
|
|
@@ -108,7 +211,7 @@ version = 1
|
|
|
108
211
|
stale_warning_days = 90
|
|
109
212
|
require_expiration = true
|
|
110
213
|
|
|
111
|
-
[
|
|
214
|
+
[secret.DATABASE_URL]
|
|
112
215
|
service = "postgres"
|
|
113
216
|
purpose = "Primary application database"
|
|
114
217
|
capabilities = ["SELECT", "INSERT", "UPDATE", "DELETE"]
|
|
@@ -117,14 +220,14 @@ source = "vault"
|
|
|
117
220
|
created = "2025-11-01"
|
|
118
221
|
expires = "2026-11-01"
|
|
119
222
|
|
|
120
|
-
[
|
|
223
|
+
[secret.REDIS_URL]
|
|
121
224
|
service = "redis"
|
|
122
225
|
purpose = "Caching and session storage"
|
|
123
226
|
created = "2025-11-01"
|
|
124
227
|
expires = "2026-11-01"
|
|
125
228
|
```
|
|
126
229
|
|
|
127
|
-
|
|
230
|
+
#### Agent file (`agents/pipeline/envpkt.toml`)
|
|
128
231
|
|
|
129
232
|
```toml
|
|
130
233
|
version = 1
|
|
@@ -136,11 +239,11 @@ consumer = "agent"
|
|
|
136
239
|
secrets = ["DATABASE_URL", "REDIS_URL"]
|
|
137
240
|
|
|
138
241
|
# Optional: narrow the catalog definition for this agent
|
|
139
|
-
[
|
|
242
|
+
[secret.DATABASE_URL]
|
|
140
243
|
capabilities = ["SELECT"]
|
|
141
244
|
```
|
|
142
245
|
|
|
143
|
-
|
|
246
|
+
#### Resolve to a flat config
|
|
144
247
|
|
|
145
248
|
```bash
|
|
146
249
|
envpkt resolve -c agents/pipeline/envpkt.toml
|
|
@@ -148,54 +251,32 @@ envpkt resolve -c agents/pipeline/envpkt.toml
|
|
|
148
251
|
|
|
149
252
|
This produces a self-contained config with catalog metadata merged in and agent overrides applied. The resolved output has no `catalog` reference — it's ready for deployment.
|
|
150
253
|
|
|
151
|
-
|
|
254
|
+
#### Merge rules
|
|
152
255
|
|
|
153
|
-
- Each field in the agent's `[
|
|
256
|
+
- Each field in the agent's `[secret.KEY]` override **replaces** the catalog field (shallow merge)
|
|
154
257
|
- Omitted fields keep the catalog value
|
|
155
258
|
- `agent.secrets` is the source of truth for which keys the agent needs
|
|
156
259
|
|
|
157
|
-
##
|
|
260
|
+
## How envpkt Compares
|
|
158
261
|
|
|
159
|
-
|
|
262
|
+
The agentic credential space is splitting into approaches. Here's where envpkt fits:
|
|
160
263
|
|
|
161
|
-
|
|
264
|
+
| | envpkt | agent-vault | AgentSecrets | 1Password Agentic | Infisical |
|
|
265
|
+
| --------------------------- | ----------------------------------------------------------- | --------------------------- | -------------------------- | ----------------------------- | -------------------- |
|
|
266
|
+
| **Core approach** | Metadata sidecar | Git-based secret storage | Proxy injection | Browser autofill | Secret retrieval API |
|
|
267
|
+
| **What agents see** | Structured metadata (capabilities, constraints, expiration) | Raw secret values | Nothing (proxy handles it) | Nothing (autofill handles it) | Raw secret values |
|
|
268
|
+
| **MCP server** | Yes | Yes | No | No | Yes |
|
|
269
|
+
| **Encryption at rest** | age sealed packets | Git-crypt | N/A (proxy model) | Vault encryption | Vault encryption |
|
|
270
|
+
| **Per-agent scoping** | Yes (agent.secrets, capabilities) | Yes (policies) | Yes (proxy rules) | No | Yes (policies) |
|
|
271
|
+
| **Fleet health monitoring** | Yes (fleet scan, aggregated audit) | No | No | No | No |
|
|
272
|
+
| **Credential metadata** | Rich (purpose, capabilities, rotation, lifecycle) | Minimal | Minimal | Minimal | Moderate |
|
|
273
|
+
| **Adoption path** | Scan existing env vars, add metadata incrementally | New secret storage workflow | Proxy configuration | Browser extension | API integration |
|
|
162
274
|
|
|
163
|
-
|
|
164
|
-
# Generate an age keypair
|
|
165
|
-
age-keygen -o identity.txt
|
|
166
|
-
# public key: age1ql3z7hjy54pw3hyww5ayyfg7zqgvc7w3j2elw8zmrj2kg5sfn9aqmcac8p
|
|
167
|
-
```
|
|
275
|
+
**envpkt's angle**: Competitors are fighting over how secrets move — retrieval vs. proxy vs. autofill. envpkt owns what secrets _mean_. Rate limits, expiration policies, capability scopes, rotation runbooks — structured semantics that travel with the credential. That's the layer the others don't have.
|
|
168
276
|
|
|
169
|
-
|
|
277
|
+
> **Note**: This comparison reflects publicly available information. Verify current feature sets before making procurement decisions.
|
|
170
278
|
|
|
171
|
-
|
|
172
|
-
[agent]
|
|
173
|
-
name = "my-agent"
|
|
174
|
-
recipient = "age1ql3z7hjy54pw3hyww5ayyfg7zqgvc7w3j2elw8zmrj2kg5sfn9aqmcac8p"
|
|
175
|
-
identity = "identity.txt"
|
|
176
|
-
```
|
|
177
|
-
|
|
178
|
-
### Seal
|
|
179
|
-
|
|
180
|
-
```bash
|
|
181
|
-
envpkt seal
|
|
182
|
-
```
|
|
183
|
-
|
|
184
|
-
Each secret gets an `encrypted_value` field with age-armored ciphertext. The TOML (including ciphertext) is safe to commit.
|
|
185
|
-
|
|
186
|
-
### Boot
|
|
187
|
-
|
|
188
|
-
At runtime, sealed values are automatically decrypted:
|
|
189
|
-
|
|
190
|
-
```typescript
|
|
191
|
-
import { boot } from "envpkt"
|
|
192
|
-
|
|
193
|
-
const result = boot() // decrypts sealed values, injects into process.env
|
|
194
|
-
```
|
|
195
|
-
|
|
196
|
-
Mixed mode is supported — sealed values take priority, with fnox as fallback for keys without `encrypted_value`.
|
|
197
|
-
|
|
198
|
-
## CLI Commands
|
|
279
|
+
## CLI Reference
|
|
199
280
|
|
|
200
281
|
### `envpkt init`
|
|
201
282
|
|
|
@@ -237,18 +318,6 @@ envpkt resolve -c agent.toml --dry-run # Preview without writing
|
|
|
237
318
|
|
|
238
319
|
Configs without a `catalog` field pass through unchanged.
|
|
239
320
|
|
|
240
|
-
### `envpkt fleet`
|
|
241
|
-
|
|
242
|
-
Scan a directory tree for `envpkt.toml` files and aggregate health.
|
|
243
|
-
|
|
244
|
-
```bash
|
|
245
|
-
envpkt fleet # Scan current directory (depth 3)
|
|
246
|
-
envpkt fleet -d /opt/agents # Scan specific directory
|
|
247
|
-
envpkt fleet --depth 5 # Increase scan depth
|
|
248
|
-
envpkt fleet --format json # JSON output
|
|
249
|
-
envpkt fleet --status critical # Filter agents by health status
|
|
250
|
-
```
|
|
251
|
-
|
|
252
321
|
### `envpkt inspect`
|
|
253
322
|
|
|
254
323
|
Display a structured view of an `envpkt.toml` file. Automatically resolves catalog references.
|
|
@@ -323,9 +392,30 @@ envpkt env check --strict # Exit non-zero on any drift
|
|
|
323
392
|
envpkt env check -c path/to/envpkt.toml # Specify config path
|
|
324
393
|
```
|
|
325
394
|
|
|
395
|
+
### `envpkt env export`
|
|
396
|
+
|
|
397
|
+
Output `export KEY='VALUE'` statements for sourcing secrets into the current shell. Secrets are resolved via sealed packets and/or fnox — the same pipeline as `envpkt exec`, but instead of spawning a subprocess, the output is designed to be `eval`'d.
|
|
398
|
+
|
|
399
|
+
```bash
|
|
400
|
+
# Source secrets into the current shell
|
|
401
|
+
eval "$(envpkt env export)"
|
|
402
|
+
|
|
403
|
+
# Use a specific fnox profile
|
|
404
|
+
eval "$(envpkt env export --profile staging)"
|
|
405
|
+
|
|
406
|
+
# Specify config path
|
|
407
|
+
eval "$(envpkt env export -c path/to/envpkt.toml)"
|
|
408
|
+
```
|
|
409
|
+
|
|
410
|
+
Add to your shell startup (e.g. `~/.zshrc` or `~/.bashrc`) for automatic secret loading. envpkt's [config discovery chain](#config-resolution) finds your config automatically — no platform-specific shell logic needed:
|
|
411
|
+
|
|
412
|
+
```bash
|
|
413
|
+
eval "$(envpkt env export 2>/dev/null)"
|
|
414
|
+
```
|
|
415
|
+
|
|
326
416
|
### `envpkt shell-hook`
|
|
327
417
|
|
|
328
|
-
Output a shell function that runs `envpkt audit --format minimal` whenever you `cd` into a directory
|
|
418
|
+
Output a shell function that runs `envpkt audit --format minimal` whenever you `cd` into a directory. envpkt's config discovery chain automatically finds config files beyond CWD (see [Config Resolution](#config-resolution)), so the hook works even in directories without a local `envpkt.toml`.
|
|
329
419
|
|
|
330
420
|
```bash
|
|
331
421
|
# Add to your .zshrc
|
|
@@ -343,86 +433,34 @@ Start the envpkt MCP server (stdio transport) for AI agent integration.
|
|
|
343
433
|
envpkt mcp
|
|
344
434
|
```
|
|
345
435
|
|
|
346
|
-
##
|
|
347
|
-
|
|
348
|
-
envpkt ships an [MCP](https://modelcontextprotocol.io/) server that exposes credential metadata to AI agents. Add it to your MCP client config:
|
|
349
|
-
|
|
350
|
-
```json
|
|
351
|
-
{
|
|
352
|
-
"mcpServers": {
|
|
353
|
-
"envpkt": {
|
|
354
|
-
"command": "envpkt",
|
|
355
|
-
"args": ["mcp"]
|
|
356
|
-
}
|
|
357
|
-
}
|
|
358
|
-
}
|
|
359
|
-
```
|
|
436
|
+
## Config Resolution
|
|
360
437
|
|
|
361
|
-
|
|
438
|
+
Commands that read `envpkt.toml` resolve the config path via a priority chain:
|
|
362
439
|
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
440
|
+
1. **Explicit flag** — `-c path/to/envpkt.toml`
|
|
441
|
+
2. **Environment variable** — `ENVPKT_CONFIG`
|
|
442
|
+
3. **Discovery chain** — searches in order:
|
|
443
|
+
- `./envpkt.toml` (current working directory)
|
|
444
|
+
- Custom paths in `ENVPKT_SEARCH_PATH` (colon-separated)
|
|
445
|
+
- `~/.envpkt/envpkt.toml` (user home)
|
|
446
|
+
- Cloud storage paths (OneDrive, iCloud, Dropbox, Google Drive)
|
|
369
447
|
|
|
370
|
-
|
|
448
|
+
When a config is discovered outside CWD, envpkt prints where it loaded from to stderr:
|
|
371
449
|
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
| `envpkt://health` | Current credential health summary |
|
|
375
|
-
| `envpkt://capabilities` | Agent and secret capabilities |
|
|
376
|
-
|
|
377
|
-
No secret values are ever exposed through the MCP server.
|
|
378
|
-
|
|
379
|
-
## Schema
|
|
380
|
-
|
|
381
|
-
envpkt.toml is validated against a JSON Schema. Editors with TOML + JSON Schema support will provide autocompletion and validation when the `#:schema` directive is present on line 1.
|
|
382
|
-
|
|
383
|
-
The schema is published at:
|
|
384
|
-
|
|
385
|
-
- npm: `envpkt/schema` (importable via package exports)
|
|
386
|
-
- GitHub: `schemas/envpkt.schema.json`
|
|
387
|
-
|
|
388
|
-
### Secret Metadata Fields
|
|
389
|
-
|
|
390
|
-
Each `[meta.<KEY>]` section describes a secret:
|
|
391
|
-
|
|
392
|
-
| Tier | Fields | Description |
|
|
393
|
-
| --------------- | ----------------------------------------------- | ------------------------------------------- |
|
|
394
|
-
| **Scan-first** | `service`, `expires`, `rotation_url` | Key health indicators for audit |
|
|
395
|
-
| **Context** | `purpose`, `capabilities`, `created` | Why this secret exists and what it grants |
|
|
396
|
-
| **Operational** | `rotates`, `rate_limit`, `model_hint`, `source` | Runtime and provisioning info |
|
|
397
|
-
| **Sealed** | `encrypted_value` | Age-encrypted secret value (safe to commit) |
|
|
398
|
-
| **Enforcement** | `required`, `tags` | Filtering, grouping, and policy |
|
|
399
|
-
|
|
400
|
-
### Agent Identity
|
|
401
|
-
|
|
402
|
-
The optional `[agent]` section identifies the AI agent:
|
|
403
|
-
|
|
404
|
-
```toml
|
|
405
|
-
[agent]
|
|
406
|
-
name = "data-pipeline-agent"
|
|
407
|
-
consumer = "agent" # agent | service | developer | ci
|
|
408
|
-
description = "ETL pipeline processor"
|
|
409
|
-
capabilities = ["read-s3", "write-postgres"]
|
|
410
|
-
expires = "2027-01-01"
|
|
411
|
-
services = ["aws", "postgres"]
|
|
412
|
-
secrets = ["DATABASE_URL", "AWS_KEY"] # When using a catalog
|
|
450
|
+
```
|
|
451
|
+
envpkt: loaded /Users/you/.envpkt/envpkt.toml
|
|
413
452
|
```
|
|
414
453
|
|
|
415
|
-
###
|
|
454
|
+
### `ENVPKT_SEARCH_PATH`
|
|
416
455
|
|
|
417
|
-
|
|
456
|
+
Prepend custom search locations (colon-separated paths to `envpkt.toml` files):
|
|
418
457
|
|
|
419
|
-
```
|
|
420
|
-
|
|
421
|
-
stale_warning_days = 90 # Flag secrets older than N days without updates
|
|
422
|
-
require_expiration = true # Require expires on all secrets
|
|
423
|
-
require_service = true # Require service on all secrets
|
|
458
|
+
```bash
|
|
459
|
+
export ENVPKT_SEARCH_PATH="$HOME/OneDrive/.envpkt/envpkt.toml:/custom/path/envpkt.toml"
|
|
424
460
|
```
|
|
425
461
|
|
|
462
|
+
These are searched after CWD but before the built-in candidate paths. Useful for corporate OneDrive names, Google Drive with email in the path, or any non-standard location.
|
|
463
|
+
|
|
426
464
|
## Library API
|
|
427
465
|
|
|
428
466
|
envpkt is also available as a TypeScript library with a functional programming API built on [functype](https://github.com/jordanburke/functype). All functions return `Either<Error, Result>` or `Option<T>` — no thrown exceptions.
|
|
@@ -433,6 +471,7 @@ import { boot, bootSafe, loadConfig, computeAudit, scanFleet, resolveConfig } fr
|
|
|
433
471
|
// Boot API — load config, resolve catalog, audit, inject secrets
|
|
434
472
|
const result = boot({ configPath: "envpkt.toml", inject: true })
|
|
435
473
|
console.log(result.audit.status) // "healthy" | "degraded" | "critical"
|
|
474
|
+
console.log(result.configSource) // "flag" | "env" | "cwd" | "search"
|
|
436
475
|
|
|
437
476
|
// Safe variant returns Either instead of throwing
|
|
438
477
|
const safe = bootSafe({ configPath: "envpkt.toml" })
|
|
@@ -461,6 +500,21 @@ const fleet = scanFleet("/opt/agents", { maxDepth: 3 })
|
|
|
461
500
|
console.log(`${fleet.total_agents} agents, ${fleet.total_secrets} secrets`)
|
|
462
501
|
```
|
|
463
502
|
|
|
503
|
+
### Framework Integration
|
|
504
|
+
|
|
505
|
+
`boot()` runs before your agent framework initializes, making it compatible with any framework:
|
|
506
|
+
|
|
507
|
+
```typescript
|
|
508
|
+
import { boot } from "envpkt"
|
|
509
|
+
|
|
510
|
+
// Resolve and inject credentials before agent startup
|
|
511
|
+
const result = boot({ configPath: "envpkt.toml", inject: true })
|
|
512
|
+
console.log(`${result.audit.status} — ${result.injected.length} secrets loaded`)
|
|
513
|
+
|
|
514
|
+
// Now start your agent framework — process.env is populated
|
|
515
|
+
// Works with LangChain, CrewAI, AutoGen, or any framework that reads from process.env
|
|
516
|
+
```
|
|
517
|
+
|
|
464
518
|
### Packet Formatting API
|
|
465
519
|
|
|
466
520
|
```typescript
|
|
@@ -570,11 +624,58 @@ loadConfig(configPath).fold(
|
|
|
570
624
|
)
|
|
571
625
|
```
|
|
572
626
|
|
|
627
|
+
## Schema
|
|
628
|
+
|
|
629
|
+
envpkt.toml is validated against a JSON Schema. Editors with TOML + JSON Schema support will provide autocompletion and validation when the `#:schema` directive is present on line 1.
|
|
630
|
+
|
|
631
|
+
The schema is published at:
|
|
632
|
+
|
|
633
|
+
- npm: `envpkt/schema` (importable via package exports)
|
|
634
|
+
- GitHub: `schemas/envpkt.schema.json`
|
|
635
|
+
|
|
636
|
+
### Secret Metadata Fields
|
|
637
|
+
|
|
638
|
+
Each `[secret.<KEY>]` section describes a secret:
|
|
639
|
+
|
|
640
|
+
| Tier | Fields | Description |
|
|
641
|
+
| --------------- | ----------------------------------------------- | ------------------------------------------- |
|
|
642
|
+
| **Scan-first** | `service`, `expires`, `rotation_url` | Key health indicators for audit |
|
|
643
|
+
| **Context** | `purpose`, `comment`, `capabilities`, `created` | Why this secret exists and what it grants |
|
|
644
|
+
| **Operational** | `rotates`, `rate_limit`, `model_hint`, `source` | Runtime and provisioning info |
|
|
645
|
+
| **Sealed** | `encrypted_value` | Age-encrypted secret value (safe to commit) |
|
|
646
|
+
| **Enforcement** | `required`, `tags` | Filtering, grouping, and policy |
|
|
647
|
+
|
|
648
|
+
### Agent Identity
|
|
649
|
+
|
|
650
|
+
The optional `[agent]` section identifies the AI agent:
|
|
651
|
+
|
|
652
|
+
```toml
|
|
653
|
+
[agent]
|
|
654
|
+
name = "data-pipeline-agent"
|
|
655
|
+
consumer = "agent" # agent | service | developer | ci
|
|
656
|
+
description = "ETL pipeline processor"
|
|
657
|
+
capabilities = ["read-s3", "write-postgres"]
|
|
658
|
+
expires = "2027-01-01"
|
|
659
|
+
services = ["aws", "postgres"]
|
|
660
|
+
secrets = ["DATABASE_URL", "AWS_KEY"] # When using a catalog
|
|
661
|
+
```
|
|
662
|
+
|
|
663
|
+
### Lifecycle Policy
|
|
664
|
+
|
|
665
|
+
The optional `[lifecycle]` section configures audit behavior:
|
|
666
|
+
|
|
667
|
+
```toml
|
|
668
|
+
[lifecycle]
|
|
669
|
+
stale_warning_days = 90 # Flag secrets older than N days without updates
|
|
670
|
+
require_expiration = true # Require expires on all secrets
|
|
671
|
+
require_service = true # Require service on all secrets
|
|
672
|
+
```
|
|
673
|
+
|
|
573
674
|
## fnox Integration
|
|
574
675
|
|
|
575
676
|
envpkt integrates with [fnox](https://github.com/jordanburke/fnox) for secret resolution:
|
|
576
677
|
|
|
577
|
-
- `envpkt init --from-fnox` scaffolds `[
|
|
678
|
+
- `envpkt init --from-fnox` scaffolds `[secret.*]` entries from `fnox.toml`
|
|
578
679
|
- `envpkt audit` detects orphaned keys (in envpkt but not in fnox, or vice versa)
|
|
579
680
|
- `envpkt exec` injects fnox secrets into the subprocess environment
|
|
580
681
|
|