Files
purpur-sentinel/scripts/secret-input.test.ts
T
dmg b211e9d337
CI / build (pull_request) Successful in 1m16s
CI / build (push) Successful in 3m24s
feat(sentinel): alert on repeated suspicious movement
2026-10-29 08:28:27 -04:00

68 lines
3.5 KiB
TypeScript

import assert from "node:assert/strict";
import { spawnSync } from "node:child_process";
import { closeSync, chmodSync, mkdtempSync, openSync, realpathSync, rmSync, symlinkSync, writeFileSync } from "node:fs";
import { tmpdir } from "node:os";
import { join, resolve } from "node:path";
import { test } from "node:test";
import { planSecretInput } from "./secret-input.js";
const fixture = "synthetic-provisioning-value-not-a-real-secret";
function protectedInput(body: (dir: string, file: string) => void) {
const dir = realpathSync(mkdtempSync(join(tmpdir(), "sentinel-secret-contract-")));
const file = join(dir, "release-token");
try {
chmodSync(dir, 0o700);
writeFileSync(file, fixture, { mode: 0o600 });
body(dir, file);
} finally { rmSync(dir, { recursive: true, force: true }); }
}
for (const invalid of ["public-file", "public-directory", "symlink", "relative", "repository", "missing", "directory", "empty", "login"] as const) {
test(`protected provisioning plan refuses ${invalid} input without reading or echoing it`, () => protectedInput((dir, file) => {
let path = file;
let root = resolve(".");
let login = "fixture-login";
if (invalid === "public-file") chmodSync(file, 0o644);
if (invalid === "public-directory") chmodSync(dir, 0o755);
if (invalid === "symlink") { path = join(dir, "link"); symlinkSync(file, path); }
if (invalid === "relative") path = "relative-token";
if (invalid === "repository") root = dir;
if (invalid === "missing") path = join(dir, "missing");
if (invalid === "directory") path = dir;
if (invalid === "empty") writeFileSync(file, "");
if (invalid === "login") login = "--debug";
assert.throws(() => planSecretInput(login, path, "file", root), {
message: "Invalid protected secret input; no provisioning was performed.",
});
}));
}
for (const mode of ["file", "stdin"] as const) {
test(`protected ${mode} plan follows tea contract without credential argv, logs or actual provisioning`, () => protectedInput((dir, file) => {
const plan = planSecretInput("fixture-login", file, mode, resolve("."));
assert.equal(plan.command, "tea");
assert.deepEqual(plan.args, ["actions", "secrets", "create", "--login", "fixture-login", "--repo", "dmg/purpur-sentinel",
...(mode === "file" ? ["--file", file] : ["--stdin"]), "RELEASE_TOKEN"]);
assert.equal(plan.stdinFile, mode === "stdin" ? file : undefined);
assert.ok(!JSON.stringify(plan).includes(fixture));
// Execute only an isolated local fake, NEVER the installed tea command.
const fake = join(dir, "fake-tea.cjs");
writeFileSync(fake, `
const fs = require('node:fs');
const args = process.argv.slice(2);
const bytes = args.includes('--stdin') ? fs.readFileSync(0, 'utf8') : fs.readFileSync(args[args.indexOf('--file') + 1], 'utf8');
if (bytes !== ${JSON.stringify(fixture)} || args.join(' ').includes(bytes)) process.exit(1);
process.stdout.write('Accepted protected input for RELEASE_TOKEN.\\n');
`, { mode: 0o600 });
const fd = plan.stdinFile ? openSync(plan.stdinFile, "r") : undefined;
try {
const child = spawnSync(process.execPath, [fake, ...plan.args], {
env: {}, encoding: "utf8", stdio: [fd ?? "ignore", "pipe", "pipe"],
});
assert.equal(child.status, 0, child.stderr);
assert.equal(child.stdout, "Accepted protected input for RELEASE_TOKEN.\n");
assert.equal(child.stderr, "");
} finally { if (fd !== undefined) closeSync(fd); }
}));
}