@mcpfold/secrets 1.0.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/LICENSE +28 -0
- package/dist/exec.d.ts +13 -0
- package/dist/exec.d.ts.map +1 -0
- package/dist/exec.js +20 -0
- package/dist/exec.js.map +1 -0
- package/dist/index.d.ts +20 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +28 -0
- package/dist/index.js.map +1 -0
- package/dist/providers/dotenv.d.ts +13 -0
- package/dist/providers/dotenv.d.ts.map +1 -0
- package/dist/providers/dotenv.js +54 -0
- package/dist/providers/dotenv.js.map +1 -0
- package/dist/providers/env.d.ts +7 -0
- package/dist/providers/env.d.ts.map +1 -0
- package/dist/providers/env.js +17 -0
- package/dist/providers/env.js.map +1 -0
- package/dist/providers/infisical.d.ts +32 -0
- package/dist/providers/infisical.d.ts.map +1 -0
- package/dist/providers/infisical.js +46 -0
- package/dist/providers/infisical.js.map +1 -0
- package/dist/providers/keychain.d.ts +23 -0
- package/dist/providers/keychain.d.ts.map +1 -0
- package/dist/providers/keychain.js +46 -0
- package/dist/providers/keychain.js.map +1 -0
- package/dist/providers/op.d.ts +14 -0
- package/dist/providers/op.d.ts.map +1 -0
- package/dist/providers/op.js +28 -0
- package/dist/providers/op.js.map +1 -0
- package/dist/resolver.d.ts +24 -0
- package/dist/resolver.d.ts.map +1 -0
- package/dist/resolver.js +101 -0
- package/dist/resolver.js.map +1 -0
- package/dist/types.d.ts +21 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +10 -0
- package/dist/types.js.map +1 -0
- package/package.json +39 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 mcpfold 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.
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
The MIT license above covers the open-source packages: packages/* (@mcpfold/core,
|
|
26
|
+
@mcpfold/adapters, @mcpfold/secrets, @mcpfold/proxy, @mcpfold/schema) and the `mcpfold`
|
|
27
|
+
CLI. The cloud layer (apps/web, services/edge) is commercial/closed and NOT covered by
|
|
28
|
+
this license.
|
package/dist/exec.d.ts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A minimal command runner shared by the keychain and 1Password providers. Injectable so
|
|
3
|
+
* provider logic is testable without invoking the real OS backend or CLI. Never logs args
|
|
4
|
+
* or output (they may contain secrets).
|
|
5
|
+
*/
|
|
6
|
+
export interface ExecResult {
|
|
7
|
+
code: number;
|
|
8
|
+
stdout: string;
|
|
9
|
+
stderr: string;
|
|
10
|
+
}
|
|
11
|
+
export type CommandExec = (command: string, args: string[]) => Promise<ExecResult>;
|
|
12
|
+
export declare const defaultExec: CommandExec;
|
|
13
|
+
//# sourceMappingURL=exec.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"exec.d.ts","sourceRoot":"","sources":["../src/exec.ts"],"names":[],"mappings":"AAEA;;;;GAIG;AAEH,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,MAAM,WAAW,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,OAAO,CAAC,UAAU,CAAC,CAAC;AAEnF,eAAO,MAAM,WAAW,EAAE,WAiBtB,CAAC"}
|
package/dist/exec.js
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { spawn } from 'node:child_process';
|
|
2
|
+
export const defaultExec = (command, args) => new Promise((resolve, reject) => {
|
|
3
|
+
let child;
|
|
4
|
+
try {
|
|
5
|
+
child = spawn(command, args, { stdio: ['ignore', 'pipe', 'pipe'] });
|
|
6
|
+
}
|
|
7
|
+
catch (error) {
|
|
8
|
+
reject(error);
|
|
9
|
+
return;
|
|
10
|
+
}
|
|
11
|
+
let stdout = '';
|
|
12
|
+
let stderr = '';
|
|
13
|
+
child.stdout.setEncoding('utf8');
|
|
14
|
+
child.stderr.setEncoding('utf8');
|
|
15
|
+
child.stdout.on('data', (d) => (stdout += d));
|
|
16
|
+
child.stderr.on('data', (d) => (stderr += d));
|
|
17
|
+
child.on('error', reject);
|
|
18
|
+
child.on('close', (code) => resolve({ code: code ?? 1, stdout, stderr }));
|
|
19
|
+
});
|
|
20
|
+
//# sourceMappingURL=exec.js.map
|
package/dist/exec.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"exec.js","sourceRoot":"","sources":["../src/exec.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAgB3C,MAAM,CAAC,MAAM,WAAW,GAAgB,CAAC,OAAO,EAAE,IAAI,EAAE,EAAE,CACxD,IAAI,OAAO,CAAa,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;IAC1C,IAAI,KAAK,CAAC;IACV,IAAI,CAAC;QACH,KAAK,GAAG,KAAK,CAAC,OAAO,EAAE,IAAI,EAAE,EAAE,KAAK,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,CAAC;IACtE,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,CAAC,KAAK,CAAC,CAAC;QACd,OAAO;IACT,CAAC;IACD,IAAI,MAAM,GAAG,EAAE,CAAC;IAChB,IAAI,MAAM,GAAG,EAAE,CAAC;IAChB,KAAK,CAAC,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;IACjC,KAAK,CAAC,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;IACjC,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,CAAS,EAAE,EAAE,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC,CAAC,CAAC;IACtD,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,CAAS,EAAE,EAAE,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC,CAAC,CAAC;IACtD,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;IAC1B,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,IAAI,IAAI,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC;AAC5E,CAAC,CAAC,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { SecretProvider } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* @mcpfold/secrets — secret providers and the fail-closed resolver. Impure by design
|
|
4
|
+
* (env/fs/network); injected into the pure core.
|
|
5
|
+
*/
|
|
6
|
+
export type { SecretProvider, SecretResolveContext } from './types.js';
|
|
7
|
+
export { resolveSecrets, DEFAULT_TIMEOUT_MS, type ResolveOptions } from './resolver.js';
|
|
8
|
+
export { defaultExec, type CommandExec, type ExecResult } from './exec.js';
|
|
9
|
+
export { envProvider } from './providers/env.js';
|
|
10
|
+
export { dotenvProvider, parseDotenv } from './providers/dotenv.js';
|
|
11
|
+
export { infisicalProvider, parseInfisicalPath, type InfisicalConfig, type InfisicalFetch, type InfisicalFetchParams, } from './providers/infisical.js';
|
|
12
|
+
export { keychainProvider, keychainCommand, type KeychainConfig } from './providers/keychain.js';
|
|
13
|
+
export { opProvider, opReference, type OpConfig } from './providers/op.js';
|
|
14
|
+
/**
|
|
15
|
+
* All built-in providers (spec §6 order): env, dotenv, infisical, keychain, op. Each is
|
|
16
|
+
* registered so any `${scheme:path}` resolves; providers that need configuration fail with
|
|
17
|
+
* an actionable message at resolve time rather than "no provider for scheme".
|
|
18
|
+
*/
|
|
19
|
+
export declare function defaultProviders(cwd?: string): SecretProvider[];
|
|
20
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAEjD;;;GAGG;AAEH,YAAY,EAAE,cAAc,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AACvE,OAAO,EAAE,cAAc,EAAE,kBAAkB,EAAE,KAAK,cAAc,EAAE,MAAM,eAAe,CAAC;AACxF,OAAO,EAAE,WAAW,EAAE,KAAK,WAAW,EAAE,KAAK,UAAU,EAAE,MAAM,WAAW,CAAC;AAC3E,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACpE,OAAO,EACL,iBAAiB,EACjB,kBAAkB,EAClB,KAAK,eAAe,EACpB,KAAK,cAAc,EACnB,KAAK,oBAAoB,GAC1B,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,gBAAgB,EAAE,eAAe,EAAE,KAAK,cAAc,EAAE,MAAM,yBAAyB,CAAC;AACjG,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,KAAK,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAE3E;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,GAAE,MAAsB,GAAG,cAAc,EAAE,CAQ9E"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { join } from 'node:path';
|
|
2
|
+
import { envProvider } from './providers/env.js';
|
|
3
|
+
import { dotenvProvider } from './providers/dotenv.js';
|
|
4
|
+
import { infisicalProvider } from './providers/infisical.js';
|
|
5
|
+
import { keychainProvider } from './providers/keychain.js';
|
|
6
|
+
import { opProvider } from './providers/op.js';
|
|
7
|
+
export { resolveSecrets, DEFAULT_TIMEOUT_MS } from './resolver.js';
|
|
8
|
+
export { defaultExec } from './exec.js';
|
|
9
|
+
export { envProvider } from './providers/env.js';
|
|
10
|
+
export { dotenvProvider, parseDotenv } from './providers/dotenv.js';
|
|
11
|
+
export { infisicalProvider, parseInfisicalPath, } from './providers/infisical.js';
|
|
12
|
+
export { keychainProvider, keychainCommand } from './providers/keychain.js';
|
|
13
|
+
export { opProvider, opReference } from './providers/op.js';
|
|
14
|
+
/**
|
|
15
|
+
* All built-in providers (spec §6 order): env, dotenv, infisical, keychain, op. Each is
|
|
16
|
+
* registered so any `${scheme:path}` resolves; providers that need configuration fail with
|
|
17
|
+
* an actionable message at resolve time rather than "no provider for scheme".
|
|
18
|
+
*/
|
|
19
|
+
export function defaultProviders(cwd = process.cwd()) {
|
|
20
|
+
return [
|
|
21
|
+
envProvider(),
|
|
22
|
+
dotenvProvider(join(cwd, '.env')),
|
|
23
|
+
infisicalProvider(),
|
|
24
|
+
keychainProvider(),
|
|
25
|
+
opProvider(),
|
|
26
|
+
];
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAC7D,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAC3D,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAS/C,OAAO,EAAE,cAAc,EAAE,kBAAkB,EAAuB,MAAM,eAAe,CAAC;AACxF,OAAO,EAAE,WAAW,EAAqC,MAAM,WAAW,CAAC;AAC3E,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACpE,OAAO,EACL,iBAAiB,EACjB,kBAAkB,GAInB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,gBAAgB,EAAE,eAAe,EAAuB,MAAM,yBAAyB,CAAC;AACjG,OAAO,EAAE,UAAU,EAAE,WAAW,EAAiB,MAAM,mBAAmB,CAAC;AAE3E;;;;GAIG;AACH,MAAM,UAAU,gBAAgB,CAAC,MAAc,OAAO,CAAC,GAAG,EAAE;IAC1D,OAAO;QACL,WAAW,EAAE;QACb,cAAc,CAAC,IAAI,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;QACjC,iBAAiB,EAAE;QACnB,gBAAgB,EAAE;QAClB,UAAU,EAAE;KACb,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { SecretProvider } from '../types.js';
|
|
2
|
+
/**
|
|
3
|
+
* `dotenv` provider (S4.2) — resolves `${dotenv:NAME}` from a designated `.env` file.
|
|
4
|
+
*
|
|
5
|
+
* Path convention: the file path is supplied when the provider is constructed (the CLI
|
|
6
|
+
* defaults to `<cwd>/.env`). Values are read into a private cache — they are **never**
|
|
7
|
+
* written to `process.env`, so a dotenv secret can't leak to child processes or other code
|
|
8
|
+
* that inspects the global environment.
|
|
9
|
+
*/
|
|
10
|
+
/** Minimal .env parser: `KEY=VALUE` lines, `#` comments, optional surrounding quotes. */
|
|
11
|
+
export declare function parseDotenv(text: string): Record<string, string>;
|
|
12
|
+
export declare function dotenvProvider(filePath: string): SecretProvider;
|
|
13
|
+
//# sourceMappingURL=dotenv.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dotenv.d.ts","sourceRoot":"","sources":["../../src/providers/dotenv.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAElD;;;;;;;GAOG;AAEH,yFAAyF;AACzF,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAkBhE;AAED,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,cAAc,CAqB/D"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { readFileSync } from 'node:fs';
|
|
2
|
+
/**
|
|
3
|
+
* `dotenv` provider (S4.2) — resolves `${dotenv:NAME}` from a designated `.env` file.
|
|
4
|
+
*
|
|
5
|
+
* Path convention: the file path is supplied when the provider is constructed (the CLI
|
|
6
|
+
* defaults to `<cwd>/.env`). Values are read into a private cache — they are **never**
|
|
7
|
+
* written to `process.env`, so a dotenv secret can't leak to child processes or other code
|
|
8
|
+
* that inspects the global environment.
|
|
9
|
+
*/
|
|
10
|
+
/** Minimal .env parser: `KEY=VALUE` lines, `#` comments, optional surrounding quotes. */
|
|
11
|
+
export function parseDotenv(text) {
|
|
12
|
+
const out = {};
|
|
13
|
+
for (const rawLine of text.split(/\r?\n/)) {
|
|
14
|
+
const line = rawLine.trim();
|
|
15
|
+
if (!line || line.startsWith('#'))
|
|
16
|
+
continue;
|
|
17
|
+
const eq = line.indexOf('=');
|
|
18
|
+
if (eq === -1)
|
|
19
|
+
continue;
|
|
20
|
+
const key = line.slice(0, eq).trim();
|
|
21
|
+
let value = line.slice(eq + 1).trim();
|
|
22
|
+
if ((value.startsWith('"') && value.endsWith('"')) ||
|
|
23
|
+
(value.startsWith("'") && value.endsWith("'"))) {
|
|
24
|
+
value = value.slice(1, -1);
|
|
25
|
+
}
|
|
26
|
+
if (key)
|
|
27
|
+
out[key] = value;
|
|
28
|
+
}
|
|
29
|
+
return out;
|
|
30
|
+
}
|
|
31
|
+
export function dotenvProvider(filePath) {
|
|
32
|
+
let cache = null;
|
|
33
|
+
return {
|
|
34
|
+
scheme: 'dotenv',
|
|
35
|
+
async resolve(path) {
|
|
36
|
+
if (!cache) {
|
|
37
|
+
let text;
|
|
38
|
+
try {
|
|
39
|
+
text = readFileSync(filePath, 'utf8');
|
|
40
|
+
}
|
|
41
|
+
catch {
|
|
42
|
+
throw new Error(`could not read dotenv file at ${filePath}`);
|
|
43
|
+
}
|
|
44
|
+
cache = parseDotenv(text);
|
|
45
|
+
}
|
|
46
|
+
const value = cache[path];
|
|
47
|
+
if (value === undefined) {
|
|
48
|
+
throw new Error(`"${path}" not found in ${filePath}`);
|
|
49
|
+
}
|
|
50
|
+
return value;
|
|
51
|
+
},
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
//# sourceMappingURL=dotenv.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dotenv.js","sourceRoot":"","sources":["../../src/providers/dotenv.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAGvC;;;;;;;GAOG;AAEH,yFAAyF;AACzF,MAAM,UAAU,WAAW,CAAC,IAAY;IACtC,MAAM,GAAG,GAA2B,EAAE,CAAC;IACvC,KAAK,MAAM,OAAO,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC;QAC1C,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC;QAC5B,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC;YAAE,SAAS;QAC5C,MAAM,EAAE,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QAC7B,IAAI,EAAE,KAAK,CAAC,CAAC;YAAE,SAAS;QACxB,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;QACrC,IAAI,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QACtC,IACE,CAAC,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;YAC9C,CAAC,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,EAC9C,CAAC;YACD,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;QAC7B,CAAC;QACD,IAAI,GAAG;YAAE,GAAG,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;IAC5B,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,QAAgB;IAC7C,IAAI,KAAK,GAAkC,IAAI,CAAC;IAChD,OAAO;QACL,MAAM,EAAE,QAAQ;QAChB,KAAK,CAAC,OAAO,CAAC,IAAI;YAChB,IAAI,CAAC,KAAK,EAAE,CAAC;gBACX,IAAI,IAAY,CAAC;gBACjB,IAAI,CAAC;oBACH,IAAI,GAAG,YAAY,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;gBACxC,CAAC;gBAAC,MAAM,CAAC;oBACP,MAAM,IAAI,KAAK,CAAC,iCAAiC,QAAQ,EAAE,CAAC,CAAC;gBAC/D,CAAC;gBACD,KAAK,GAAG,WAAW,CAAC,IAAI,CAAC,CAAC;YAC5B,CAAC;YACD,MAAM,KAAK,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC;YAC1B,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;gBACxB,MAAM,IAAI,KAAK,CAAC,IAAI,IAAI,kBAAkB,QAAQ,EAAE,CAAC,CAAC;YACxD,CAAC;YACD,OAAO,KAAK,CAAC;QACf,CAAC;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { SecretProvider } from '../types.js';
|
|
2
|
+
/**
|
|
3
|
+
* `env` provider (S4.2) — resolves `${env:NAME}` from the process environment. A missing
|
|
4
|
+
* variable is a clear, fail-closed error. Writes secret values nowhere.
|
|
5
|
+
*/
|
|
6
|
+
export declare function envProvider(env?: NodeJS.ProcessEnv): SecretProvider;
|
|
7
|
+
//# sourceMappingURL=env.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"env.d.ts","sourceRoot":"","sources":["../../src/providers/env.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAElD;;;GAGG;AACH,wBAAgB,WAAW,CAAC,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,cAAc,CAWhF"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `env` provider (S4.2) — resolves `${env:NAME}` from the process environment. A missing
|
|
3
|
+
* variable is a clear, fail-closed error. Writes secret values nowhere.
|
|
4
|
+
*/
|
|
5
|
+
export function envProvider(env = process.env) {
|
|
6
|
+
return {
|
|
7
|
+
scheme: 'env',
|
|
8
|
+
async resolve(path) {
|
|
9
|
+
const value = env[path];
|
|
10
|
+
if (value === undefined) {
|
|
11
|
+
throw new Error(`environment variable "${path}" is not set`);
|
|
12
|
+
}
|
|
13
|
+
return value;
|
|
14
|
+
},
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=env.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"env.js","sourceRoot":"","sources":["../../src/providers/env.ts"],"names":[],"mappings":"AAEA;;;GAGG;AACH,MAAM,UAAU,WAAW,CAAC,MAAyB,OAAO,CAAC,GAAG;IAC9D,OAAO;QACL,MAAM,EAAE,KAAK;QACb,KAAK,CAAC,OAAO,CAAC,IAAI;YAChB,MAAM,KAAK,GAAG,GAAG,CAAC,IAAI,CAAC,CAAC;YACxB,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;gBACxB,MAAM,IAAI,KAAK,CAAC,yBAAyB,IAAI,cAAc,CAAC,CAAC;YAC/D,CAAC;YACD,OAAO,KAAK,CAAC;QACf,CAAC;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import type { SecretProvider } from '../types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Infisical provider (S4.3) — resolves `${infisical:env/path/KEY}` against a configured
|
|
4
|
+
* Infisical project (spec §6). Auth is via a machine-identity/service token taken from the
|
|
5
|
+
* environment (`INFISICAL_TOKEN`) — never hardcoded. The network call is isolated behind an
|
|
6
|
+
* injectable `fetchSecret` so tests need no real Infisical.
|
|
7
|
+
*
|
|
8
|
+
* Ref grammar: the FIRST path segment is the environment slug, the LAST is the secret key,
|
|
9
|
+
* and anything in between is the folder path — e.g. `dev/mcp/GITHUB_PAT` →
|
|
10
|
+
* env `dev`, path `/mcp`, key `GITHUB_PAT`.
|
|
11
|
+
*/
|
|
12
|
+
export interface InfisicalFetchParams {
|
|
13
|
+
key: string;
|
|
14
|
+
environment: string;
|
|
15
|
+
secretPath: string;
|
|
16
|
+
token: string;
|
|
17
|
+
projectId: string;
|
|
18
|
+
apiUrl: string;
|
|
19
|
+
}
|
|
20
|
+
export type InfisicalFetch = (params: InfisicalFetchParams) => Promise<string>;
|
|
21
|
+
export interface InfisicalConfig {
|
|
22
|
+
env?: NodeJS.ProcessEnv;
|
|
23
|
+
/** Injectable network call; defaults to the Infisical v3 raw-secret REST endpoint. */
|
|
24
|
+
fetchSecret?: InfisicalFetch;
|
|
25
|
+
}
|
|
26
|
+
export declare function parseInfisicalPath(path: string): {
|
|
27
|
+
environment: string;
|
|
28
|
+
secretPath: string;
|
|
29
|
+
key: string;
|
|
30
|
+
};
|
|
31
|
+
export declare function infisicalProvider(config?: InfisicalConfig): SecretProvider;
|
|
32
|
+
//# sourceMappingURL=infisical.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"infisical.d.ts","sourceRoot":"","sources":["../../src/providers/infisical.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAElD;;;;;;;;;GASG;AAEH,MAAM,WAAW,oBAAoB;IACnC,GAAG,EAAE,MAAM,CAAC;IACZ,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,MAAM,cAAc,GAAG,CAAC,MAAM,EAAE,oBAAoB,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;AAE/E,MAAM,WAAW,eAAe;IAC9B,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;IACxB,sFAAsF;IACtF,WAAW,CAAC,EAAE,cAAc,CAAC;CAC9B;AAED,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG;IAChD,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,GAAG,EAAE,MAAM,CAAC;CACb,CAWA;AAwBD,wBAAgB,iBAAiB,CAAC,MAAM,GAAE,eAAoB,GAAG,cAAc,CAqB9E"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
export function parseInfisicalPath(path) {
|
|
2
|
+
const segments = path.split('/').filter(Boolean);
|
|
3
|
+
if (segments.length < 2) {
|
|
4
|
+
throw new Error(`infisical reference "${path}" must be "env/[folder/…/]KEY" (e.g. dev/mcp/GITHUB_PAT)`);
|
|
5
|
+
}
|
|
6
|
+
const environment = segments[0];
|
|
7
|
+
const key = segments[segments.length - 1];
|
|
8
|
+
const folder = segments.slice(1, -1);
|
|
9
|
+
return { environment, secretPath: `/${folder.join('/')}`, key };
|
|
10
|
+
}
|
|
11
|
+
const defaultFetch = async ({ key, environment, secretPath, token, projectId, apiUrl, }) => {
|
|
12
|
+
const url = new URL(`${apiUrl.replace(/\/$/, '')}/api/v3/secrets/raw/${encodeURIComponent(key)}`);
|
|
13
|
+
url.searchParams.set('workspaceId', projectId);
|
|
14
|
+
url.searchParams.set('environment', environment);
|
|
15
|
+
url.searchParams.set('secretPath', secretPath);
|
|
16
|
+
const response = await fetch(url, { headers: { Authorization: `Bearer ${token}` } });
|
|
17
|
+
if (!response.ok) {
|
|
18
|
+
throw new Error(`Infisical API responded ${response.status} for "${key}"`);
|
|
19
|
+
}
|
|
20
|
+
const body = (await response.json());
|
|
21
|
+
const value = body.secret?.secretValue;
|
|
22
|
+
if (value === undefined)
|
|
23
|
+
throw new Error(`Infisical returned no value for "${key}"`);
|
|
24
|
+
return value;
|
|
25
|
+
};
|
|
26
|
+
export function infisicalProvider(config = {}) {
|
|
27
|
+
const env = config.env ?? process.env;
|
|
28
|
+
const fetchSecret = config.fetchSecret ?? defaultFetch;
|
|
29
|
+
return {
|
|
30
|
+
scheme: 'infisical',
|
|
31
|
+
async resolve(path) {
|
|
32
|
+
const token = env.INFISICAL_TOKEN;
|
|
33
|
+
const projectId = env.INFISICAL_PROJECT_ID;
|
|
34
|
+
const apiUrl = env.INFISICAL_API_URL ?? 'https://app.infisical.com';
|
|
35
|
+
if (!token) {
|
|
36
|
+
throw new Error('INFISICAL_TOKEN is not set (use an Infisical machine-identity/service token)');
|
|
37
|
+
}
|
|
38
|
+
if (!projectId) {
|
|
39
|
+
throw new Error('INFISICAL_PROJECT_ID is not set');
|
|
40
|
+
}
|
|
41
|
+
const { environment, secretPath, key } = parseInfisicalPath(path);
|
|
42
|
+
return fetchSecret({ key, environment, secretPath, token, projectId, apiUrl });
|
|
43
|
+
},
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
//# sourceMappingURL=infisical.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"infisical.js","sourceRoot":"","sources":["../../src/providers/infisical.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { type CommandExec } from '../exec.js';
|
|
2
|
+
import type { SecretProvider } from '../types.js';
|
|
3
|
+
/**
|
|
4
|
+
* OS keychain provider (S4.4) — resolves `${keychain:account}` from the platform's native
|
|
5
|
+
* secret store under a fixed service name (`mcpfold` by default):
|
|
6
|
+
* - macOS: `security find-generic-password -s <service> -a <account> -w`
|
|
7
|
+
* - Linux: `secret-tool lookup service <service> account <account>` (libsecret)
|
|
8
|
+
* - Windows: PowerShell + the CredentialManager module (`Get-StoredCredential`)
|
|
9
|
+
*
|
|
10
|
+
* Store a value with `mcpfold secret set` (or the OS tool directly). The backend call is
|
|
11
|
+
* injectable for tests.
|
|
12
|
+
*/
|
|
13
|
+
export interface KeychainConfig {
|
|
14
|
+
platform?: NodeJS.Platform;
|
|
15
|
+
service?: string;
|
|
16
|
+
exec?: CommandExec;
|
|
17
|
+
}
|
|
18
|
+
export declare function keychainCommand(platform: NodeJS.Platform, service: string, account: string): {
|
|
19
|
+
command: string;
|
|
20
|
+
args: string[];
|
|
21
|
+
};
|
|
22
|
+
export declare function keychainProvider(config?: KeychainConfig): SecretProvider;
|
|
23
|
+
//# sourceMappingURL=keychain.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"keychain.d.ts","sourceRoot":"","sources":["../../src/providers/keychain.ts"],"names":[],"mappings":"AAAA,OAAO,EAAe,KAAK,WAAW,EAAE,MAAM,YAAY,CAAC;AAC3D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAElD;;;;;;;;;GASG;AAEH,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,EAAE,MAAM,CAAC,QAAQ,CAAC;IAC3B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,WAAW,CAAC;CACpB;AAED,wBAAgB,eAAe,CAC7B,QAAQ,EAAE,MAAM,CAAC,QAAQ,EACzB,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,GACd;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,EAAE,CAAA;CAAE,CAmBrC;AAED,wBAAgB,gBAAgB,CAAC,MAAM,GAAE,cAAmB,GAAG,cAAc,CA0B5E"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { defaultExec } from '../exec.js';
|
|
2
|
+
export function keychainCommand(platform, service, account) {
|
|
3
|
+
switch (platform) {
|
|
4
|
+
case 'darwin':
|
|
5
|
+
return {
|
|
6
|
+
command: 'security',
|
|
7
|
+
args: ['find-generic-password', '-s', service, '-a', account, '-w'],
|
|
8
|
+
};
|
|
9
|
+
case 'win32':
|
|
10
|
+
return {
|
|
11
|
+
command: 'powershell',
|
|
12
|
+
args: [
|
|
13
|
+
'-NoProfile',
|
|
14
|
+
'-Command',
|
|
15
|
+
`(Get-StoredCredential -Target '${service}:${account}').GetNetworkCredential().Password`,
|
|
16
|
+
],
|
|
17
|
+
};
|
|
18
|
+
default: // linux / libsecret
|
|
19
|
+
return { command: 'secret-tool', args: ['lookup', 'service', service, 'account', account] };
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
export function keychainProvider(config = {}) {
|
|
23
|
+
const platform = config.platform ?? process.platform;
|
|
24
|
+
const service = config.service ?? 'mcpfold';
|
|
25
|
+
const exec = config.exec ?? defaultExec;
|
|
26
|
+
return {
|
|
27
|
+
scheme: 'keychain',
|
|
28
|
+
async resolve(account) {
|
|
29
|
+
const { command, args } = keychainCommand(platform, service, account);
|
|
30
|
+
let result;
|
|
31
|
+
try {
|
|
32
|
+
result = await exec(command, args);
|
|
33
|
+
}
|
|
34
|
+
catch {
|
|
35
|
+
throw new Error(`keychain backend "${command}" is not available — install it (macOS: built-in; ` +
|
|
36
|
+
`Linux: libsecret/secret-tool; Windows: CredentialManager module) or use a different provider`);
|
|
37
|
+
}
|
|
38
|
+
if (result.code !== 0) {
|
|
39
|
+
throw new Error(`keychain has no entry for "${service}:${account}" (store it with \`mcpfold secret set\`)`);
|
|
40
|
+
}
|
|
41
|
+
// `security -w` and secret-tool return a trailing newline.
|
|
42
|
+
return result.stdout.replace(/\r?\n$/, '');
|
|
43
|
+
},
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
//# sourceMappingURL=keychain.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"keychain.js","sourceRoot":"","sources":["../../src/providers/keychain.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAoB,MAAM,YAAY,CAAC;AAoB3D,MAAM,UAAU,eAAe,CAC7B,QAAyB,EACzB,OAAe,EACf,OAAe;IAEf,QAAQ,QAAQ,EAAE,CAAC;QACjB,KAAK,QAAQ;YACX,OAAO;gBACL,OAAO,EAAE,UAAU;gBACnB,IAAI,EAAE,CAAC,uBAAuB,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,CAAC;aACpE,CAAC;QACJ,KAAK,OAAO;YACV,OAAO;gBACL,OAAO,EAAE,YAAY;gBACrB,IAAI,EAAE;oBACJ,YAAY;oBACZ,UAAU;oBACV,kCAAkC,OAAO,IAAI,OAAO,oCAAoC;iBACzF;aACF,CAAC;QACJ,SAAS,oBAAoB;YAC3B,OAAO,EAAE,OAAO,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,QAAQ,EAAE,SAAS,EAAE,OAAO,EAAE,SAAS,EAAE,OAAO,CAAC,EAAE,CAAC;IAChG,CAAC;AACH,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,SAAyB,EAAE;IAC1D,MAAM,QAAQ,GAAG,MAAM,CAAC,QAAQ,IAAI,OAAO,CAAC,QAAQ,CAAC;IACrD,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,IAAI,SAAS,CAAC;IAC5C,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,IAAI,WAAW,CAAC;IACxC,OAAO;QACL,MAAM,EAAE,UAAU;QAClB,KAAK,CAAC,OAAO,CAAC,OAAO;YACnB,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,GAAG,eAAe,CAAC,QAAQ,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;YACtE,IAAI,MAAM,CAAC;YACX,IAAI,CAAC;gBACH,MAAM,GAAG,MAAM,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;YACrC,CAAC;YAAC,MAAM,CAAC;gBACP,MAAM,IAAI,KAAK,CACb,qBAAqB,OAAO,oDAAoD;oBAC9E,8FAA8F,CACjG,CAAC;YACJ,CAAC;YACD,IAAI,MAAM,CAAC,IAAI,KAAK,CAAC,EAAE,CAAC;gBACtB,MAAM,IAAI,KAAK,CACb,8BAA8B,OAAO,IAAI,OAAO,0CAA0C,CAC3F,CAAC;YACJ,CAAC;YACD,2DAA2D;YAC3D,OAAO,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;QAC7C,CAAC;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { type CommandExec } from '../exec.js';
|
|
2
|
+
import type { SecretProvider } from '../types.js';
|
|
3
|
+
/**
|
|
4
|
+
* 1Password provider (S4.5) — resolves `${op:vault/item/field}` by shelling out to the `op`
|
|
5
|
+
* CLI (`op read op://vault/item/field`). The CLI must be installed and signed in; a
|
|
6
|
+
* missing/locked CLI produces an actionable message. Secret values are never logged. The
|
|
7
|
+
* `op` invocation is injectable for tests.
|
|
8
|
+
*/
|
|
9
|
+
export interface OpConfig {
|
|
10
|
+
exec?: CommandExec;
|
|
11
|
+
}
|
|
12
|
+
export declare function opReference(path: string): string;
|
|
13
|
+
export declare function opProvider(config?: OpConfig): SecretProvider;
|
|
14
|
+
//# sourceMappingURL=op.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"op.d.ts","sourceRoot":"","sources":["../../src/providers/op.ts"],"names":[],"mappings":"AAAA,OAAO,EAAe,KAAK,WAAW,EAAE,MAAM,YAAY,CAAC;AAC3D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAElD;;;;;GAKG;AAEH,MAAM,WAAW,QAAQ;IACvB,IAAI,CAAC,EAAE,WAAW,CAAC;CACpB;AAED,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEhD;AAED,wBAAgB,UAAU,CAAC,MAAM,GAAE,QAAa,GAAG,cAAc,CAuBhE"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { defaultExec } from '../exec.js';
|
|
2
|
+
export function opReference(path) {
|
|
3
|
+
return `op://${path.replace(/^op:\/\//, '')}`;
|
|
4
|
+
}
|
|
5
|
+
export function opProvider(config = {}) {
|
|
6
|
+
const exec = config.exec ?? defaultExec;
|
|
7
|
+
return {
|
|
8
|
+
scheme: 'op',
|
|
9
|
+
async resolve(path) {
|
|
10
|
+
const reference = opReference(path);
|
|
11
|
+
let result;
|
|
12
|
+
try {
|
|
13
|
+
result = await exec('op', ['read', reference]);
|
|
14
|
+
}
|
|
15
|
+
catch {
|
|
16
|
+
throw new Error('the 1Password CLI `op` is not installed or not on PATH — install it from https://developer.1password.com/docs/cli');
|
|
17
|
+
}
|
|
18
|
+
if (result.code !== 0) {
|
|
19
|
+
const hint = /not signed in|authorization|sign in/i.test(result.stderr)
|
|
20
|
+
? 'run `op signin` first'
|
|
21
|
+
: `check that "${reference}" exists`;
|
|
22
|
+
throw new Error(`op could not read "${reference}" (${hint})`);
|
|
23
|
+
}
|
|
24
|
+
return result.stdout.replace(/\r?\n$/, '');
|
|
25
|
+
},
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=op.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"op.js","sourceRoot":"","sources":["../../src/providers/op.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAoB,MAAM,YAAY,CAAC;AAc3D,MAAM,UAAU,WAAW,CAAC,IAAY;IACtC,OAAO,QAAQ,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,EAAE,CAAC;AAChD,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,SAAmB,EAAE;IAC9C,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,IAAI,WAAW,CAAC;IACxC,OAAO;QACL,MAAM,EAAE,IAAI;QACZ,KAAK,CAAC,OAAO,CAAC,IAAI;YAChB,MAAM,SAAS,GAAG,WAAW,CAAC,IAAI,CAAC,CAAC;YACpC,IAAI,MAAM,CAAC;YACX,IAAI,CAAC;gBACH,MAAM,GAAG,MAAM,IAAI,CAAC,IAAI,EAAE,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC,CAAC;YACjD,CAAC;YAAC,MAAM,CAAC;gBACP,MAAM,IAAI,KAAK,CACb,mHAAmH,CACpH,CAAC;YACJ,CAAC;YACD,IAAI,MAAM,CAAC,IAAI,KAAK,CAAC,EAAE,CAAC;gBACtB,MAAM,IAAI,GAAG,sCAAsC,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC;oBACrE,CAAC,CAAC,uBAAuB;oBACzB,CAAC,CAAC,eAAe,SAAS,UAAU,CAAC;gBACvC,MAAM,IAAI,KAAK,CAAC,sBAAsB,SAAS,MAAM,IAAI,GAAG,CAAC,CAAC;YAChE,CAAC;YACD,OAAO,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;QAC7C,CAAC;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { type ResolvedServer } from '@mcpfold/core';
|
|
2
|
+
import type { SecretProvider } from './types.js';
|
|
3
|
+
/**
|
|
4
|
+
* The fail-closed secret resolver (S4.1 + the S0.9 contract).
|
|
5
|
+
*
|
|
6
|
+
* Selects a provider by scheme, resolves every `${scheme:path}` reference in a server set,
|
|
7
|
+
* and injects the values — memoizing within a run so the same ref is fetched once. If ANY
|
|
8
|
+
* reference cannot be resolved (missing provider, missing value, provider error, or
|
|
9
|
+
* timeout) the whole call rejects with a {@link SecretResolutionError} naming the provider
|
|
10
|
+
* and ref, and NO server is returned partially resolved (fail closed).
|
|
11
|
+
*/
|
|
12
|
+
/** Default per-provider timeout. A hung provider aborts cleanly rather than blocking forever. */
|
|
13
|
+
export declare const DEFAULT_TIMEOUT_MS = 10000;
|
|
14
|
+
export interface ResolveOptions {
|
|
15
|
+
providers: SecretProvider[];
|
|
16
|
+
/** Global per-provider timeout (ms); a provider's own `timeoutMs` overrides it. */
|
|
17
|
+
timeoutMs?: number;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Resolve all secret references in `servers`, returning new servers with values injected.
|
|
21
|
+
* Rejects (fail closed) on the first unresolved reference.
|
|
22
|
+
*/
|
|
23
|
+
export declare function resolveSecrets(servers: ResolvedServer[], options: ResolveOptions): Promise<ResolvedServer[]>;
|
|
24
|
+
//# sourceMappingURL=resolver.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolver.d.ts","sourceRoot":"","sources":["../src/resolver.ts"],"names":[],"mappings":"AAAA,OAAO,EAAiD,KAAK,cAAc,EAAE,MAAM,eAAe,CAAC;AACnG,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAEjD;;;;;;;;GAQG;AAEH,iGAAiG;AACjG,eAAO,MAAM,kBAAkB,QAAS,CAAC;AAEzC,MAAM,WAAW,cAAc;IAC7B,SAAS,EAAE,cAAc,EAAE,CAAC;IAC5B,mFAAmF;IACnF,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAwBD;;;GAGG;AACH,wBAAsB,cAAc,CAClC,OAAO,EAAE,cAAc,EAAE,EACzB,OAAO,EAAE,cAAc,GACtB,OAAO,CAAC,cAAc,EAAE,CAAC,CAqE3B"}
|
package/dist/resolver.js
ADDED
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import { findSecretRefsInString, SecretResolutionError } from '@mcpfold/core';
|
|
2
|
+
/**
|
|
3
|
+
* The fail-closed secret resolver (S4.1 + the S0.9 contract).
|
|
4
|
+
*
|
|
5
|
+
* Selects a provider by scheme, resolves every `${scheme:path}` reference in a server set,
|
|
6
|
+
* and injects the values — memoizing within a run so the same ref is fetched once. If ANY
|
|
7
|
+
* reference cannot be resolved (missing provider, missing value, provider error, or
|
|
8
|
+
* timeout) the whole call rejects with a {@link SecretResolutionError} naming the provider
|
|
9
|
+
* and ref, and NO server is returned partially resolved (fail closed).
|
|
10
|
+
*/
|
|
11
|
+
/** Default per-provider timeout. A hung provider aborts cleanly rather than blocking forever. */
|
|
12
|
+
export const DEFAULT_TIMEOUT_MS = 10_000;
|
|
13
|
+
function buildRegistry(providers) {
|
|
14
|
+
const registry = new Map();
|
|
15
|
+
for (const p of providers)
|
|
16
|
+
registry.set(p.scheme, p);
|
|
17
|
+
return registry;
|
|
18
|
+
}
|
|
19
|
+
async function withTimeout(work, ms) {
|
|
20
|
+
const controller = new AbortController();
|
|
21
|
+
let timer;
|
|
22
|
+
const timeout = new Promise((_, reject) => {
|
|
23
|
+
timer = setTimeout(() => {
|
|
24
|
+
controller.abort();
|
|
25
|
+
reject(new Error(`timed out after ${ms}ms`));
|
|
26
|
+
}, ms);
|
|
27
|
+
});
|
|
28
|
+
try {
|
|
29
|
+
return await Promise.race([work(controller.signal), timeout]);
|
|
30
|
+
}
|
|
31
|
+
finally {
|
|
32
|
+
if (timer)
|
|
33
|
+
clearTimeout(timer);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Resolve all secret references in `servers`, returning new servers with values injected.
|
|
38
|
+
* Rejects (fail closed) on the first unresolved reference.
|
|
39
|
+
*/
|
|
40
|
+
export async function resolveSecrets(servers, options) {
|
|
41
|
+
const registry = buildRegistry(options.providers);
|
|
42
|
+
const defaultTimeout = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;
|
|
43
|
+
const memo = new Map();
|
|
44
|
+
const resolveOne = async (raw, scheme, path) => {
|
|
45
|
+
const cached = memo.get(raw);
|
|
46
|
+
if (cached !== undefined)
|
|
47
|
+
return cached;
|
|
48
|
+
const provider = registry.get(scheme);
|
|
49
|
+
if (!provider) {
|
|
50
|
+
throw new SecretResolutionError(`No secret provider registered for scheme "${scheme}" (reference ${raw}).`, {
|
|
51
|
+
hint: `Register a provider for "${scheme}", or use a supported scheme (env, dotenv, infisical, keychain, op).`,
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
let value;
|
|
55
|
+
try {
|
|
56
|
+
value = await withTimeout((signal) => provider.resolve(path, { signal }), provider.timeoutMs ?? defaultTimeout);
|
|
57
|
+
}
|
|
58
|
+
catch (error) {
|
|
59
|
+
throw new SecretResolutionError(`Failed to resolve ${raw} via provider "${scheme}": ${error.message}`, {
|
|
60
|
+
cause: error,
|
|
61
|
+
hint: `Check that "${path}" exists and the "${scheme}" provider is reachable.`,
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
memo.set(raw, value);
|
|
65
|
+
return value;
|
|
66
|
+
};
|
|
67
|
+
/** Replace every embedded ref in a string with its resolved value. */
|
|
68
|
+
const resolveString = async (input) => {
|
|
69
|
+
let out = input;
|
|
70
|
+
for (const ref of findSecretRefsInString(input)) {
|
|
71
|
+
const value = await resolveOne(ref.raw, ref.scheme, ref.path);
|
|
72
|
+
out = out.split(ref.raw).join(value);
|
|
73
|
+
}
|
|
74
|
+
return out;
|
|
75
|
+
};
|
|
76
|
+
const resolved = [];
|
|
77
|
+
for (const server of servers) {
|
|
78
|
+
const clone = { ...server };
|
|
79
|
+
if (server.auth) {
|
|
80
|
+
const auth = { ...server.auth };
|
|
81
|
+
if (server.auth.token)
|
|
82
|
+
auth.token = await resolveString(server.auth.token);
|
|
83
|
+
if (server.auth.headers) {
|
|
84
|
+
const headers = {};
|
|
85
|
+
for (const [k, v] of Object.entries(server.auth.headers))
|
|
86
|
+
headers[k] = await resolveString(v);
|
|
87
|
+
auth.headers = headers;
|
|
88
|
+
}
|
|
89
|
+
clone.auth = auth;
|
|
90
|
+
}
|
|
91
|
+
if (server.env) {
|
|
92
|
+
const env = {};
|
|
93
|
+
for (const [k, v] of Object.entries(server.env))
|
|
94
|
+
env[k] = await resolveString(v);
|
|
95
|
+
clone.env = env;
|
|
96
|
+
}
|
|
97
|
+
resolved.push(clone);
|
|
98
|
+
}
|
|
99
|
+
return resolved;
|
|
100
|
+
}
|
|
101
|
+
//# sourceMappingURL=resolver.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolver.js","sourceRoot":"","sources":["../src/resolver.ts"],"names":[],"mappings":"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"}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Secret-provider interface (S4.1, spec §6) and the resolver contract (S0.9).
|
|
3
|
+
*
|
|
4
|
+
* A provider resolves the `path` portion of a `${scheme:path}` reference to a value. It may
|
|
5
|
+
* touch env/fs/network (this package is impure by design); it is injected into the pure
|
|
6
|
+
* core. Resolution is **fail-closed**: any failure aborts the whole operation — a blank or
|
|
7
|
+
* partial secret is NEVER injected.
|
|
8
|
+
*/
|
|
9
|
+
export interface SecretResolveContext {
|
|
10
|
+
/** Aborted when the per-provider timeout elapses; providers should honor it. */
|
|
11
|
+
signal?: AbortSignal;
|
|
12
|
+
}
|
|
13
|
+
export interface SecretProvider {
|
|
14
|
+
/** The scheme this provider handles, e.g. `env`, `dotenv`, `infisical`. */
|
|
15
|
+
readonly scheme: string;
|
|
16
|
+
/** Optional per-provider timeout override (ms). Falls back to the resolver default. */
|
|
17
|
+
readonly timeoutMs?: number;
|
|
18
|
+
/** Resolve the path portion of a ref to its secret value, or throw. */
|
|
19
|
+
resolve(path: string, ctx?: SecretResolveContext): Promise<string>;
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,MAAM,WAAW,oBAAoB;IACnC,gFAAgF;IAChF,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB;AAED,MAAM,WAAW,cAAc;IAC7B,2EAA2E;IAC3E,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,uFAAuF;IACvF,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,uEAAuE;IACvE,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,oBAAoB,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;CACpE"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Secret-provider interface (S4.1, spec §6) and the resolver contract (S0.9).
|
|
3
|
+
*
|
|
4
|
+
* A provider resolves the `path` portion of a `${scheme:path}` reference to a value. It may
|
|
5
|
+
* touch env/fs/network (this package is impure by design); it is injected into the pure
|
|
6
|
+
* core. Resolution is **fail-closed**: any failure aborts the whole operation — a blank or
|
|
7
|
+
* partial secret is NEVER injected.
|
|
8
|
+
*/
|
|
9
|
+
export {};
|
|
10
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG"}
|
package/package.json
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@mcpfold/secrets",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Secret providers (env, dotenv, infisical, keychain, 1Password) and the fail-closed resolver.",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"main": "./dist/index.js",
|
|
8
|
+
"types": "./dist/index.d.ts",
|
|
9
|
+
"exports": {
|
|
10
|
+
".": {
|
|
11
|
+
"types": "./dist/index.d.ts",
|
|
12
|
+
"import": "./dist/index.js"
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
"files": [
|
|
16
|
+
"dist"
|
|
17
|
+
],
|
|
18
|
+
"dependencies": {
|
|
19
|
+
"@mcpfold/core": "1.0.0"
|
|
20
|
+
},
|
|
21
|
+
"publishConfig": {
|
|
22
|
+
"access": "public"
|
|
23
|
+
},
|
|
24
|
+
"repository": {
|
|
25
|
+
"type": "git",
|
|
26
|
+
"url": "git+https://github.com/dj-pearson/MCPFold.git",
|
|
27
|
+
"directory": "packages/secrets"
|
|
28
|
+
},
|
|
29
|
+
"homepage": "https://mcpfold.com",
|
|
30
|
+
"bugs": {
|
|
31
|
+
"url": "https://github.com/dj-pearson/MCPFold/issues"
|
|
32
|
+
},
|
|
33
|
+
"scripts": {
|
|
34
|
+
"build": "tsc -p tsconfig.build.json",
|
|
35
|
+
"test": "vitest run",
|
|
36
|
+
"lint": "eslint . --max-warnings=0",
|
|
37
|
+
"typecheck": "tsc --noEmit"
|
|
38
|
+
}
|
|
39
|
+
}
|