secretless-ai 0.10.0 → 0.10.2
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 +90 -8
- package/dist/backends/keychain-linux.d.ts +1 -0
- package/dist/backends/keychain-linux.d.ts.map +1 -1
- package/dist/backends/keychain-linux.js +63 -21
- package/dist/backends/keychain-linux.js.map +1 -1
- package/dist/backends/keychain-macos.d.ts +1 -0
- package/dist/backends/keychain-macos.d.ts.map +1 -1
- package/dist/backends/keychain-macos.js +69 -22
- package/dist/backends/keychain-macos.js.map +1 -1
- package/dist/backends/onepassword.d.ts +5 -0
- package/dist/backends/onepassword.d.ts.map +1 -1
- package/dist/backends/onepassword.js +41 -16
- package/dist/backends/onepassword.js.map +1 -1
- package/dist/cli.js +85 -6
- package/dist/cli.js.map +1 -1
- package/dist/git-hook.js +1 -1
- package/dist/git-hook.js.map +1 -1
- package/dist/history.d.ts +47 -0
- package/dist/history.d.ts.map +1 -0
- package/dist/history.js +221 -0
- package/dist/history.js.map +1 -0
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -1
- package/dist/index.js.map +1 -1
- package/dist/scan-staged.d.ts.map +1 -1
- package/dist/scan-staged.js +4 -0
- package/dist/scan-staged.js.map +1 -1
- package/dist/scope/aws.d.ts +41 -0
- package/dist/scope/aws.d.ts.map +1 -0
- package/dist/scope/aws.js +434 -0
- package/dist/scope/aws.js.map +1 -0
- package/dist/scope/index.d.ts +2 -1
- package/dist/scope/index.d.ts.map +1 -1
- package/dist/scope/index.js +10 -9
- package/dist/scope/index.js.map +1 -1
- package/dist/setup.d.ts.map +1 -1
- package/dist/setup.js +3 -1
- package/dist/setup.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
|
-
> **[OpenA2A](https://github.com/opena2a-org
|
|
1
|
+
> **[OpenA2A](https://github.com/opena2a-org)**: [CLI](https://github.com/opena2a-org/opena2a) · [HackMyAgent](https://github.com/opena2a-org/hackmyagent) · [AIM](https://github.com/opena2a-org/agent-identity-management) · [Browser Guard](https://github.com/opena2a-org/AI-BrowserGuard) · [DVAA](https://github.com/opena2a-org/damn-vulnerable-ai-agent) · [Registry](https://registry.opena2a.org)
|
|
2
2
|
|
|
3
3
|
# Secretless AI
|
|
4
4
|
|
|
5
5
|
[](https://www.npmjs.com/package/secretless-ai)
|
|
6
6
|
[](https://opensource.org/licenses/Apache-2.0)
|
|
7
7
|
|
|
8
|
+
Every AI coding assistant in your terminal can read `~/.aws/credentials`, `echo $OPENAI_API_KEY`, and access any secret on your machine. Secretless makes secrets invisible to AI context without changing your workflow.
|
|
9
|
+
|
|
8
10
|
One command to keep secrets out of AI LLMs. Works with Claude Code, Cursor, Copilot, Windsurf, Cline, and Aider.
|
|
9
11
|
|
|
10
12
|
```bash
|
|
@@ -240,7 +242,7 @@ npx secretless-ai init
|
|
|
240
242
|
Output:
|
|
241
243
|
|
|
242
244
|
```
|
|
243
|
-
Secretless v0.
|
|
245
|
+
Secretless v0.10.1
|
|
244
246
|
Keeping secrets out of AI
|
|
245
247
|
|
|
246
248
|
Detected:
|
|
@@ -349,6 +351,12 @@ npx secretless-ai hook uninstall # Remove pre-commit hook
|
|
|
349
351
|
| `scope check <NAME>` | Compare current permissions to baseline |
|
|
350
352
|
| `scope list` | Show all scope baselines |
|
|
351
353
|
| `scope reset <NAME>` | Clear a scope baseline |
|
|
354
|
+
| **Shell Integration** | |
|
|
355
|
+
| `env [--only K1,K2]` | Output export statements for stored secrets (use with `eval`) |
|
|
356
|
+
| `scan-staged` | Scan git staged files for secrets (used by pre-commit hook) |
|
|
357
|
+
| **Cache Management** | |
|
|
358
|
+
| `cache clear` | Clear the encrypted secret cache |
|
|
359
|
+
| `cache ttl [DURATION]` | Show or set cache TTL (e.g., `5m`, `1h`, `off`) |
|
|
352
360
|
|
|
353
361
|
## Usage via OpenA2A CLI
|
|
354
362
|
|
|
@@ -372,6 +380,44 @@ opena2a broker start # Start the credential broker daemon
|
|
|
372
380
|
opena2a broker status # Check broker daemon status and connected agents
|
|
373
381
|
```
|
|
374
382
|
|
|
383
|
+
**Policy example** -- define rules in `~/.secretless-ai/broker-policies.json`:
|
|
384
|
+
|
|
385
|
+
```json
|
|
386
|
+
{
|
|
387
|
+
"rules": [
|
|
388
|
+
{
|
|
389
|
+
"id": "scan-agents-read-github",
|
|
390
|
+
"agentSelector": "scan-*",
|
|
391
|
+
"credentialSelector": "GITHUB_*",
|
|
392
|
+
"effect": "allow",
|
|
393
|
+
"constraints": {
|
|
394
|
+
"minTrustScore": 0.7,
|
|
395
|
+
"rateLimit": { "maxPerMinute": 10 },
|
|
396
|
+
"scopeCheck": true
|
|
397
|
+
}
|
|
398
|
+
},
|
|
399
|
+
{
|
|
400
|
+
"id": "deny-all-production-keys",
|
|
401
|
+
"agentSelector": "*",
|
|
402
|
+
"credentialSelector": "PROD_*",
|
|
403
|
+
"effect": "deny",
|
|
404
|
+
"constraints": {}
|
|
405
|
+
}
|
|
406
|
+
]
|
|
407
|
+
}
|
|
408
|
+
```
|
|
409
|
+
|
|
410
|
+
The policy engine is default-deny: deny rules are evaluated first, then allow rules. All constraints must pass for an allow rule to grant access. Supported constraints include `minTrustScore` (AIM trust score), `rateLimit`, `timeWindow`, `requireCapability`, and `scopeCheck` (blocks access if a credential's scope has expanded beyond its baseline).
|
|
411
|
+
|
|
412
|
+
**Request flow:**
|
|
413
|
+
|
|
414
|
+
1. `opena2a broker start` -- starts the broker daemon on a local socket
|
|
415
|
+
2. An agent requests a credential (e.g., `GITHUB_TOKEN`)
|
|
416
|
+
3. The broker verifies the agent's AIM identity token
|
|
417
|
+
4. The policy engine evaluates the request against loaded rules
|
|
418
|
+
5. If allowed, the broker resolves the secret from the configured backend and returns it
|
|
419
|
+
6. If denied, the broker returns an error and logs the attempt to the audit log
|
|
420
|
+
|
|
375
421
|
### Data Loss Prevention (DLP)
|
|
376
422
|
|
|
377
423
|
DLP commands scan AI tool transcripts (conversation logs, shell history, tool output) for accidentally leaked credentials. If an API key, token, or connection string appears in a transcript, DLP flags it so you can rotate the exposed credential.
|
|
@@ -381,6 +427,41 @@ opena2a dlp scan # Scan AI tool transcripts for leaked credentials
|
|
|
381
427
|
opena2a dlp report # Generate a DLP report with findings and remediation steps
|
|
382
428
|
```
|
|
383
429
|
|
|
430
|
+
**Example output from `opena2a dlp scan`:**
|
|
431
|
+
|
|
432
|
+
```
|
|
433
|
+
DLP Transcript Scan
|
|
434
|
+
|
|
435
|
+
Scanning 3 transcript(s)...
|
|
436
|
+
|
|
437
|
+
! claude-code/2026-03-01-project-setup.jsonl
|
|
438
|
+
Line 142: AWS Access Key (AKIA...) — AKIA2EXAMPLE7XRQWZ
|
|
439
|
+
Line 307: Stripe Secret Key (sk_live_...) — sk_live_51J3Example
|
|
440
|
+
|
|
441
|
+
! cursor/composer-history.json
|
|
442
|
+
Line 89: GitHub PAT (ghp_...) — ghp_A1b2C3ExampleToken
|
|
443
|
+
|
|
444
|
+
3 leaked credential(s) found in 2 transcript(s).
|
|
445
|
+
|
|
446
|
+
Rotate these credentials immediately — they have been sent to
|
|
447
|
+
an external API as part of the AI conversation context.
|
|
448
|
+
```
|
|
449
|
+
|
|
450
|
+
Each finding shows the transcript file, line number, credential type, and a truncated value preview. The `opena2a dlp report` command generates a structured report with remediation steps for each finding.
|
|
451
|
+
|
|
452
|
+
### Cross-Product Integration
|
|
453
|
+
|
|
454
|
+
Secretless connects to the wider OpenA2A ecosystem at multiple levels:
|
|
455
|
+
|
|
456
|
+
| Entry Point | Command | What It Does |
|
|
457
|
+
|-------------|---------|--------------|
|
|
458
|
+
| Standalone | `npx secretless-ai init` | Protect AI tool context, manage secrets, encrypt MCP configs |
|
|
459
|
+
| Credential drift | `opena2a protect` | Detect when credential scopes expand beyond their baselines |
|
|
460
|
+
| Credential brokering | `opena2a broker start` | Identity-aware secret injection for AI agents via AIM tokens |
|
|
461
|
+
| Leak detection | `opena2a dlp scan` | Scan transcripts and shell history for exposed credentials |
|
|
462
|
+
|
|
463
|
+
Each layer builds on the previous one. Start with `secretless-ai init` for immediate protection, then add drift detection, brokering, and DLP as your agent deployment grows.
|
|
464
|
+
|
|
384
465
|
### When to Use Which Interface
|
|
385
466
|
|
|
386
467
|
| Use Case | Command |
|
|
@@ -412,7 +493,7 @@ For Claude Code, Secretless installs a PreToolUse hook that intercepts every `Re
|
|
|
412
493
|
|
|
413
494
|
```bash
|
|
414
495
|
npm run build # Compile TypeScript to dist/
|
|
415
|
-
npm test # Run tests (vitest,
|
|
496
|
+
npm test # Run tests (vitest, 677 tests)
|
|
416
497
|
npm run dev # Watch mode — recompile on file changes
|
|
417
498
|
npm run clean # Remove dist/ directory
|
|
418
499
|
```
|
|
@@ -432,11 +513,12 @@ Secretless has zero runtime dependencies.
|
|
|
432
513
|
|
|
433
514
|
| Project | Description | Install |
|
|
434
515
|
|---------|-------------|---------|
|
|
435
|
-
| [**
|
|
436
|
-
| [**HackMyAgent**](https://github.com/opena2a-org/hackmyagent) | Security scanner --
|
|
437
|
-
| [**
|
|
438
|
-
| [**
|
|
439
|
-
| [**DVAA**](https://github.com/opena2a-org/damn-vulnerable-ai-agent) | Damn Vulnerable AI Agent -- security training
|
|
516
|
+
| [**OpenA2A CLI**](https://github.com/opena2a-org/opena2a) | Unified security CLI -- orchestrates all OpenA2A tools | `npx opena2a` |
|
|
517
|
+
| [**HackMyAgent**](https://github.com/opena2a-org/hackmyagent) | Security scanner and red-team toolkit -- checks, attack mode, benchmarks, runtime protection | `npx hackmyagent secure` |
|
|
518
|
+
| [**AIM**](https://github.com/opena2a-org/agent-identity-management) | Agent Identity Management -- identity, access control, and trust scoring for AI agents | Self-hosted |
|
|
519
|
+
| [**AI Browser Guard**](https://github.com/opena2a-org/AI-BrowserGuard) | Browser agent detection and control -- 4-layer detection, delegation engine | Chrome Web Store |
|
|
520
|
+
| [**DVAA**](https://github.com/opena2a-org/damn-vulnerable-ai-agent) | Damn Vulnerable AI Agent -- security training target | `docker pull opena2a/dvaa` |
|
|
521
|
+
| [**Registry**](https://registry.opena2a.org) | Trust registry -- agent discovery, trust scores, supply chain verification | `registry.opena2a.org` |
|
|
440
522
|
|
|
441
523
|
## License
|
|
442
524
|
|
|
@@ -21,6 +21,7 @@ export declare class LinuxKeychainBackend implements WritableSecretBackend {
|
|
|
21
21
|
resolve(secretPath: string): Promise<Record<string, string>>;
|
|
22
22
|
delete(key: string): Promise<boolean>;
|
|
23
23
|
healthCheck(): Promise<BackendHealth>;
|
|
24
|
+
private lookupSecret;
|
|
24
25
|
private readIndex;
|
|
25
26
|
private writeIndex;
|
|
26
27
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"keychain-linux.d.ts","sourceRoot":"","sources":["../../src/backends/keychain-linux.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAKH,OAAO,KAAK,EAAE,qBAAqB,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"keychain-linux.d.ts","sourceRoot":"","sources":["../../src/backends/keychain-linux.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAKH,OAAO,KAAK,EAAE,qBAAqB,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAcpE,qBAAa,oBAAqB,YAAW,qBAAqB;IAChE,QAAQ,CAAC,IAAI,oBAAoB;IACjC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;gBAEvB,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAOtC,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAiChD,OAAO,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAkB5D,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAoCrC,WAAW,IAAI,OAAO,CAAC,aAAa,CAAC;IAkB3C,OAAO,CAAC,YAAY;IAapB,OAAO,CAAC,SAAS;IAUjB,OAAO,CAAC,UAAU;CAKnB"}
|
|
@@ -51,8 +51,16 @@ exports.LinuxKeychainBackend = void 0;
|
|
|
51
51
|
const child_process_1 = require("child_process");
|
|
52
52
|
const fs = __importStar(require("fs"));
|
|
53
53
|
const path = __importStar(require("path"));
|
|
54
|
-
const
|
|
54
|
+
const LEGACY_SERVICE_NAME = 'secretless';
|
|
55
55
|
const INDEX_FILENAME = 'keychain-index.json';
|
|
56
|
+
/**
|
|
57
|
+
* Derive a per-key service name so password managers show a descriptive
|
|
58
|
+
* name instead of "secretless" for every entry.
|
|
59
|
+
*/
|
|
60
|
+
function serviceNameFor(key) {
|
|
61
|
+
const lastSegment = key.split('/').pop() ?? key;
|
|
62
|
+
return `Secretless: ${lastSegment}`;
|
|
63
|
+
}
|
|
56
64
|
class LinuxKeychainBackend {
|
|
57
65
|
constructor(config) {
|
|
58
66
|
this.name = 'keychain-linux';
|
|
@@ -62,11 +70,23 @@ class LinuxKeychainBackend {
|
|
|
62
70
|
this.indexPath = path.join(storeDir, INDEX_FILENAME);
|
|
63
71
|
}
|
|
64
72
|
async store(key, value) {
|
|
73
|
+
const svc = serviceNameFor(key);
|
|
74
|
+
// Delete legacy entry to prevent duplicates
|
|
75
|
+
try {
|
|
76
|
+
(0, child_process_1.execFileSync)('secret-tool', [
|
|
77
|
+
'clear',
|
|
78
|
+
'service', LEGACY_SERVICE_NAME,
|
|
79
|
+
'account', key,
|
|
80
|
+
], { stdio: 'pipe' });
|
|
81
|
+
}
|
|
82
|
+
catch {
|
|
83
|
+
// No legacy entry — that's fine
|
|
84
|
+
}
|
|
65
85
|
// secret-tool store reads the value from stdin
|
|
66
86
|
(0, child_process_1.execFileSync)('secret-tool', [
|
|
67
87
|
'store',
|
|
68
|
-
|
|
69
|
-
'service',
|
|
88
|
+
`--label=Secretless: ${key}`,
|
|
89
|
+
'service', svc,
|
|
70
90
|
'account', key,
|
|
71
91
|
], {
|
|
72
92
|
input: value,
|
|
@@ -84,38 +104,47 @@ class LinuxKeychainBackend {
|
|
|
84
104
|
const matchingKeys = index.filter(k => k === secretPath || k.startsWith(secretPath + '/'));
|
|
85
105
|
const results = {};
|
|
86
106
|
for (const key of matchingKeys) {
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
], { stdio: ['pipe', 'pipe', 'pipe'], encoding: 'utf-8' }).trimEnd();
|
|
93
|
-
if (value) {
|
|
94
|
-
results[key] = value;
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
catch {
|
|
98
|
-
// Key was in index but not in keyring — skip
|
|
107
|
+
// Try new per-key service name first, fall back to legacy
|
|
108
|
+
const value = this.lookupSecret(serviceNameFor(key), key)
|
|
109
|
+
?? this.lookupSecret(LEGACY_SERVICE_NAME, key);
|
|
110
|
+
if (value) {
|
|
111
|
+
results[key] = value;
|
|
99
112
|
}
|
|
100
113
|
}
|
|
101
114
|
return results;
|
|
102
115
|
}
|
|
103
116
|
async delete(key) {
|
|
117
|
+
let deleted = false;
|
|
118
|
+
// Delete new-format entry
|
|
119
|
+
try {
|
|
120
|
+
(0, child_process_1.execFileSync)('secret-tool', [
|
|
121
|
+
'clear',
|
|
122
|
+
'service', serviceNameFor(key),
|
|
123
|
+
'account', key,
|
|
124
|
+
], { stdio: 'pipe' });
|
|
125
|
+
deleted = true;
|
|
126
|
+
}
|
|
127
|
+
catch {
|
|
128
|
+
// Not found with new service name
|
|
129
|
+
}
|
|
130
|
+
// Also delete legacy entry if it exists
|
|
104
131
|
try {
|
|
105
132
|
(0, child_process_1.execFileSync)('secret-tool', [
|
|
106
133
|
'clear',
|
|
107
|
-
'service',
|
|
134
|
+
'service', LEGACY_SERVICE_NAME,
|
|
108
135
|
'account', key,
|
|
109
136
|
], { stdio: 'pipe' });
|
|
110
|
-
|
|
137
|
+
deleted = true;
|
|
138
|
+
}
|
|
139
|
+
catch {
|
|
140
|
+
// No legacy entry
|
|
141
|
+
}
|
|
142
|
+
if (deleted) {
|
|
111
143
|
const index = this.readIndex();
|
|
112
144
|
const filtered = index.filter(k => k !== key);
|
|
113
145
|
this.writeIndex(filtered);
|
|
114
|
-
return true;
|
|
115
|
-
}
|
|
116
|
-
catch {
|
|
117
|
-
return false;
|
|
118
146
|
}
|
|
147
|
+
return deleted;
|
|
119
148
|
}
|
|
120
149
|
async healthCheck() {
|
|
121
150
|
const start = Date.now();
|
|
@@ -135,6 +164,19 @@ class LinuxKeychainBackend {
|
|
|
135
164
|
};
|
|
136
165
|
}
|
|
137
166
|
}
|
|
167
|
+
lookupSecret(service, account) {
|
|
168
|
+
try {
|
|
169
|
+
const value = (0, child_process_1.execFileSync)('secret-tool', [
|
|
170
|
+
'lookup',
|
|
171
|
+
'service', service,
|
|
172
|
+
'account', account,
|
|
173
|
+
], { stdio: ['pipe', 'pipe', 'pipe'], encoding: 'utf-8' }).trimEnd();
|
|
174
|
+
return value || null;
|
|
175
|
+
}
|
|
176
|
+
catch {
|
|
177
|
+
return null;
|
|
178
|
+
}
|
|
179
|
+
}
|
|
138
180
|
readIndex() {
|
|
139
181
|
try {
|
|
140
182
|
const raw = fs.readFileSync(this.indexPath, 'utf-8');
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"keychain-linux.js","sourceRoot":"","sources":["../../src/backends/keychain-linux.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;GAaG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAEH,iDAA6C;AAC7C,uCAAyB;AACzB,2CAA6B;AAG7B,MAAM,
|
|
1
|
+
{"version":3,"file":"keychain-linux.js","sourceRoot":"","sources":["../../src/backends/keychain-linux.ts"],"names":[],"mappings":"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"}
|
|
@@ -19,6 +19,7 @@ export declare class MacOSKeychainBackend implements WritableSecretBackend {
|
|
|
19
19
|
resolve(secretPath: string): Promise<Record<string, string>>;
|
|
20
20
|
delete(key: string): Promise<boolean>;
|
|
21
21
|
healthCheck(): Promise<BackendHealth>;
|
|
22
|
+
private findPassword;
|
|
22
23
|
private readIndex;
|
|
23
24
|
private writeIndex;
|
|
24
25
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"keychain-macos.d.ts","sourceRoot":"","sources":["../../src/backends/keychain-macos.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAKH,OAAO,KAAK,EAAE,qBAAqB,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"keychain-macos.d.ts","sourceRoot":"","sources":["../../src/backends/keychain-macos.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAKH,OAAO,KAAK,EAAE,qBAAqB,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAuCpE,qBAAa,oBAAqB,YAAW,qBAAqB;IAChE,QAAQ,CAAC,IAAI,oBAAoB;IACjC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;gBAEvB,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAOtC,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IA0ChD,OAAO,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAkB5D,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAoCrC,WAAW,IAAI,OAAO,CAAC,aAAa,CAAC;IAkB3C,OAAO,CAAC,YAAY;IAapB,OAAO,CAAC,SAAS;IAUjB,OAAO,CAAC,UAAU;CAKnB"}
|
|
@@ -49,8 +49,20 @@ exports.MacOSKeychainBackend = void 0;
|
|
|
49
49
|
const child_process_1 = require("child_process");
|
|
50
50
|
const fs = __importStar(require("fs"));
|
|
51
51
|
const path = __importStar(require("path"));
|
|
52
|
-
const
|
|
52
|
+
const LEGACY_SERVICE_NAME = 'secretless';
|
|
53
53
|
const INDEX_FILENAME = 'keychain-index.json';
|
|
54
|
+
/**
|
|
55
|
+
* Derive a per-key service name so macOS Passwords.app shows a descriptive
|
|
56
|
+
* name instead of "Secretless" for every entry.
|
|
57
|
+
*
|
|
58
|
+
* Examples:
|
|
59
|
+
* "secret/ANTHROPIC_API_KEY" → "Secretless: ANTHROPIC_API_KEY"
|
|
60
|
+
* "mcp/claude-desktop/server/TOKEN" → "Secretless: TOKEN"
|
|
61
|
+
*/
|
|
62
|
+
function serviceNameFor(key) {
|
|
63
|
+
const lastSegment = key.split('/').pop() ?? key;
|
|
64
|
+
return `Secretless: ${lastSegment}`;
|
|
65
|
+
}
|
|
54
66
|
/**
|
|
55
67
|
* macOS `security find-generic-password -w` hex-encodes passwords that contain
|
|
56
68
|
* non-printable characters (e.g. newlines). Detect and decode hex output.
|
|
@@ -80,23 +92,35 @@ class MacOSKeychainBackend {
|
|
|
80
92
|
this.indexPath = path.join(storeDir, INDEX_FILENAME);
|
|
81
93
|
}
|
|
82
94
|
async store(key, value) {
|
|
83
|
-
|
|
95
|
+
const svc = serviceNameFor(key);
|
|
96
|
+
// Delete existing entry (new service name)
|
|
84
97
|
try {
|
|
85
98
|
(0, child_process_1.execFileSync)('security', [
|
|
86
99
|
'delete-generic-password',
|
|
87
|
-
'-s',
|
|
100
|
+
'-s', svc,
|
|
88
101
|
'-a', key,
|
|
89
102
|
], { stdio: 'pipe' });
|
|
90
103
|
}
|
|
91
104
|
catch {
|
|
92
105
|
// Entry didn't exist — that's fine
|
|
93
106
|
}
|
|
94
|
-
//
|
|
107
|
+
// Also delete legacy entry (old unified service name) to prevent duplicates
|
|
108
|
+
try {
|
|
109
|
+
(0, child_process_1.execFileSync)('security', [
|
|
110
|
+
'delete-generic-password',
|
|
111
|
+
'-s', LEGACY_SERVICE_NAME,
|
|
112
|
+
'-a', key,
|
|
113
|
+
], { stdio: 'pipe' });
|
|
114
|
+
}
|
|
115
|
+
catch {
|
|
116
|
+
// No legacy entry — that's fine
|
|
117
|
+
}
|
|
118
|
+
// Add the new entry with a per-key service name (visible in macOS Passwords.app)
|
|
95
119
|
(0, child_process_1.execFileSync)('security', [
|
|
96
120
|
'add-generic-password',
|
|
97
|
-
'-s',
|
|
121
|
+
'-s', svc,
|
|
98
122
|
'-a', key,
|
|
99
|
-
'-l', `
|
|
123
|
+
'-l', `Secretless: ${key}`,
|
|
100
124
|
'-w', value,
|
|
101
125
|
], { stdio: 'pipe' });
|
|
102
126
|
// Update index
|
|
@@ -111,37 +135,47 @@ class MacOSKeychainBackend {
|
|
|
111
135
|
const matchingKeys = index.filter(k => k === secretPath || k.startsWith(secretPath + '/'));
|
|
112
136
|
const results = {};
|
|
113
137
|
for (const key of matchingKeys) {
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
'-a', key,
|
|
119
|
-
'-w',
|
|
120
|
-
], { stdio: ['pipe', 'pipe', 'pipe'], encoding: 'utf-8' }).trimEnd();
|
|
138
|
+
// Try new per-key service name first, fall back to legacy
|
|
139
|
+
const raw = this.findPassword(serviceNameFor(key), key)
|
|
140
|
+
?? this.findPassword(LEGACY_SERVICE_NAME, key);
|
|
141
|
+
if (raw !== null) {
|
|
121
142
|
results[key] = decodeKeychainValue(raw);
|
|
122
143
|
}
|
|
123
|
-
catch {
|
|
124
|
-
// Key was in index but not in keychain — skip (stale index entry)
|
|
125
|
-
}
|
|
126
144
|
}
|
|
127
145
|
return results;
|
|
128
146
|
}
|
|
129
147
|
async delete(key) {
|
|
148
|
+
let deleted = false;
|
|
149
|
+
// Delete new-format entry
|
|
130
150
|
try {
|
|
131
151
|
(0, child_process_1.execFileSync)('security', [
|
|
132
152
|
'delete-generic-password',
|
|
133
|
-
'-s',
|
|
153
|
+
'-s', serviceNameFor(key),
|
|
134
154
|
'-a', key,
|
|
135
155
|
], { stdio: 'pipe' });
|
|
136
|
-
|
|
156
|
+
deleted = true;
|
|
157
|
+
}
|
|
158
|
+
catch {
|
|
159
|
+
// Not found with new service name
|
|
160
|
+
}
|
|
161
|
+
// Also delete legacy entry if it exists
|
|
162
|
+
try {
|
|
163
|
+
(0, child_process_1.execFileSync)('security', [
|
|
164
|
+
'delete-generic-password',
|
|
165
|
+
'-s', LEGACY_SERVICE_NAME,
|
|
166
|
+
'-a', key,
|
|
167
|
+
], { stdio: 'pipe' });
|
|
168
|
+
deleted = true;
|
|
169
|
+
}
|
|
170
|
+
catch {
|
|
171
|
+
// No legacy entry
|
|
172
|
+
}
|
|
173
|
+
if (deleted) {
|
|
137
174
|
const index = this.readIndex();
|
|
138
175
|
const filtered = index.filter(k => k !== key);
|
|
139
176
|
this.writeIndex(filtered);
|
|
140
|
-
return true;
|
|
141
|
-
}
|
|
142
|
-
catch {
|
|
143
|
-
return false;
|
|
144
177
|
}
|
|
178
|
+
return deleted;
|
|
145
179
|
}
|
|
146
180
|
async healthCheck() {
|
|
147
181
|
const start = Date.now();
|
|
@@ -161,6 +195,19 @@ class MacOSKeychainBackend {
|
|
|
161
195
|
};
|
|
162
196
|
}
|
|
163
197
|
}
|
|
198
|
+
findPassword(service, account) {
|
|
199
|
+
try {
|
|
200
|
+
return (0, child_process_1.execFileSync)('security', [
|
|
201
|
+
'find-generic-password',
|
|
202
|
+
'-s', service,
|
|
203
|
+
'-a', account,
|
|
204
|
+
'-w',
|
|
205
|
+
], { stdio: ['pipe', 'pipe', 'pipe'], encoding: 'utf-8' }).trimEnd();
|
|
206
|
+
}
|
|
207
|
+
catch {
|
|
208
|
+
return null;
|
|
209
|
+
}
|
|
210
|
+
}
|
|
164
211
|
readIndex() {
|
|
165
212
|
try {
|
|
166
213
|
const raw = fs.readFileSync(this.indexPath, 'utf-8');
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"keychain-macos.js","sourceRoot":"","sources":["../../src/backends/keychain-macos.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;GAWG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAEH,iDAA6C;AAC7C,uCAAyB;AACzB,2CAA6B;AAG7B,MAAM,
|
|
1
|
+
{"version":3,"file":"keychain-macos.js","sourceRoot":"","sources":["../../src/backends/keychain-macos.ts"],"names":[],"mappings":"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"}
|
|
@@ -30,6 +30,7 @@ export declare class OnePasswordBackend implements WritableSecretBackend {
|
|
|
30
30
|
resolve(secretPath: string): Promise<Record<string, string>>;
|
|
31
31
|
delete(key: string): Promise<boolean>;
|
|
32
32
|
healthCheck(): Promise<BackendHealth>;
|
|
33
|
+
private op;
|
|
33
34
|
/**
|
|
34
35
|
* Get or create the Secretless vault. Returns the vault ID.
|
|
35
36
|
* Caches the vault ID for the lifetime of this backend instance.
|
|
@@ -38,6 +39,10 @@ export declare class OnePasswordBackend implements WritableSecretBackend {
|
|
|
38
39
|
/**
|
|
39
40
|
* Look up the vault ID by name. Returns null if the vault doesn't exist
|
|
40
41
|
* or the CLI is not authenticated.
|
|
42
|
+
*
|
|
43
|
+
* Falls back to `op vault list` when `op vault get` fails due to
|
|
44
|
+
* ambiguous name (multiple vaults with the same name). This prevents
|
|
45
|
+
* ensureVault() from creating duplicate vaults.
|
|
41
46
|
*/
|
|
42
47
|
private getVaultId;
|
|
43
48
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"onepassword.d.ts","sourceRoot":"","sources":["../../src/backends/onepassword.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAMH,OAAO,KAAK,EAAE,qBAAqB,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAqBpE,qBAAa,kBAAmB,YAAW,qBAAqB;IAC9D,QAAQ,CAAC,IAAI,eAAe;IAC5B,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,aAAa,CAAuB;gBAEhC,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAQtC,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAuChD,OAAO,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAuB5D,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAYrC,WAAW,IAAI,OAAO,CAAC,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"onepassword.d.ts","sourceRoot":"","sources":["../../src/backends/onepassword.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAMH,OAAO,KAAK,EAAE,qBAAqB,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAqBpE,qBAAa,kBAAmB,YAAW,qBAAqB;IAC9D,QAAQ,CAAC,IAAI,eAAe;IAC5B,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,aAAa,CAAuB;gBAEhC,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAQtC,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAuChD,OAAO,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAuB5D,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAYrC,WAAW,IAAI,OAAO,CAAC,aAAa,CAAC;IAsB3C,OAAO,CAAC,EAAE;IAOV;;;OAGG;IACH,OAAO,CAAC,WAAW;IAcnB;;;;;;;OAOG;IACH,OAAO,CAAC,UAAU;IAoClB;;;OAGG;IACH,OAAO,CAAC,SAAS;IAgBjB;;OAEG;IACH,OAAO,CAAC,eAAe;IAYvB;;;;;;;OAOG;IACH,OAAO,CAAC,aAAa;CAMtB"}
|