@seekrit/cli 2.6.0 → 2.7.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.
Files changed (2) hide show
  1. package/dist/index.js +331 -9
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -1752,6 +1752,229 @@ function prettyJsonOrRaw(value) {
1752
1752
  const inspection = inspectJsonValue(value);
1753
1753
  return inspection.kind === "json" ? inspection.pretty : value;
1754
1754
  }
1755
+ // ../../packages/core/src/managed-providers/aws-cache.ts
1756
+ const cacheRegionSchema = z$1.string().regex(/^[a-z]{2}(?:-[a-z]+)+-\d$/);
1757
+ const cacheGroupSchema = z$1.string().min(1).max(128).regex(/^[a-zA-Z][a-zA-Z0-9-]*$/);
1758
+ const cacheAccessSchema = z$1.string().min(1).max(4096).refine((value) => /^on(?:\s|$)/.test(value) && !/(?:^|\s)(?:nopass|resetpass|[>#<])/.test(value), "ACL must enable the user and must not contain password directives");
1759
+ // ../../packages/core/src/managed-providers/common.ts
1760
+ const managedEndpointSchema = z$1.string().url().max(2048).refine((value) => {
1761
+ try {
1762
+ const url = new URL(value);
1763
+ url.port = "";
1764
+ return connectUrlSchema.safeParse(url.toString()).success;
1765
+ } catch {
1766
+ return false;
1767
+ }
1768
+ }, "use a public HTTPS endpoint without embedded credentials, query, or fragment");
1769
+ const managedTtlSchema = z$1.number().int().min(60).max(604800).optional();
1770
+ const nameSchema$1 = z$1.string().min(1).max(128).regex(/^[a-zA-Z_][a-zA-Z0-9_-]*$/);
1771
+ // ../../packages/core/src/managed-providers/memorydb.ts
1772
+ const memorydbTargetConfigSchema = z$1.object({
1773
+ provider: z$1.literal("memorydb"),
1774
+ executor: z$1.literal("in_do"),
1775
+ region: cacheRegionSchema,
1776
+ aclName: cacheGroupSchema,
1777
+ accessString: cacheAccessSchema,
1778
+ maxTtlSeconds: managedTtlSchema
1779
+ }).strict();
1780
+ // ../../packages/core/src/managed-providers/elasticache.ts
1781
+ const elasticacheTargetConfigSchema = z$1.object({
1782
+ provider: z$1.literal("elasticache"),
1783
+ executor: z$1.literal("in_do"),
1784
+ region: cacheRegionSchema,
1785
+ userGroupId: cacheGroupSchema,
1786
+ engine: z$1.enum(["redis", "valkey"]).default("redis"),
1787
+ accessString: cacheAccessSchema,
1788
+ maxTtlSeconds: managedTtlSchema
1789
+ }).strict();
1790
+ // ../../packages/core/src/managed-providers/snowflake.ts
1791
+ const identifier = z$1.string().regex(/^[a-zA-Z_][a-zA-Z0-9_$]{0,254}$/).transform((value) => value.toUpperCase());
1792
+ const snowflakeTargetConfigSchema = z$1.object({
1793
+ provider: z$1.literal("snowflake"),
1794
+ executor: z$1.literal("in_do"),
1795
+ account: z$1.string().min(1).max(200).regex(/^[a-z0-9](?:[a-z0-9-]*[a-z0-9])?(?:\.[a-z0-9](?:[a-z0-9-]*[a-z0-9])?)*$/i),
1796
+ adminRole: identifier.default("USERADMIN"),
1797
+ roles: z$1.array(identifier).min(1).max(50),
1798
+ warehouse: identifier.optional(),
1799
+ networkPolicy: identifier.optional(),
1800
+ maxTtlSeconds: managedTtlSchema
1801
+ }).strict();
1802
+ // ../../packages/core/src/managed-providers/couchbase.ts
1803
+ const resourceName = z$1.string().min(1).max(255);
1804
+ const access = z$1.object({
1805
+ privileges: z$1.array(z$1.enum(["data_reader", "data_writer"])).min(1).max(2),
1806
+ resources: z$1.object({ buckets: z$1.array(z$1.object({
1807
+ name: resourceName,
1808
+ scopes: z$1.array(z$1.object({
1809
+ name: resourceName,
1810
+ collections: z$1.array(resourceName).min(1).max(100).optional()
1811
+ }).strict()).min(1).max(100).optional()
1812
+ }).strict()).min(1).max(100) }).strict()
1813
+ }).strict();
1814
+ const couchbaseTargetConfigSchema = z$1.object({
1815
+ provider: z$1.literal("couchbase"),
1816
+ executor: z$1.literal("in_do"),
1817
+ organizationId: z$1.string().uuid(),
1818
+ projectId: z$1.string().uuid(),
1819
+ clusterId: z$1.string().uuid(),
1820
+ credentialType: z$1.enum(["basic", "advanced"]).default("basic"),
1821
+ access: z$1.array(access).min(1).max(100).optional(),
1822
+ userRoles: z$1.array(resourceName).min(1).max(100).optional(),
1823
+ maxTtlSeconds: managedTtlSchema
1824
+ }).strict().superRefine((value, ctx) => {
1825
+ if (value.credentialType === "basic" ? !value.access || !!value.userRoles : !value.userRoles || !!value.access) ctx.addIssue({
1826
+ code: "custom",
1827
+ message: "basic credentials require access only; advanced credentials require userRoles only"
1828
+ });
1829
+ });
1830
+ // ../../packages/core/src/managed-providers/mongodb-atlas.ts
1831
+ const mongoAtlasTargetConfigSchema = z$1.object({
1832
+ provider: z$1.literal("mongodb-atlas"),
1833
+ executor: z$1.literal("in_do"),
1834
+ projectId: z$1.string().regex(/^[a-f0-9]{24}$/),
1835
+ roles: z$1.array(z$1.object({
1836
+ roleName: z$1.string().min(1).max(128),
1837
+ databaseName: z$1.string().min(1).max(64),
1838
+ collectionName: z$1.string().min(1).max(128).optional()
1839
+ }).strict()).min(1).max(100),
1840
+ clusters: z$1.array(z$1.string().min(1).max(64)).min(1).max(100),
1841
+ maxTtlSeconds: managedTtlSchema
1842
+ }).strict();
1843
+ // ../../packages/core/src/managed-providers/milvus.ts
1844
+ const milvusTargetConfigSchema = z$1.object({
1845
+ provider: z$1.literal("milvus"),
1846
+ executor: z$1.literal("in_do"),
1847
+ endpoint: managedEndpointSchema,
1848
+ roles: z$1.array(z$1.string().regex(/^[a-zA-Z][a-zA-Z0-9_]{0,127}$/)).min(1).max(50),
1849
+ maxTtlSeconds: managedTtlSchema
1850
+ }).strict();
1851
+ // ../../packages/core/src/managed-providers/rabbitmq.ts
1852
+ const rabbitmqTargetConfigSchema = z$1.object({
1853
+ provider: z$1.literal("rabbitmq"),
1854
+ executor: z$1.literal("in_do"),
1855
+ endpoint: managedEndpointSchema,
1856
+ vhost: z$1.string().min(1).max(255),
1857
+ configure: z$1.string().max(2048).default("^$"),
1858
+ write: z$1.string().max(2048).default("^$"),
1859
+ read: z$1.string().max(2048).default("^$"),
1860
+ maxTtlSeconds: managedTtlSchema
1861
+ }).strict();
1862
+ // ../../packages/core/src/managed-providers/clickhouse.ts
1863
+ const clickhouseTargetConfigSchema = z$1.object({
1864
+ provider: z$1.literal("clickhouse"),
1865
+ executor: z$1.literal("in_do"),
1866
+ endpoint: managedEndpointSchema,
1867
+ roles: z$1.array(nameSchema$1).min(1).max(50),
1868
+ database: nameSchema$1.optional(),
1869
+ cluster: nameSchema$1.optional(),
1870
+ maxTtlSeconds: managedTtlSchema
1871
+ }).strict();
1872
+ // ../../packages/core/src/managed-providers/elasticsearch.ts
1873
+ const role = z$1.object({
1874
+ cluster: z$1.array(z$1.string().min(1).max(100)).max(100).default([]),
1875
+ indices: z$1.array(z$1.object({
1876
+ names: z$1.array(z$1.string().min(1).max(256)).min(1).max(100),
1877
+ privileges: z$1.array(z$1.string().min(1).max(100)).min(1).max(100),
1878
+ allow_restricted_indices: z$1.literal(false).optional()
1879
+ }).strict()).max(100).default([])
1880
+ }).strict();
1881
+ const elasticsearchTargetConfigSchema = z$1.object({
1882
+ provider: z$1.literal("elasticsearch"),
1883
+ executor: z$1.literal("in_do"),
1884
+ endpoint: managedEndpointSchema,
1885
+ credentialType: z$1.enum(["user", "api_key"]).default("user"),
1886
+ roles: z$1.array(z$1.string().min(1).max(128)).min(1).max(100).optional(),
1887
+ roleDescriptors: z$1.record(z$1.string().min(1).max(128), role).refine((value) => Object.keys(value).length > 0 && Object.keys(value).length <= 20, "supply explicit key permissions").optional(),
1888
+ maxTtlSeconds: managedTtlSchema
1889
+ }).strict().superRefine((value, ctx) => {
1890
+ if (value.credentialType === "user" && !value.roles?.length) ctx.addIssue({
1891
+ code: "custom",
1892
+ path: ["roles"],
1893
+ message: "select at least one user role"
1894
+ });
1895
+ if (value.credentialType === "api_key" && !value.roleDescriptors) ctx.addIssue({
1896
+ code: "custom",
1897
+ path: ["roleDescriptors"],
1898
+ message: "supply explicit key permissions"
1899
+ });
1900
+ });
1901
+ // ../../packages/core/src/managed-leases.ts
1902
+ /** Providers whose credential is generated by the broker or upstream service. */
1903
+ const MANAGED_LEASE_KINDS = [
1904
+ "openrouter",
1905
+ "tailscale",
1906
+ "elasticsearch",
1907
+ "clickhouse",
1908
+ "rabbitmq",
1909
+ "milvus",
1910
+ "mongodb-atlas",
1911
+ "couchbase",
1912
+ "snowflake",
1913
+ "elasticache",
1914
+ "memorydb"
1915
+ ];
1916
+ const openRouterTargetConfigSchema = z$1.object({
1917
+ provider: z$1.literal("openrouter"),
1918
+ executor: z$1.literal("in_do"),
1919
+ workspaceId: z$1.string().uuid().optional(),
1920
+ creditLimit: z$1.number().finite().nonnegative(),
1921
+ limitReset: z$1.enum([
1922
+ "daily",
1923
+ "weekly",
1924
+ "monthly"
1925
+ ]).optional(),
1926
+ includeByokInLimit: z$1.boolean().optional(),
1927
+ maxTtlSeconds: z$1.number().int().min(60).max(604800).optional()
1928
+ }).strict();
1929
+ const tailscaleTargetConfigSchema = z$1.object({
1930
+ provider: z$1.literal("tailscale"),
1931
+ executor: z$1.literal("in_do"),
1932
+ tailnet: z$1.string().min(1).max(253).regex(/^[a-zA-Z0-9@._-]+$/),
1933
+ credentialType: z$1.enum([
1934
+ "auth",
1935
+ "client",
1936
+ "federated"
1937
+ ]),
1938
+ tags: z$1.array(z$1.string().regex(/^tag:[a-zA-Z0-9_-]+$/)).max(100).default([]),
1939
+ reusable: z$1.boolean().default(false),
1940
+ ephemeral: z$1.boolean().default(true),
1941
+ preauthorized: z$1.boolean().default(false),
1942
+ scopes: z$1.array(z$1.string().min(1).max(128)).max(100).default([]),
1943
+ issuer: z$1.string().url().optional(),
1944
+ audience: z$1.string().min(1).max(2048).optional(),
1945
+ subject: z$1.string().min(1).max(2048).optional(),
1946
+ maxTtlSeconds: z$1.number().int().min(60).max(604800).optional()
1947
+ }).strict().superRefine((value, ctx) => {
1948
+ if (value.credentialType !== "auth" && !value.scopes.length) ctx.addIssue({
1949
+ code: "custom",
1950
+ path: ["scopes"],
1951
+ message: "select at least one scope"
1952
+ });
1953
+ if (value.credentialType === "federated" && (!value.issuer?.startsWith("https://") || !value.audience || !value.subject)) ctx.addIssue({
1954
+ code: "custom",
1955
+ path: ["issuer"],
1956
+ message: "federation requires HTTPS issuer, audience, and subject"
1957
+ });
1958
+ });
1959
+ const managedTargetConfigSchema = z$1.discriminatedUnion("provider", [
1960
+ clickhouseTargetConfigSchema,
1961
+ rabbitmqTargetConfigSchema,
1962
+ milvusTargetConfigSchema,
1963
+ mongoAtlasTargetConfigSchema,
1964
+ couchbaseTargetConfigSchema,
1965
+ snowflakeTargetConfigSchema,
1966
+ elasticacheTargetConfigSchema,
1967
+ memorydbTargetConfigSchema,
1968
+ openRouterTargetConfigSchema,
1969
+ tailscaleTargetConfigSchema,
1970
+ elasticsearchTargetConfigSchema
1971
+ ]);
1972
+ function isManagedLeaseKind(value) {
1973
+ return MANAGED_LEASE_KINDS.includes(value);
1974
+ }
1975
+ function isManagedTarget(value) {
1976
+ return isManagedLeaseKind(value.provider);
1977
+ }
1755
1978
  z$1.enum([
1756
1979
  "postgres",
1757
1980
  "mysql",
@@ -1759,7 +1982,8 @@ z$1.enum([
1759
1982
  "redis",
1760
1983
  "aws",
1761
1984
  "gcp",
1762
- "mongodb"
1985
+ "mongodb",
1986
+ ...MANAGED_LEASE_KINDS
1763
1987
  ]);
1764
1988
  const executorModeSchema = z$1.enum(["in_do", "remote"]);
1765
1989
  /**
@@ -1994,7 +2218,8 @@ const leaseTargetConfigSchema = z$1.discriminatedUnion("provider", [
1994
2218
  sshTargetConfigSchema,
1995
2219
  awsTargetConfigSchema,
1996
2220
  gcpTargetConfigSchema,
1997
- mongoTargetConfigSchema
2221
+ mongoTargetConfigSchema,
2222
+ ...managedTargetConfigSchema.options
1998
2223
  ]);
1999
2224
  z$1.object({
2000
2225
  name: z$1.string().trim().min(1).max(128),
@@ -2100,6 +2325,18 @@ const mintMongoLeaseSchema = z$1.object({
2100
2325
  recipientPublicKey: p256PublicKeyJwkSchema,
2101
2326
  ttlSeconds: ttlSecondsSchema
2102
2327
  });
2328
+ const mintManagedLeaseSchema = z$1.object({
2329
+ provider: z$1.enum(MANAGED_LEASE_KINDS),
2330
+ targetId: z$1.string().min(1),
2331
+ recipientPublicKey: p256PublicKeyJwkSchema.refine((value) => {
2332
+ try {
2333
+ return !("d" in JSON.parse(value));
2334
+ } catch {
2335
+ return false;
2336
+ }
2337
+ }, "send only a public key"),
2338
+ ttlSeconds: ttlSecondsSchema
2339
+ });
2103
2340
  z$1.discriminatedUnion("provider", [
2104
2341
  mintPostgresLeaseSchema,
2105
2342
  mintMysqlLeaseSchema,
@@ -2107,9 +2344,9 @@ z$1.discriminatedUnion("provider", [
2107
2344
  mintSshLeaseSchema,
2108
2345
  mintAwsLeaseSchema,
2109
2346
  mintGcpLeaseSchema,
2110
- mintMongoLeaseSchema
2347
+ mintMongoLeaseSchema,
2348
+ mintManagedLeaseSchema
2111
2349
  ]);
2112
- // ../../packages/core/src/providers/aws.ts
2113
2350
  /**
2114
2351
  * The one-time IAM setup an admin performs so seekrit can assume the target
2115
2352
  * role. Analogue of `sshHostSetupInstructions` / `postgresGroupBootstrapSql` —
@@ -2136,7 +2373,6 @@ function awsTrustPolicyInstructions(config) {
2136
2373
  `# on ${config.roleArn}. seekrit only ever calls AssumeRole on this role.`
2137
2374
  ].join("\n");
2138
2375
  }
2139
- // ../../packages/core/src/providers/gcp.ts
2140
2376
  /**
2141
2377
  * The one-time IAM setup an admin performs so seekrit can impersonate the target
2142
2378
  * service account. Analogue of `awsTrustPolicyInstructions` — printed for the
@@ -2158,7 +2394,6 @@ function gcpSetupInstructions(config) {
2158
2394
  "gcloud services enable iamcredentials.googleapis.com"
2159
2395
  ].join("\n");
2160
2396
  }
2161
- // ../../packages/core/src/providers/mongodb.ts
2162
2397
  /**
2163
2398
  * The one-time setup an admin performs so seekrit can provision users: create a
2164
2399
  * dedicated provisioning user with `userAdmin` on the target database (or
@@ -2183,7 +2418,6 @@ function mongoAdminSetupInstructions(config) {
2183
2418
  `// --uri "mongodb://seekrit_provisioner:<pwd>@${config.connection.host}:${config.connection.port}/?authSource=${authSource}"`
2184
2419
  ].join("\n");
2185
2420
  }
2186
- // ../../packages/core/src/providers/postgres.ts
2187
2421
  /**
2188
2422
  * The one-time setup SQL an admin runs to create the shared group role that a
2189
2423
  * read-only / read-write target's leased credentials inherit. Idempotent (safe
@@ -2214,7 +2448,6 @@ function postgresGroupBootstrapSql(config) {
2214
2448
  if (config.accessLevel === "readwrite") lines.push(`GRANT USAGE, SELECT ON ALL SEQUENCES IN SCHEMA "${schema}" TO ${group};`, `ALTER DEFAULT PRIVILEGES IN SCHEMA "${schema}" GRANT USAGE, SELECT ON SEQUENCES TO ${group};`);
2215
2449
  return lines.join("\n");
2216
2450
  }
2217
- // ../../packages/core/src/providers/ssh.ts
2218
2451
  /**
2219
2452
  * The one-time host setup an admin runs so a target's certificates are accepted.
2220
2453
  * Analogue of `postgresGroupBootstrapSql` — displayed for the admin to run, not
@@ -5052,6 +5285,19 @@ async function decryptDataKey(material, wrapped) {
5052
5285
  throw new SeekritCryptoError("DECRYPT_FAILED", "data key unwrap failed: wrong key or tampered blob");
5053
5286
  }
5054
5287
  }
5288
+ // ../../packages/crypto/src/managed-credential.ts
5289
+ const generateCredentialRecipientKeyPair = generateKeyPair;
5290
+ /** Only called on the consumer; the API receives the wrapped bytes. */
5291
+ async function unwrapManagedCredential(wrapped, privateKeyJwk) {
5292
+ const bytes = await unwrapDek(wrapped, await importPrivateKey(privateKeyJwk));
5293
+ try {
5294
+ const result = JSON.parse(new TextDecoder().decode(bytes));
5295
+ if (!result || typeof result !== "object" || Array.isArray(result) || !Object.values(result).every((value) => typeof value === "string")) throw new Error();
5296
+ return result;
5297
+ } catch {
5298
+ throw new SeekritCryptoError("DECRYPT_FAILED", "invalid managed credential");
5299
+ }
5300
+ }
5055
5301
  // ../../packages/crypto/src/random.ts
5056
5302
  const ALPHABETS = {
5057
5303
  alphanumeric: "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",
@@ -5894,7 +6140,7 @@ async function createAgentTaskToken() {
5894
6140
  };
5895
6141
  }
5896
6142
  // package.json
5897
- var version = "2.6.0";
6143
+ var version = "2.7.0";
5898
6144
  // ../../packages/api-client/src/index.ts
5899
6145
  /**
5900
6146
  * The proposer's note travels as a header, not a body field: an unprotected
@@ -12619,6 +12865,81 @@ function registerDoctorCommand(program) {
12619
12865
  if (checks.some((c) => c.status === "fail")) process.exitCode = 1;
12620
12866
  });
12621
12867
  }
12868
+ // src/dynamic.ts
12869
+ function dynamicTtl(value) {
12870
+ const match = /^(\d+)([smhd]?)$/.exec(value);
12871
+ if (!match) throw new Error("invalid TTL (use 15m, 1h, or 1d)");
12872
+ const seconds = Number(match[1]) * ({
12873
+ s: 1,
12874
+ m: 60,
12875
+ h: 3600,
12876
+ d: 86400
12877
+ }[match[2] || "s"] ?? 1);
12878
+ if (!Number.isSafeInteger(seconds) || seconds < 60 || seconds > 604800) throw new Error("TTL must be 1 minute–7 days");
12879
+ return seconds;
12880
+ }
12881
+ function registerDynamicCommands(program) {
12882
+ const dynamic = program.command("dynamic").description("manage provider-issued temporary credentials");
12883
+ const targets = dynamic.command("target").description("manage dynamic credential targets");
12884
+ targets.command("add").requiredOption("--name <name>", "target name").requiredOption("--config <file>", "non-secret provider configuration JSON").option("--org <slug>", "organization").description("register a target; read its admin credential from stdin and encrypt it locally").action(async (options) => {
12885
+ const config = managedTargetConfigSchema.parse(JSON.parse(readFileSync(options.config, "utf8")));
12886
+ if (process.stdin.isTTY) fail("pipe the admin credential on stdin");
12887
+ const secret = (await readStdin()).trim();
12888
+ if (!secret) fail("admin credential is empty");
12889
+ const ctx = buildContext();
12890
+ const org = await resolveOrg(ctx, options.org);
12891
+ const { publicKeyJwk } = await ctx.client.getLeaseBrokerKey(org.id);
12892
+ const wrappedAdminSecret = await wrapDek(new TextEncoder().encode(secret), publicKeyJwk);
12893
+ const { target } = await ctx.client.registerLeaseTarget(org.id, {
12894
+ name: options.name,
12895
+ config,
12896
+ wrappedAdminSecret
12897
+ });
12898
+ console.log(JSON.stringify(target));
12899
+ });
12900
+ targets.command("list").option("--org <slug>", "organization").action(async (options) => {
12901
+ const ctx = buildContext();
12902
+ const org = await resolveOrg(ctx, options.org);
12903
+ const { targets } = await ctx.client.listLeaseTargets(org.id);
12904
+ console.log(JSON.stringify(targets.filter((target) => isManagedTarget(target))));
12905
+ });
12906
+ dynamic.command("lease <target>").option("--ttl <duration>", "credential lifetime", "1h").option("--org <slug>", "organization").description("mint and decrypt a credential locally; outputs JSON once").action(async (reference, options) => {
12907
+ const ttlSeconds = dynamicTtl(options.ttl);
12908
+ const ctx = buildContext();
12909
+ const org = await resolveOrg(ctx, options.org);
12910
+ const { targets } = await ctx.client.listLeaseTargets(org.id);
12911
+ const matches = targets.filter((target) => target.id === reference || target.name === reference);
12912
+ if (matches.length !== 1) fail("target must identify exactly one registered target");
12913
+ const target = matches[0];
12914
+ if (!target) fail("target not found");
12915
+ const config = managedTargetConfigSchema.parse(target.config);
12916
+ const recipient = await generateCredentialRecipientKeyPair();
12917
+ const result = await ctx.client.mintLease(org.id, {
12918
+ provider: config.provider,
12919
+ targetId: target.id,
12920
+ recipientPublicKey: recipient.publicKeyJwk,
12921
+ ttlSeconds
12922
+ });
12923
+ try {
12924
+ const credential = await unwrapManagedCredential(result.credential.wrappedCredential, recipient.privateKeyJwk);
12925
+ console.log(JSON.stringify({
12926
+ leaseId: result.lease.id,
12927
+ expiresAt: result.credential.expiresAt,
12928
+ credential
12929
+ }));
12930
+ } catch (error) {
12931
+ await ctx.client.revokeLease(org.id, result.lease.id);
12932
+ throw error;
12933
+ }
12934
+ });
12935
+ dynamic.command("revoke <leaseId>").option("--org <slug>", "organization").option("-y, --yes", "skip the confirmation prompt").description("revoke a temporary credential now").action(async (leaseId, options) => {
12936
+ await confirmDestructive(options.yes, `Revoke temporary credential ${leaseId}?`);
12937
+ const ctx = buildContext();
12938
+ const org = await resolveOrg(ctx, options.org);
12939
+ await ctx.client.revokeLease(org.id, leaseId);
12940
+ console.log(JSON.stringify({ revoked: leaseId }));
12941
+ });
12942
+ }
12622
12943
  // src/gcp.ts
12623
12944
  /**
12624
12945
  * `seekrit gcp` — temporary GCP credentials via IAM Credentials
@@ -18475,6 +18796,7 @@ registerHermesCommands(program);
18475
18796
  registerSshCommands(program);
18476
18797
  registerAwsCommands(program);
18477
18798
  registerGcpCommands(program);
18799
+ registerDynamicCommands(program);
18478
18800
  registerIdentityCommands(program);
18479
18801
  registerMongoCommands(program);
18480
18802
  registerKmsCommands(program);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@seekrit/cli",
3
- "version": "2.6.0",
3
+ "version": "2.7.0",
4
4
  "description": "CLI for seekrit (https://seekrit.dev), a zero-knowledge secrets manager and credential broker for AI agents — inject decrypted secrets into any command.",
5
5
  "homepage": "https://seekrit.dev/docs/guides/cli",
6
6
  "keywords": [