@seekrit/cli 1.7.0 → 1.8.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/dist/index.js
CHANGED
|
@@ -2174,7 +2174,12 @@ z.object({
|
|
|
2174
2174
|
z.object({
|
|
2175
2175
|
groupId: z.string().min(1),
|
|
2176
2176
|
/** Precedence among an env's groups (higher wins). Appended if omitted. */
|
|
2177
|
-
position: z.number().int().min(0).optional()
|
|
2177
|
+
position: z.number().int().min(0).optional(),
|
|
2178
|
+
/** Client-wrapped group DEK for each sync connection newly reading this group. */
|
|
2179
|
+
syncGrants: z.array(z.object({
|
|
2180
|
+
connectionId: z.string().min(1),
|
|
2181
|
+
wrappedDek: z.string().min(1)
|
|
2182
|
+
})).optional()
|
|
2178
2183
|
});
|
|
2179
2184
|
z.object({
|
|
2180
2185
|
name: nameSchema,
|
|
@@ -2555,7 +2560,8 @@ const SYNC_PROVIDER_KINDS = [
|
|
|
2555
2560
|
"gcp-secret-manager",
|
|
2556
2561
|
"langgraph-platform",
|
|
2557
2562
|
"azure-key-vault",
|
|
2558
|
-
"huggingface-spaces"
|
|
2563
|
+
"huggingface-spaces",
|
|
2564
|
+
"openai-vault"
|
|
2559
2565
|
];
|
|
2560
2566
|
z.enum(SYNC_PROVIDER_KINDS);
|
|
2561
2567
|
/**
|
|
@@ -2959,6 +2965,8 @@ const azureKeyVaultConnectionConfigSchema = z.object({
|
|
|
2959
2965
|
* would invite pointing a connection at a host that silently swallows secrets.
|
|
2960
2966
|
*/
|
|
2961
2967
|
const huggingfaceSpacesConnectionConfigSchema = z.object({ provider: z.literal("huggingface-spaces") });
|
|
2968
|
+
/** The wrapped credential is an OpenAI project API key with vault read/write access. */
|
|
2969
|
+
const openaiVaultConnectionConfigSchema = z.object({ provider: z.literal("openai-vault") });
|
|
2962
2970
|
const syncConnectionConfigSchema = z.discriminatedUnion("provider", [
|
|
2963
2971
|
vercelConnectionConfigSchema,
|
|
2964
2972
|
cloudflareWorkersConnectionConfigSchema,
|
|
@@ -2978,7 +2986,8 @@ const syncConnectionConfigSchema = z.discriminatedUnion("provider", [
|
|
|
2978
2986
|
gcpSecretManagerConnectionConfigSchema,
|
|
2979
2987
|
langgraphPlatformConnectionConfigSchema,
|
|
2980
2988
|
azureKeyVaultConnectionConfigSchema,
|
|
2981
|
-
huggingfaceSpacesConnectionConfigSchema
|
|
2989
|
+
huggingfaceSpacesConnectionConfigSchema,
|
|
2990
|
+
openaiVaultConnectionConfigSchema
|
|
2982
2991
|
]);
|
|
2983
2992
|
/** Vercel's three deployment targets. A binding writes to one or more. */
|
|
2984
2993
|
const VERCEL_TARGETS = [
|
|
@@ -3803,6 +3812,12 @@ const huggingfaceSpacesDestinationSchema = z.object({
|
|
|
3803
3812
|
/** Space ID as `owner/name`, e.g. `acme/support-demo`. */
|
|
3804
3813
|
repoId: huggingfaceRepoIdSchema
|
|
3805
3814
|
});
|
|
3815
|
+
/** One existing OpenAI vault; every credential in this binding gets the same host boundary. */
|
|
3816
|
+
const openaiVaultDestinationSchema = z.object({
|
|
3817
|
+
provider: z.literal("openai-vault"),
|
|
3818
|
+
vaultId: z.string().trim().regex(/^vault_[A-Za-z0-9_-]+$/, "must be an OpenAI vault ID"),
|
|
3819
|
+
allowedHosts: z.array(z.string().trim().toLowerCase().max(253).regex(/^(?=.{1,253}$)[a-z0-9](?:[a-z0-9-]*[a-z0-9])?(?:\.[a-z0-9](?:[a-z0-9-]*[a-z0-9])?)+$/, "must be an exact hostname without scheme, port, path, or wildcard")).min(1).max(100).refine((hosts) => new Set(hosts).size === hosts.length, "hostnames must be unique")
|
|
3820
|
+
});
|
|
3806
3821
|
const syncDestinationSchema = z.discriminatedUnion("provider", [
|
|
3807
3822
|
vercelDestinationSchema,
|
|
3808
3823
|
cloudflareWorkersDestinationSchema,
|
|
@@ -3822,7 +3837,8 @@ const syncDestinationSchema = z.discriminatedUnion("provider", [
|
|
|
3822
3837
|
gcpSecretManagerDestinationSchema,
|
|
3823
3838
|
langgraphPlatformDestinationSchema,
|
|
3824
3839
|
azureKeyVaultDestinationSchema,
|
|
3825
|
-
huggingfaceSpacesDestinationSchema
|
|
3840
|
+
huggingfaceSpacesDestinationSchema,
|
|
3841
|
+
openaiVaultDestinationSchema
|
|
3826
3842
|
]);
|
|
3827
3843
|
/**
|
|
3828
3844
|
* How seekrit secret names become destination key names. Applied in order:
|
|
@@ -5110,7 +5126,7 @@ async function createAgentTaskToken() {
|
|
|
5110
5126
|
}
|
|
5111
5127
|
//#endregion
|
|
5112
5128
|
//#region package.json
|
|
5113
|
-
var version = "1.
|
|
5129
|
+
var version = "1.8.0";
|
|
5114
5130
|
//#endregion
|
|
5115
5131
|
//#region ../../packages/api-client/src/index.ts
|
|
5116
5132
|
/**
|
|
@@ -7646,6 +7662,32 @@ function registerEnvDiff(env) {
|
|
|
7646
7662
|
});
|
|
7647
7663
|
}
|
|
7648
7664
|
//#endregion
|
|
7665
|
+
//#region src/group-sync-grants.ts
|
|
7666
|
+
/** Wrap a newly composed group layer for connections already syncing the app env or its branches. */
|
|
7667
|
+
async function syncGrantsForGroupLink(ctx, orgId, envId, envSlug, groupId) {
|
|
7668
|
+
const [{ groups }, { bindings }, { branches }] = await Promise.all([
|
|
7669
|
+
ctx.client.listEnvGroups(orgId, envId),
|
|
7670
|
+
ctx.client.listSyncBindings(orgId),
|
|
7671
|
+
ctx.client.listBranches(orgId, envId)
|
|
7672
|
+
]);
|
|
7673
|
+
if (groups.some((group) => group.groupId === groupId)) return void 0;
|
|
7674
|
+
const targets = /* @__PURE__ */ new Set([envId, ...branches.map((branch) => branch.id)]);
|
|
7675
|
+
const connectionIds = new Set(bindings.filter((binding) => targets.has(binding.environmentId)).map((b) => b.connectionId));
|
|
7676
|
+
if (connectionIds.size === 0) return void 0;
|
|
7677
|
+
const [{ environments }, { connections }] = await Promise.all([ctx.client.listGroupEnvs(orgId, groupId), ctx.client.listSyncConnections(orgId)]);
|
|
7678
|
+
const groupEnv = environments.find((entry) => entry.slug === envSlug);
|
|
7679
|
+
if (!groupEnv) fail(`create a ${envSlug} environment in this group before composing it`);
|
|
7680
|
+
const dek = await getDek(ctx, orgId, groupEnv.id);
|
|
7681
|
+
return Promise.all([...connectionIds].map(async (connectionId) => {
|
|
7682
|
+
const connection = connections.find((entry) => entry.id === connectionId);
|
|
7683
|
+
if (!connection) fail("a sync connection could not be found; refresh and retry");
|
|
7684
|
+
return {
|
|
7685
|
+
connectionId,
|
|
7686
|
+
wrappedDek: await wrapDek(dek, connection.publicKeyJwk)
|
|
7687
|
+
};
|
|
7688
|
+
}));
|
|
7689
|
+
}
|
|
7690
|
+
//#endregion
|
|
7649
7691
|
//#region src/kms.ts
|
|
7650
7692
|
/** Collect a repeatable option into a list. */
|
|
7651
7693
|
function collect$8(value, acc = []) {
|
|
@@ -8308,9 +8350,11 @@ function registerAppCommands(program) {
|
|
|
8308
8350
|
org: options.org,
|
|
8309
8351
|
group: options.group
|
|
8310
8352
|
});
|
|
8353
|
+
const syncGrants = await syncGrantsForGroupLink(ctx, target.orgId, target.envId, target.envSlug, group.id);
|
|
8311
8354
|
await ctx.client.linkEnvGroup(target.orgId, target.envId, {
|
|
8312
8355
|
groupId: group.id,
|
|
8313
|
-
position: options.position === void 0 ? void 0 : Number.parseInt(options.position, 10)
|
|
8356
|
+
position: options.position === void 0 ? void 0 : Number.parseInt(options.position, 10),
|
|
8357
|
+
syncGrants
|
|
8314
8358
|
});
|
|
8315
8359
|
console.error(`composed ${group.slug} into ${target.appSlug}/${target.envSlug}`);
|
|
8316
8360
|
});
|
|
@@ -11848,7 +11892,7 @@ function collect$4(value, acc) {
|
|
|
11848
11892
|
* release-please-config.json), so the pin follows the crate without anyone
|
|
11849
11893
|
* remembering to move it.
|
|
11850
11894
|
*/
|
|
11851
|
-
const PROXY_VERSION = "0.12.
|
|
11895
|
+
const PROXY_VERSION = "0.12.2";
|
|
11852
11896
|
const BIN = "seekrit-proxy";
|
|
11853
11897
|
/**
|
|
11854
11898
|
* Host → Rust target triple.
|
|
@@ -11884,7 +11928,7 @@ function versionPrefix(version) {
|
|
|
11884
11928
|
return version.startsWith("v") ? version : `v${version}`;
|
|
11885
11929
|
}
|
|
11886
11930
|
function resolveVersion(explicit) {
|
|
11887
|
-
return explicit ?? process.env.SEEKRIT_PROXY_VERSION ?? "0.12.
|
|
11931
|
+
return explicit ?? process.env.SEEKRIT_PROXY_VERSION ?? "0.12.2";
|
|
11888
11932
|
}
|
|
11889
11933
|
function resolveBaseUrl(explicit) {
|
|
11890
11934
|
return (explicit ?? process.env.SEEKRIT_PROXY_BASE_URL ?? "https://proxy.seekrit.dev").replace(/\/+$/, "");
|
|
@@ -12042,7 +12086,7 @@ const PLUGIN_BIN = "seekrit-nomad-secrets";
|
|
|
12042
12086
|
* entry in release-please-config.json), so the pin follows the crate without
|
|
12043
12087
|
* anyone remembering to move it — the same arrangement `PROXY_VERSION` has.
|
|
12044
12088
|
*/
|
|
12045
|
-
const NOMAD_PLUGIN_VERSION = "0.2.
|
|
12089
|
+
const NOMAD_PLUGIN_VERSION = "0.2.1";
|
|
12046
12090
|
/** Public artifact host. Mirrors GitHub Releases; public, no egress fees. */
|
|
12047
12091
|
const DEFAULT_BASE_URL = "https://nomad.seekrit.dev";
|
|
12048
12092
|
/** Where the plugin reads its node config, matching `config::DEFAULT_CONFIG_PATH`. */
|
|
@@ -12129,7 +12173,7 @@ async function fetchBytes(url) {
|
|
|
12129
12173
|
* let Nomad fingerprint a half-written executable.
|
|
12130
12174
|
*/
|
|
12131
12175
|
async function installPlugin(pluginDir, options = {}) {
|
|
12132
|
-
const version = options.version ?? "0.2.
|
|
12176
|
+
const version = options.version ?? "0.2.1";
|
|
12133
12177
|
const baseUrl = (options.baseUrl ?? "https://nomad.seekrit.dev").replace(/\/+$/, "");
|
|
12134
12178
|
const { target, exe } = detectTarget();
|
|
12135
12179
|
if (exe !== "") fail("Nomad secret provider plugins are not supported on Windows clients");
|
|
@@ -13834,10 +13878,10 @@ Next:
|
|
|
13834
13878
|
});
|
|
13835
13879
|
console.log(path);
|
|
13836
13880
|
const { target } = detectTarget();
|
|
13837
|
-
process.stderr.write(`seekrit-proxy ${versionPrefix(options.proxyVersion ?? "0.12.
|
|
13881
|
+
process.stderr.write(`seekrit-proxy ${versionPrefix(options.proxyVersion ?? "0.12.2")} (${target})\n`);
|
|
13838
13882
|
});
|
|
13839
13883
|
proxy.command("where").description("show which binary `seekrit proxy run` would use, without fetching it").option("--proxy-version <version>", `version to report (default: ${PROXY_VERSION})`).option("--json", "machine-readable output").action((options) => {
|
|
13840
|
-
const version = options.proxyVersion ?? process.env.SEEKRIT_PROXY_VERSION ?? "0.12.
|
|
13884
|
+
const version = options.proxyVersion ?? process.env.SEEKRIT_PROXY_VERSION ?? "0.12.2";
|
|
13841
13885
|
const override = process.env.SEEKRIT_PROXY_BIN;
|
|
13842
13886
|
const { target, exe } = detectTarget();
|
|
13843
13887
|
const path = override ?? proxyBinaryPath(version, target, exe);
|
|
@@ -13896,7 +13940,7 @@ Next:
|
|
|
13896
13940
|
process.stdout.write(renderComposeSnippet(plan, {
|
|
13897
13941
|
service: options.service,
|
|
13898
13942
|
workload: options.workload,
|
|
13899
|
-
image: options.image ?? `seekritdev/proxy:0.12.
|
|
13943
|
+
image: options.image ?? `seekritdev/proxy:0.12.2`,
|
|
13900
13944
|
publish: Boolean(options.publish)
|
|
13901
13945
|
}));
|
|
13902
13946
|
});
|
|
@@ -14522,6 +14566,7 @@ function credentialNoun(provider) {
|
|
|
14522
14566
|
if (provider === "langgraph-platform") return "LangSmith API key";
|
|
14523
14567
|
if (provider === "azure-key-vault") return "client secret";
|
|
14524
14568
|
if (provider === "huggingface-spaces") return "user access token";
|
|
14569
|
+
if (provider === "openai-vault") return "OpenAI project API key";
|
|
14525
14570
|
return "API token";
|
|
14526
14571
|
}
|
|
14527
14572
|
/**
|
|
@@ -14611,6 +14656,7 @@ function buildConfig(provider, options) {
|
|
|
14611
14656
|
};
|
|
14612
14657
|
}
|
|
14613
14658
|
case "huggingface-spaces": return { provider: "huggingface-spaces" };
|
|
14659
|
+
case "openai-vault": return { provider: "openai-vault" };
|
|
14614
14660
|
}
|
|
14615
14661
|
}
|
|
14616
14662
|
/** Where inside the platform a binding writes. */
|
|
@@ -14828,6 +14874,14 @@ function buildDestination(provider, options) {
|
|
|
14828
14874
|
provider: "huggingface-spaces",
|
|
14829
14875
|
repoId: assertHuggingfaceSpace(options.hfSpace)
|
|
14830
14876
|
};
|
|
14877
|
+
case "openai-vault":
|
|
14878
|
+
if (!options.openaiVault) fail("--openai-vault is required for openai-vault (vault_… ID)");
|
|
14879
|
+
if (!options.openaiHosts) fail("--openai-hosts is required for openai-vault");
|
|
14880
|
+
return {
|
|
14881
|
+
provider: "openai-vault",
|
|
14882
|
+
vaultId: options.openaiVault.trim(),
|
|
14883
|
+
allowedHosts: list(options.openaiHosts, "")
|
|
14884
|
+
};
|
|
14831
14885
|
}
|
|
14832
14886
|
}
|
|
14833
14887
|
/** One-line description of a destination, for list output. */
|
|
@@ -14851,6 +14905,7 @@ function describeDestination(destination) {
|
|
|
14851
14905
|
case "langgraph-platform": return `deployment ${destination.deploymentId}`;
|
|
14852
14906
|
case "azure-key-vault": return `${destination.vault}${destination.prefix ? ` (${destination.prefix}*)` : ""}`;
|
|
14853
14907
|
case "huggingface-spaces": return `space ${destination.repoId}`;
|
|
14908
|
+
case "openai-vault": return `${destination.vaultId} (${destination.allowedHosts.join(", ")})`;
|
|
14854
14909
|
case "github-actions": switch (destination.kind) {
|
|
14855
14910
|
case "repo": return `${destination.owner}/${destination.repo}`;
|
|
14856
14911
|
case "environment": return `${destination.owner}/${destination.repo} @${destination.environment}`;
|
|
@@ -14866,7 +14921,7 @@ function describeDestination(destination) {
|
|
|
14866
14921
|
* application whose environment the binding reads from.
|
|
14867
14922
|
*/
|
|
14868
14923
|
function destinationOptions(command) {
|
|
14869
|
-
return command.option("--project <id>", "vercel: project id or name · cloudflare-pages / northflank: project name or slug · bunnyshell: project ID (writes variables new environments inherit)").option("--target <list>", "vercel / cloudflare-pages: comma-separated deployment targets", "production").option("--git-branch <branch>", "vercel: restrict preview writes to one branch").option("--script <name>", "cloudflare-workers: Worker script name").option("--store-id <id>", "cloudflare-secrets-store: store ID (32 hex)").option("--scopes <list>", "cloudflare-secrets-store: comma-separated scopes", "workers").option("--railway-project <id>", "railway: project ID (a UUID)").option("--railway-environment <id>", "railway: environment ID (a UUID)").option("--service <id>", "railway: service ID (omit for the environment's shared variables) · render: service ID (srv-…, or crn-… for a cron job)").option("--skip-deploys", "railway: stage values without triggering a redeploy").option("--path <path>", "aws-parameter-store: hierarchy, e.g. /prod/storefront/ · aws-secrets-manager, azure-key-vault: name prefix").option("--layout <layout>", `aws-secrets-manager: ${AWS_SECRETS_MANAGER_LAYOUTS.join(" | ")}`).option("--secret-name <name>", "aws-secrets-manager: the secret a json-bundle writes to").option("--param-type <type>", `aws-parameter-store: ${AWS_PARAMETER_TYPES.join(" | ")}`).option("--tier <tier>", `aws-parameter-store: ${AWS_PARAMETER_TIERS.join(" | ")}`).option("--kms-key-id <id>", "aws: customer-managed KMS key id, ARN, or alias").option("--env-group <id>", "render: environment group ID (evg-…)").option("--fly-app <name>", "fly: app name, as `fly apps list` shows it").option("--secret-group <id>", "northflank: secret group ID (the slug in its URL)").option("--do-app <id>", "digitalocean: App Platform app ID (the UUID in its URL)").option("--component <name>", "digitalocean: write to one component's variables (omit for app-level)").option("--env-scope <scope>", `digitalocean: ${DIGITALOCEAN_ENV_SCOPES.join(" | ")}`).option("--heroku-app <name>", "heroku: app name, as `heroku apps` shows it (or its UUID)").option("--netlify-site <id>", "netlify: site API ID (the UUID under Project configuration)").option("--no-netlify-secret", "netlify: create readable variables instead of Netlify secrets (write-only)").option("--bunnyshell-environment <id>", "bunnyshell: environment ID (omit to write a project)").option("--no-bunnyshell-secret", "bunnyshell: create variables visible in the dashboard instead of secret ones").option("--gh-repo <owner/name>", "github-actions: repository, e.g. acme/storefront").option("--gh-environment <name>", "github-actions: write to one deployment environment's secrets (needs --gh-repo)").option("--gh-org <login>", "github-actions: write organization secrets instead of a repo's").option("--gh-visibility <v>", `github-actions org secrets: ${GITHUB_ACTIONS_VISIBILITIES.join(" | ")}`).option("--gh-repo-ids <ids>", "github-actions: comma-separated numeric repository IDs for --gh-visibility selected").option("--langgraph-deployment <id>", "langgraph-platform: deployment UUID (the one in its dashboard URL)").option("--gcp-prefix <prefix>", "gcp: prepended to every secret ID, e.g. prod-storefront-").option("--gcp-replication <policy>", `gcp: ${GCP_REPLICATION_POLICIES.join(" | ")}`, "automatic").option("--gcp-locations <list>", "gcp: regions for user-managed replication, e.g. us-east1").option("--gcp-kms-key <name>", "gcp: Cloud KMS key (projects/…/cryptoKeys/…)").option("--gcp-prune-versions", "gcp: destroy the version each push supersedes, keeping one active version").option("--vault <name>", "azure-key-vault: vault name, e.g. acme-prod").option("--hf-space <owner/name>", "huggingface-spaces: Space ID, e.g. acme/support-demo (its owner and name, not a URL)").option("--name-mode <mode>", `azure-key-vault: ${AZURE_KEY_VAULT_NAME_MODES.join(" | ")} — Key Vault stores no underscores, so DATABASE_URL becomes DATABASE-URL unless you reject instead`);
|
|
14924
|
+
return command.option("--project <id>", "vercel: project id or name · cloudflare-pages / northflank: project name or slug · bunnyshell: project ID (writes variables new environments inherit)").option("--target <list>", "vercel / cloudflare-pages: comma-separated deployment targets", "production").option("--git-branch <branch>", "vercel: restrict preview writes to one branch").option("--script <name>", "cloudflare-workers: Worker script name").option("--store-id <id>", "cloudflare-secrets-store: store ID (32 hex)").option("--scopes <list>", "cloudflare-secrets-store: comma-separated scopes", "workers").option("--railway-project <id>", "railway: project ID (a UUID)").option("--railway-environment <id>", "railway: environment ID (a UUID)").option("--service <id>", "railway: service ID (omit for the environment's shared variables) · render: service ID (srv-…, or crn-… for a cron job)").option("--skip-deploys", "railway: stage values without triggering a redeploy").option("--path <path>", "aws-parameter-store: hierarchy, e.g. /prod/storefront/ · aws-secrets-manager, azure-key-vault: name prefix").option("--layout <layout>", `aws-secrets-manager: ${AWS_SECRETS_MANAGER_LAYOUTS.join(" | ")}`).option("--secret-name <name>", "aws-secrets-manager: the secret a json-bundle writes to").option("--param-type <type>", `aws-parameter-store: ${AWS_PARAMETER_TYPES.join(" | ")}`).option("--tier <tier>", `aws-parameter-store: ${AWS_PARAMETER_TIERS.join(" | ")}`).option("--kms-key-id <id>", "aws: customer-managed KMS key id, ARN, or alias").option("--env-group <id>", "render: environment group ID (evg-…)").option("--fly-app <name>", "fly: app name, as `fly apps list` shows it").option("--secret-group <id>", "northflank: secret group ID (the slug in its URL)").option("--do-app <id>", "digitalocean: App Platform app ID (the UUID in its URL)").option("--component <name>", "digitalocean: write to one component's variables (omit for app-level)").option("--env-scope <scope>", `digitalocean: ${DIGITALOCEAN_ENV_SCOPES.join(" | ")}`).option("--heroku-app <name>", "heroku: app name, as `heroku apps` shows it (or its UUID)").option("--netlify-site <id>", "netlify: site API ID (the UUID under Project configuration)").option("--no-netlify-secret", "netlify: create readable variables instead of Netlify secrets (write-only)").option("--bunnyshell-environment <id>", "bunnyshell: environment ID (omit to write a project)").option("--no-bunnyshell-secret", "bunnyshell: create variables visible in the dashboard instead of secret ones").option("--gh-repo <owner/name>", "github-actions: repository, e.g. acme/storefront").option("--gh-environment <name>", "github-actions: write to one deployment environment's secrets (needs --gh-repo)").option("--gh-org <login>", "github-actions: write organization secrets instead of a repo's").option("--gh-visibility <v>", `github-actions org secrets: ${GITHUB_ACTIONS_VISIBILITIES.join(" | ")}`).option("--gh-repo-ids <ids>", "github-actions: comma-separated numeric repository IDs for --gh-visibility selected").option("--langgraph-deployment <id>", "langgraph-platform: deployment UUID (the one in its dashboard URL)").option("--gcp-prefix <prefix>", "gcp: prepended to every secret ID, e.g. prod-storefront-").option("--gcp-replication <policy>", `gcp: ${GCP_REPLICATION_POLICIES.join(" | ")}`, "automatic").option("--gcp-locations <list>", "gcp: regions for user-managed replication, e.g. us-east1").option("--gcp-kms-key <name>", "gcp: Cloud KMS key (projects/…/cryptoKeys/…)").option("--gcp-prune-versions", "gcp: destroy the version each push supersedes, keeping one active version").option("--vault <name>", "azure-key-vault: vault name, e.g. acme-prod").option("--openai-vault <id>", "openai-vault: existing OpenAI Vault ID (vault_…)").option("--openai-hosts <hosts>", "openai-vault: comma-separated exact HTTPS hostnames").option("--hf-space <owner/name>", "huggingface-spaces: Space ID, e.g. acme/support-demo (its owner and name, not a URL)").option("--name-mode <mode>", `azure-key-vault: ${AZURE_KEY_VAULT_NAME_MODES.join(" | ")} — Key Vault stores no underscores, so DATABASE_URL becomes DATABASE-URL unless you reject instead`);
|
|
14870
14925
|
}
|
|
14871
14926
|
/** Find a connection by id or name — nobody keeps `syc_…` ids in their head. */
|
|
14872
14927
|
async function resolveConnection(ctx, orgId, ref) {
|
|
@@ -15796,7 +15851,7 @@ registerKmsCommands(program);
|
|
|
15796
15851
|
registerRotationCommands(program);
|
|
15797
15852
|
registerRecoveryCommands(program);
|
|
15798
15853
|
program.command("mcp").description("run an MCP server over stdio so AI agents can drive seekrit").action(async () => {
|
|
15799
|
-
const { runMcpServer } = await import("./mcp-
|
|
15854
|
+
const { runMcpServer } = await import("./mcp-ZYu1Q6Ft.js");
|
|
15800
15855
|
await runMcpServer();
|
|
15801
15856
|
});
|
|
15802
15857
|
registerAuditCommands(program);
|
|
@@ -15811,4 +15866,4 @@ program.parseAsync(argv).catch((err) => {
|
|
|
15811
15866
|
fail(describeError(err));
|
|
15812
15867
|
});
|
|
15813
15868
|
//#endregion
|
|
15814
|
-
export {
|
|
15869
|
+
export { signatureKeyRef as A, generateDek as B, createServiceToken as C, importSigningKey as D, generateSigningKeyMaterial as E, generateEncryptKeyMaterial as F, parseBranchTtl as H, kmsBlobKeyRef as I, kmsDecrypt as L, generatePostgresCredential as M, generateMysqlCredential as N, importVerifyingKey as O, generateDataKey as P, kmsEncrypt as R, version as S, parseServiceToken as T, toBase64 as V, getDek as _, kmsResolveRecipient as a, setFailThrows as b, fetchDecryptedSecrets as c, resolveApp as d, resolveAppEnv as f, resolveOrg as g, resolveGroup as h, kmsResolveKey as i, verifyMessage as j, signMessage as k, fetchDecryptedVersion as l, resolveEnvTarget as m, kmsCallerIdentity as n, syncGrantsForGroupLink as o, resolveBranch as p, kmsRecoverMaterial as r, encryptAndSetSecret as s, ensureM2mAdminToken as t, materializeEnv as u, isTokenAuth as v, isServiceToken as w, writeProjectConfig as x, tryBuildContext as y, wrapDek as z };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { A as
|
|
1
|
+
import { A as signatureKeyRef, B as generateDek, C as createServiceToken, D as importSigningKey, E as generateSigningKeyMaterial, F as generateEncryptKeyMaterial, H as parseBranchTtl, I as kmsBlobKeyRef, L as kmsDecrypt, M as generatePostgresCredential, N as generateMysqlCredential, O as importVerifyingKey, P as generateDataKey, R as kmsEncrypt, S as version, T as parseServiceToken, V as toBase64, _ as getDek, a as kmsResolveRecipient, b as setFailThrows, c as fetchDecryptedSecrets, d as resolveApp, f as resolveAppEnv, g as resolveOrg, h as resolveGroup, i as kmsResolveKey, j as verifyMessage, k as signMessage, l as fetchDecryptedVersion, m as resolveEnvTarget, n as kmsCallerIdentity, o as syncGrantsForGroupLink, p as resolveBranch, r as kmsRecoverMaterial, s as encryptAndSetSecret, t as ensureM2mAdminToken, u as materializeEnv, v as isTokenAuth, w as isServiceToken, x as writeProjectConfig, y as tryBuildContext, z as wrapDek } 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";
|
|
@@ -621,9 +621,11 @@ async function runMcpServer(options = {}) {
|
|
|
621
621
|
org,
|
|
622
622
|
group
|
|
623
623
|
});
|
|
624
|
+
const syncGrants = await syncGrantsForGroupLink(ctx, target.orgId, target.envId, target.envSlug, g.id);
|
|
624
625
|
return (await ctx.client.linkEnvGroup(target.orgId, target.envId, {
|
|
625
626
|
groupId: g.id,
|
|
626
|
-
position
|
|
627
|
+
position,
|
|
628
|
+
syncGrants
|
|
627
629
|
})).group;
|
|
628
630
|
});
|
|
629
631
|
tool("uncompose_group", "Remove a composed group from an application environment.", { idempotent: true }, {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@seekrit/cli",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.8.0",
|
|
4
4
|
"description": "End-to-end encrypted secrets manager CLI — inject decrypted secrets into any command.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"publishConfig": {
|
|
@@ -24,12 +24,12 @@
|
|
|
24
24
|
"dependencies": {
|
|
25
25
|
"@modelcontextprotocol/sdk": "^1.30.0",
|
|
26
26
|
"commander": "^15.0.0",
|
|
27
|
-
"zod": "^4.6.
|
|
27
|
+
"zod": "^4.6.5"
|
|
28
28
|
},
|
|
29
29
|
"devDependencies": {
|
|
30
|
-
"@types/node": "^26.
|
|
30
|
+
"@types/node": "^26.6.1",
|
|
31
31
|
"tsdown": "^0.23.0",
|
|
32
|
-
"vitest": "^
|
|
32
|
+
"vitest": "^5.0.1",
|
|
33
33
|
"@seekrit/api-client": "0.0.1",
|
|
34
34
|
"@seekrit/core": "0.0.1",
|
|
35
35
|
"@seekrit/crypto": "0.0.1"
|