@seekrit/cli 2.1.0 → 2.2.1

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.
@@ -3,7 +3,7 @@ import { z } from "zod";
3
3
  import { spawn } from "node:child_process";
4
4
  import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
5
5
  import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
6
- //#region src/mcp.ts
6
+ // src/mcp.ts
7
7
  /** Lowercase-alphanumeric string for a fresh Postgres role name. */
8
8
  function randomLower(length) {
9
9
  const alphabet = "abcdefghijklmnopqrstuvwxyz0123456789";
@@ -527,7 +527,8 @@ async function runMcpServer(options = {}) {
527
527
  return (await ctx.client.createEnv(orgRef.id, appRow.id, {
528
528
  name,
529
529
  slug,
530
- wrappedDek
530
+ wrappedDek,
531
+ userGrants: await ctx.client.wrapNewEnvironmentAccess(orgRef.id, { appId: appRow.id }, dek)
531
532
  })).environment;
532
533
  });
533
534
  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.", { idempotent: false }, {
@@ -595,7 +596,8 @@ async function runMcpServer(options = {}) {
595
596
  return (await ctx.client.createGroupEnv(g.orgId, g.id, {
596
597
  name,
597
598
  slug,
598
- wrappedDek
599
+ wrappedDek,
600
+ userGrants: await ctx.client.wrapNewEnvironmentAccess(g.orgId, { groupId: g.id }, dek)
599
601
  })).environment;
600
602
  });
601
603
  tool("compose_group", "Compose a group into an application environment (higher position wins on name clashes).", { idempotent: true }, {
@@ -617,6 +619,7 @@ async function runMcpServer(options = {}) {
617
619
  });
618
620
  const syncGrants = await syncGrantsForGroupLink(ctx, target.orgId, target.envId, target.envSlug, g.id);
619
621
  return (await ctx.client.linkEnvGroup(target.orgId, target.envId, {
622
+ appAccessGrants: await ctx.client.wrapGroupAppAccess(target.orgId, target.envId, g.id, (id) => getDek(ctx, target.orgId, id)),
620
623
  groupId: g.id,
621
624
  position,
622
625
  syncGrants
@@ -819,32 +822,21 @@ async function runMcpServer(options = {}) {
819
822
  env
820
823
  }) : { orgId: (await resolveOrg(ctx, org)).id };
821
824
  const created = await createServiceToken();
825
+ if (boundToEnv) ensureDecryptable(ctx);
826
+ const initialGrants = "envId" in target ? await ctx.client.prepareComposedKeyGrants(target.orgId, target.envId, {
827
+ principalType: "service_token",
828
+ principalId: created.tokenId,
829
+ publicKeyJwk: created.publicKeyJwk
830
+ }, (id) => getDek(ctx, target.orgId, id)) : void 0;
822
831
  await ctx.client.createToken(target.orgId, {
823
832
  name,
824
833
  tokenId: created.tokenId,
825
834
  tokenHash: created.tokenHash,
826
835
  publicKeyJwk: created.publicKeyJwk,
827
836
  role,
828
- environmentId: "envId" in target ? target.envId : null
837
+ environmentId: "envId" in target ? target.envId : null,
838
+ initialGrants
829
839
  });
830
- if (boundToEnv && "envId" in target) {
831
- ensureDecryptable(ctx);
832
- const grantEnv = async (envId) => {
833
- const dek = await getDek(ctx, target.orgId, envId);
834
- await ctx.client.grantEnvKey(target.orgId, envId, {
835
- principalType: "service_token",
836
- principalId: created.tokenId,
837
- wrappedDek: await wrapDek(dek, created.publicKeyJwk)
838
- });
839
- };
840
- await grantEnv(target.envId);
841
- const { groups } = await ctx.client.listEnvGroups(target.orgId, target.envId);
842
- for (const g of groups) {
843
- const { environments } = await ctx.client.listGroupEnvs(target.orgId, g.groupId);
844
- const slice = environments.find((e) => e.slug === target.envSlug);
845
- if (slice) await grantEnv(slice.id);
846
- }
847
- }
848
840
  return {
849
841
  token: created.token,
850
842
  tokenId: created.tokenId,
@@ -873,7 +865,6 @@ async function runMcpServer(options = {}) {
873
865
  const ctx = getCtx();
874
866
  ensureDecryptable(ctx);
875
867
  const { orgId, envId, label } = await resolveEnvTarget(ctx, o);
876
- const dek = await getDek(ctx, orgId, envId);
877
868
  let principalType;
878
869
  let principalId;
879
870
  let publicKeyJwk;
@@ -897,11 +888,11 @@ async function runMcpServer(options = {}) {
897
888
  t.publicKeyJwk
898
889
  ];
899
890
  }
900
- await ctx.client.grantEnvKey(orgId, envId, {
891
+ await ctx.client.grantEnvironmentAccess(orgId, envId, {
901
892
  principalType,
902
893
  principalId,
903
- wrappedDek: await wrapDek(dek, publicKeyJwk)
904
- });
894
+ publicKeyJwk
895
+ }, (id) => getDek(ctx, orgId, id));
905
896
  return {
906
897
  ok: true,
907
898
  env: label,
@@ -1032,5 +1023,4 @@ async function runMcpServer(options = {}) {
1032
1023
  });
1033
1024
  await server.connect(new StdioServerTransport());
1034
1025
  }
1035
- //#endregion
1036
1026
  export { runMcpServer };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@seekrit/cli",
3
- "version": "2.1.0",
3
+ "version": "2.2.1",
4
4
  "description": "End-to-end encrypted secrets manager CLI — inject decrypted secrets into any command.",
5
5
  "homepage": "https://seekrit.dev/docs/guides/cli",
6
6
  "keywords": [
@@ -38,13 +38,13 @@
38
38
  "node": ">=20"
39
39
  },
40
40
  "dependencies": {
41
- "@modelcontextprotocol/sdk": "^1.32.1",
41
+ "@modelcontextprotocol/sdk": "^1.32.2",
42
42
  "commander": "^15.0.0",
43
43
  "zod": "^4.6.7"
44
44
  },
45
45
  "devDependencies": {
46
46
  "@types/node": "^26.6.5",
47
- "tsdown": "^0.23.1",
47
+ "tsdown": "^0.23.3",
48
48
  "vitest": "^5.0.5",
49
49
  "@seekrit/api-client": "0.0.1",
50
50
  "@seekrit/core": "0.0.1",