@seekrit/cli 1.2.1 → 1.3.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 +80 -6
- package/package.json +5 -5
package/dist/index.js
CHANGED
|
@@ -5051,7 +5051,7 @@ async function createAgentTaskToken() {
|
|
|
5051
5051
|
}
|
|
5052
5052
|
//#endregion
|
|
5053
5053
|
//#region package.json
|
|
5054
|
-
var version = "1.
|
|
5054
|
+
var version = "1.3.0";
|
|
5055
5055
|
//#endregion
|
|
5056
5056
|
//#region ../../packages/api-client/src/index.ts
|
|
5057
5057
|
var SeekritApiError = class extends Error {
|
|
@@ -12165,7 +12165,7 @@ function collect$2(value, acc) {
|
|
|
12165
12165
|
* release-please-config.json), so the pin follows the crate without anyone
|
|
12166
12166
|
* remembering to move it.
|
|
12167
12167
|
*/
|
|
12168
|
-
const PROXY_VERSION = "0.
|
|
12168
|
+
const PROXY_VERSION = "0.11.0";
|
|
12169
12169
|
const BIN = "seekrit-proxy";
|
|
12170
12170
|
/**
|
|
12171
12171
|
* Host → Rust target triple.
|
|
@@ -12201,7 +12201,7 @@ function versionPrefix(version) {
|
|
|
12201
12201
|
return version.startsWith("v") ? version : `v${version}`;
|
|
12202
12202
|
}
|
|
12203
12203
|
function resolveVersion(explicit) {
|
|
12204
|
-
return explicit ?? process.env.SEEKRIT_PROXY_VERSION ?? "0.
|
|
12204
|
+
return explicit ?? process.env.SEEKRIT_PROXY_VERSION ?? "0.11.0";
|
|
12205
12205
|
}
|
|
12206
12206
|
function resolveBaseUrl(explicit) {
|
|
12207
12207
|
return (explicit ?? process.env.SEEKRIT_PROXY_BASE_URL ?? "https://proxy.seekrit.dev").replace(/\/+$/, "");
|
|
@@ -12328,6 +12328,42 @@ function signalNumber(signal) {
|
|
|
12328
12328
|
* — and none of them changes what the proxy does. The generated config is the
|
|
12329
12329
|
* same config; the fetched binary is the released binary, checksum-verified.
|
|
12330
12330
|
*/
|
|
12331
|
+
/**
|
|
12332
|
+
* Where `seekrit proxy approvals` looks by default.
|
|
12333
|
+
*
|
|
12334
|
+
* The control listener is loopback-bound by design, so the only interesting
|
|
12335
|
+
* variable is the port — and one URL is easier to override than a host/port pair.
|
|
12336
|
+
*/
|
|
12337
|
+
const DEFAULT_CONTROL_URL = "http://127.0.0.1:8090";
|
|
12338
|
+
/** Header the control listener authenticates with (mirrors `src/tickets.rs`). */
|
|
12339
|
+
const CONTROL_TOKEN_HEADER = "x-seekrit-control-token";
|
|
12340
|
+
/**
|
|
12341
|
+
* Talk to a running proxy's control listener.
|
|
12342
|
+
*
|
|
12343
|
+
* The token comes from the environment and never from a flag: it is what decides
|
|
12344
|
+
* whether a held request goes through, and a flag would put it in shell history
|
|
12345
|
+
* next to the operation it is guarding.
|
|
12346
|
+
*/
|
|
12347
|
+
async function controlRequest(base, path, decision) {
|
|
12348
|
+
const token = process.env.SEEKRIT_PROXY_CONTROL_TOKEN;
|
|
12349
|
+
if (!token) fail("SEEKRIT_PROXY_CONTROL_TOKEN is not set — it is the same token the proxy was started with, and without it the listener will not answer");
|
|
12350
|
+
let resp;
|
|
12351
|
+
try {
|
|
12352
|
+
resp = await fetch(new URL(path, base), {
|
|
12353
|
+
method: decision ? "POST" : "GET",
|
|
12354
|
+
headers: {
|
|
12355
|
+
[CONTROL_TOKEN_HEADER]: token,
|
|
12356
|
+
...decision ? { "content-type": "application/json" } : {}
|
|
12357
|
+
},
|
|
12358
|
+
...decision ? { body: JSON.stringify({ decision }) } : {}
|
|
12359
|
+
});
|
|
12360
|
+
} catch (e) {
|
|
12361
|
+
fail(`could not reach the proxy's control listener at ${base}: ${e.message}\nIs the proxy running, and does its config have a [control] block?`);
|
|
12362
|
+
throw e;
|
|
12363
|
+
}
|
|
12364
|
+
if (!resp.ok) fail(`${resp.status} from the control listener: ${(await resp.text()).trim()}`);
|
|
12365
|
+
return await resp.json();
|
|
12366
|
+
}
|
|
12331
12367
|
const DEFAULT_CONFIG = "seekrit-proxy.toml";
|
|
12332
12368
|
/**
|
|
12333
12369
|
* The exact grammar `seekrit_cache::parse_duration` accepts: a positive integer,
|
|
@@ -12553,10 +12589,10 @@ Next:
|
|
|
12553
12589
|
});
|
|
12554
12590
|
console.log(path);
|
|
12555
12591
|
const { target } = detectTarget();
|
|
12556
|
-
process.stderr.write(`seekrit-proxy ${versionPrefix(options.proxyVersion ?? "0.
|
|
12592
|
+
process.stderr.write(`seekrit-proxy ${versionPrefix(options.proxyVersion ?? "0.11.0")} (${target})\n`);
|
|
12557
12593
|
});
|
|
12558
12594
|
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) => {
|
|
12559
|
-
const version = options.proxyVersion ?? process.env.SEEKRIT_PROXY_VERSION ?? "0.
|
|
12595
|
+
const version = options.proxyVersion ?? process.env.SEEKRIT_PROXY_VERSION ?? "0.11.0";
|
|
12560
12596
|
const override = process.env.SEEKRIT_PROXY_BIN;
|
|
12561
12597
|
const { target, exe } = detectTarget();
|
|
12562
12598
|
const path = override ?? proxyBinaryPath(version, target, exe);
|
|
@@ -12572,12 +12608,50 @@ Next:
|
|
|
12572
12608
|
process.stderr.write(`${info.version} · ${info.target} · ${info.source}\n`);
|
|
12573
12609
|
});
|
|
12574
12610
|
});
|
|
12611
|
+
proxy.command("approvals").description("list requests a running proxy is holding for approval").option("--control <url>", "control listener URL", DEFAULT_CONTROL_URL).option("--json", "machine-readable output").action(async (options) => {
|
|
12612
|
+
const { pending } = await controlRequest(options.control, "/approvals");
|
|
12613
|
+
emit(options, { pending }, () => {
|
|
12614
|
+
printTable(pending, [
|
|
12615
|
+
col("ID", (p) => p.id),
|
|
12616
|
+
col("OPERATION", (p) => p.operation),
|
|
12617
|
+
col("REQUEST", (p) => `${p.method} ${p.host}${p.path}`),
|
|
12618
|
+
col("CARRIES", (p) => p.secrets.join(", ") || "no credential"),
|
|
12619
|
+
col("EXPIRES", (p) => `${p.expires_in_seconds}s`)
|
|
12620
|
+
], "nothing is waiting");
|
|
12621
|
+
});
|
|
12622
|
+
});
|
|
12623
|
+
for (const [verb, decision, summary] of [
|
|
12624
|
+
[
|
|
12625
|
+
"approve",
|
|
12626
|
+
"approve",
|
|
12627
|
+
"let a held request through"
|
|
12628
|
+
],
|
|
12629
|
+
[
|
|
12630
|
+
"deny",
|
|
12631
|
+
"deny",
|
|
12632
|
+
"refuse a held request"
|
|
12633
|
+
],
|
|
12634
|
+
[
|
|
12635
|
+
"always",
|
|
12636
|
+
"always",
|
|
12637
|
+
"let it through and stop asking about that host and method for this run"
|
|
12638
|
+
]
|
|
12639
|
+
]) proxy.command(`${verb} <id>`).description(summary).option("--control <url>", "control listener URL", DEFAULT_CONTROL_URL).option("--json", "machine-readable output").action(async (id, options) => {
|
|
12640
|
+
const result = await controlRequest(options.control, `/approvals/${encodeURIComponent(id)}`, decision);
|
|
12641
|
+
emit(options, {
|
|
12642
|
+
id,
|
|
12643
|
+
decision,
|
|
12644
|
+
...result
|
|
12645
|
+
}, () => {
|
|
12646
|
+
process.stderr.write(`${id}: ${decision}\n`);
|
|
12647
|
+
});
|
|
12648
|
+
});
|
|
12575
12649
|
withGenerateOptions(proxy.command("compose").description("print a docker compose sidecar snippet for a generated config")).option("--service <name>", "compose service name for the proxy", COMPOSE_DEFAULTS.service).option("--workload <name>", "compose service name for your workload", COMPOSE_DEFAULTS.workload).option("--image <ref>", "image to pin (default: seekritdev/proxy:<version>)").option("--publish", "also publish the proxy's ports to the host").action(async (options) => {
|
|
12576
12650
|
const plan = await buildPlan(options);
|
|
12577
12651
|
process.stdout.write(renderComposeSnippet(plan, {
|
|
12578
12652
|
service: options.service,
|
|
12579
12653
|
workload: options.workload,
|
|
12580
|
-
image: options.image ?? `seekritdev/proxy:0.
|
|
12654
|
+
image: options.image ?? `seekritdev/proxy:0.11.0`,
|
|
12581
12655
|
publish: Boolean(options.publish)
|
|
12582
12656
|
}));
|
|
12583
12657
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@seekrit/cli",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.3.0",
|
|
4
4
|
"description": "End-to-end encrypted secrets manager CLI — inject decrypted secrets into any command.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"publishConfig": {
|
|
@@ -22,16 +22,16 @@
|
|
|
22
22
|
"node": ">=20"
|
|
23
23
|
},
|
|
24
24
|
"dependencies": {
|
|
25
|
-
"@modelcontextprotocol/sdk": "^1.
|
|
25
|
+
"@modelcontextprotocol/sdk": "^1.30.0",
|
|
26
26
|
"commander": "^15.0.0",
|
|
27
|
-
"zod": "^4.4
|
|
27
|
+
"zod": "^4.5.4"
|
|
28
28
|
},
|
|
29
29
|
"devDependencies": {
|
|
30
30
|
"@types/node": "^26.1.0",
|
|
31
31
|
"tsdown": "^0.22.3",
|
|
32
|
-
"vitest": "^4.1.
|
|
33
|
-
"@seekrit/api-client": "0.0.1",
|
|
32
|
+
"vitest": "^4.1.11",
|
|
34
33
|
"@seekrit/core": "0.0.1",
|
|
34
|
+
"@seekrit/api-client": "0.0.1",
|
|
35
35
|
"@seekrit/crypto": "0.0.1"
|
|
36
36
|
},
|
|
37
37
|
"scripts": {
|