@seekrit/cli 0.24.0 → 0.26.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 +6 -1
- package/dist/index.js +933 -521
- package/dist/{mcp-t-sJ_SvE.js → mcp-DLplPOvz.js} +75 -4
- package/package.json +2 -2
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { A as
|
|
1
|
+
import { A as verifyMessage, B as toBase64, C as isServiceToken, D as importVerifyingKey, E as importSigningKey, F as kmsBlobKeyRef, I as kmsDecrypt, L as kmsEncrypt, M as generateMysqlCredential, N as generateDataKey, O as signMessage, P as generateEncryptKeyMaterial, R as wrapDek, S as createServiceToken, T as generateSigningKeyMaterial, V as parseBranchTtl, _ as isTokenAuth, a as ensureM2mAdminToken, b as writeProjectConfig, c as kmsResolveKey, d as resolveAppEnv, f as resolveBranch, g as getDek, h as resolveOrg, i as materializeEnv, j as generatePostgresCredential, k as signatureKeyRef, l as kmsResolveRecipient, m as resolveGroup, n as fetchDecryptedSecrets, o as kmsCallerIdentity, p as resolveEnvTarget, r as fetchDecryptedVersion, s as kmsRecoverMaterial, t as encryptAndSetSecret, u as resolveApp, v as tryBuildContext, w as parseServiceToken, x as version, y as setFailThrows, z as generateDek } from "./index.js";
|
|
2
2
|
import { spawn } from "node:child_process";
|
|
3
3
|
import { z } from "zod";
|
|
4
4
|
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
@@ -159,6 +159,7 @@ async function materializeFor(ctx, o) {
|
|
|
159
159
|
if (!isTokenAuth(ctx)) envId = (await resolveAppEnv(ctx, o)).envId;
|
|
160
160
|
return materializeEnv(ctx, {
|
|
161
161
|
envId,
|
|
162
|
+
branch: o.branch,
|
|
162
163
|
with: o.with,
|
|
163
164
|
envFiles: o.envFile ?? [".env"]
|
|
164
165
|
});
|
|
@@ -252,6 +253,24 @@ async function runMcpServer(options = {}) {
|
|
|
252
253
|
if (!appRow) throw new Error(`no app "${app}" in ${orgRef.slug}`);
|
|
253
254
|
return (await ctx.client.listEnvs(orgRef.id, appRow.id)).environments;
|
|
254
255
|
});
|
|
256
|
+
tool("list_branches", "List ephemeral branch configs in an application (optionally just one environment's).", {
|
|
257
|
+
org: z.string().optional(),
|
|
258
|
+
app: z.string(),
|
|
259
|
+
env: z.string().optional()
|
|
260
|
+
}, async ({ org, app, env }) => {
|
|
261
|
+
const ctx = getCtx();
|
|
262
|
+
const appRef = await resolveApp(ctx, {
|
|
263
|
+
org,
|
|
264
|
+
app
|
|
265
|
+
});
|
|
266
|
+
if (!env) return (await ctx.client.listAppBranches(appRef.orgId, appRef.id)).branches;
|
|
267
|
+
const parent = await resolveAppEnv(ctx, {
|
|
268
|
+
org,
|
|
269
|
+
app,
|
|
270
|
+
env
|
|
271
|
+
});
|
|
272
|
+
return (await ctx.client.listBranches(parent.orgId, parent.envId)).branches;
|
|
273
|
+
});
|
|
255
274
|
tool("list_groups", "List shared groups (reusable secret bags) in an organization.", { org: z.string().optional() }, async ({ org }) => {
|
|
256
275
|
const ctx = getCtx();
|
|
257
276
|
const orgRef = await resolveOrg(ctx, org);
|
|
@@ -514,6 +533,55 @@ async function runMcpServer(options = {}) {
|
|
|
514
533
|
wrappedDek
|
|
515
534
|
})).environment;
|
|
516
535
|
});
|
|
536
|
+
tool("create_branch", "Fork an environment into an ephemeral branch (a per-PR / preview config). The branch inherits the parent's secrets by layering at read time — nothing is copied or re-encrypted — and holds only the values you override on it. Generates the branch's data key locally, grants it to the caller, and shares it with the parent's other readers.", {
|
|
537
|
+
org: z.string().optional(),
|
|
538
|
+
app: z.string(),
|
|
539
|
+
from: z.string().describe("the environment to branch"),
|
|
540
|
+
slug: z.string().describe("the branch name, e.g. pr-142"),
|
|
541
|
+
ttl: z.string().optional().describe("lifetime: 12h, 7d, 2w, … or `never` (default 7d)")
|
|
542
|
+
}, async ({ org, app, from, slug, ttl }) => {
|
|
543
|
+
const ctx = getCtx();
|
|
544
|
+
const parent = await resolveAppEnv(ctx, {
|
|
545
|
+
org,
|
|
546
|
+
app,
|
|
547
|
+
env: from
|
|
548
|
+
});
|
|
549
|
+
const parsedTtl = parseBranchTtl(ttl ?? "7d");
|
|
550
|
+
if (parsedTtl === null) throw new Error(`invalid ttl "${ttl}" (try 12h, 7d, 2w, or never)`);
|
|
551
|
+
const me = await kmsCallerIdentity(ctx);
|
|
552
|
+
const dek = generateDek();
|
|
553
|
+
const wrappedDek = await wrapDek(dek, me.publicKeyJwk);
|
|
554
|
+
const grants = [];
|
|
555
|
+
const { grantees } = await ctx.client.listGrantees(parent.orgId, parent.envId);
|
|
556
|
+
for (const grantee of grantees) {
|
|
557
|
+
if (grantee.principalType === me.principalType && grantee.principalId === me.principalId) continue;
|
|
558
|
+
grants.push({
|
|
559
|
+
principalType: grantee.principalType,
|
|
560
|
+
principalId: grantee.principalId,
|
|
561
|
+
wrappedDek: await wrapDek(dek, grantee.publicKeyJwk)
|
|
562
|
+
});
|
|
563
|
+
}
|
|
564
|
+
return (await ctx.client.createBranch(parent.orgId, parent.envId, {
|
|
565
|
+
slug,
|
|
566
|
+
ttlSeconds: Number.isFinite(parsedTtl) ? parsedTtl : null,
|
|
567
|
+
wrappedDek,
|
|
568
|
+
grants
|
|
569
|
+
})).branch;
|
|
570
|
+
});
|
|
571
|
+
tool("delete_branch", "Tear down a branch config and every value it overrode. The parent environment is untouched.", {
|
|
572
|
+
org: z.string().optional(),
|
|
573
|
+
app: z.string(),
|
|
574
|
+
branch: z.string()
|
|
575
|
+
}, async ({ org, app, branch }) => {
|
|
576
|
+
const ctx = getCtx();
|
|
577
|
+
const appRef = await resolveApp(ctx, {
|
|
578
|
+
org,
|
|
579
|
+
app
|
|
580
|
+
});
|
|
581
|
+
const target = await resolveBranch(ctx, appRef, branch);
|
|
582
|
+
await ctx.client.deleteBranch(appRef.orgId, target.id);
|
|
583
|
+
return { deleted: target.slug };
|
|
584
|
+
});
|
|
517
585
|
tool("create_group_env", "Create a group environment. Generates the data key locally and grants it to the caller.", {
|
|
518
586
|
org: z.string().optional(),
|
|
519
587
|
group: z.string(),
|
|
@@ -573,7 +641,7 @@ async function runMcpServer(options = {}) {
|
|
|
573
641
|
await ctx.client.unlinkEnvGroup(target.orgId, target.envId, g.id);
|
|
574
642
|
return { ok: true };
|
|
575
643
|
});
|
|
576
|
-
tool("set_secret", "Encrypt a value locally and store it in an environment.", {
|
|
644
|
+
tool("set_secret", "Encrypt a value locally and store it in an environment. A value may reference another secret as ${OTHER_SECRET}: the reference is stored literally and expanded whenever the secret is read, so it tracks the referenced value. Write $${OTHER_SECRET} for a literal.", {
|
|
577
645
|
...targetShape,
|
|
578
646
|
name: z.string(),
|
|
579
647
|
value: z.string()
|
|
@@ -587,10 +655,11 @@ async function runMcpServer(options = {}) {
|
|
|
587
655
|
name: o.name
|
|
588
656
|
};
|
|
589
657
|
});
|
|
590
|
-
tool("get_secret", "Return one secret. By default only reports presence + version; pass reveal:true to decrypt the plaintext into this response (avoid unless the value is actually needed — prefer run_command). Pass `version` to read an earlier version instead of the current one.", {
|
|
658
|
+
tool("get_secret", "Return one secret. By default only reports presence + version; pass reveal:true to decrypt the plaintext into this response (avoid unless the value is actually needed — prefer run_command). A revealed current value has its ${OTHER_SECRET} references expanded against this environment's own secrets; pass raw:true for the stored text instead. Pass `version` to read an earlier version instead of the current one (always as stored, never expanded).", {
|
|
591
659
|
...targetShape,
|
|
592
660
|
name: z.string(),
|
|
593
661
|
reveal: z.boolean().optional(),
|
|
662
|
+
raw: z.boolean().optional().describe("skip ${OTHER_SECRET} expansion (with reveal)"),
|
|
594
663
|
version: z.number().int().positive().optional().describe("an earlier version from list_secret_versions (default: current)")
|
|
595
664
|
}, async (o) => {
|
|
596
665
|
const ctx = getCtx();
|
|
@@ -615,7 +684,7 @@ async function runMcpServer(options = {}) {
|
|
|
615
684
|
revealed: true
|
|
616
685
|
};
|
|
617
686
|
}
|
|
618
|
-
const values = await fetchDecryptedSecrets(ctx, orgId, envId);
|
|
687
|
+
const values = await fetchDecryptedSecrets(ctx, orgId, envId, { raw: o.raw });
|
|
619
688
|
if (!(o.name in values)) throw new Error(`no secret named ${o.name}`);
|
|
620
689
|
return {
|
|
621
690
|
name: o.name,
|
|
@@ -674,6 +743,7 @@ async function runMcpServer(options = {}) {
|
|
|
674
743
|
org: z.string().optional(),
|
|
675
744
|
app: z.string().optional(),
|
|
676
745
|
env: z.string().optional().describe("environment slug (token auth infers this)"),
|
|
746
|
+
branch: z.string().optional().describe("read an ephemeral branch of that environment"),
|
|
677
747
|
with: z.record(z.string(), z.string()).optional().describe("group=env slice overrides"),
|
|
678
748
|
envFile: z.array(z.string()).optional().describe(".env files to overlay (default [.env])"),
|
|
679
749
|
cwd: z.string().optional()
|
|
@@ -695,6 +765,7 @@ async function runMcpServer(options = {}) {
|
|
|
695
765
|
org: z.string().optional(),
|
|
696
766
|
app: z.string().optional(),
|
|
697
767
|
env: z.string().optional(),
|
|
768
|
+
branch: z.string().optional().describe("read an ephemeral branch of that environment"),
|
|
698
769
|
with: z.record(z.string(), z.string()).optional()
|
|
699
770
|
}, async (o) => {
|
|
700
771
|
const ctx = getCtx();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@seekrit/cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.26.0",
|
|
4
4
|
"description": "End-to-end encrypted secrets manager CLI — inject decrypted secrets into any command.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"publishConfig": {
|
|
@@ -26,8 +26,8 @@
|
|
|
26
26
|
"devDependencies": {
|
|
27
27
|
"@types/node": "^26.1.0",
|
|
28
28
|
"tsdown": "^0.22.3",
|
|
29
|
-
"@seekrit/api-client": "0.0.1",
|
|
30
29
|
"@seekrit/core": "0.0.1",
|
|
30
|
+
"@seekrit/api-client": "0.0.1",
|
|
31
31
|
"@seekrit/crypto": "0.0.1"
|
|
32
32
|
},
|
|
33
33
|
"scripts": {
|