refactor: tighten safe-bin policy model and docs parity

This commit is contained in:
Peter Steinberger
2026-02-21 19:24:23 +01:00
parent c730d4dd72
commit 89aad7b922
4 changed files with 227 additions and 106 deletions

View File

@@ -1,5 +1,26 @@
import fs from "node:fs";
import path from "node:path";
import { describe, expect, it } from "vitest";
import { SAFE_BIN_PROFILES, validateSafeBinArgv } from "./exec-safe-bin-policy.js";
import {
SAFE_BIN_PROFILE_FIXTURES,
SAFE_BIN_PROFILES,
renderSafeBinDeniedFlagsDocBullets,
validateSafeBinArgv,
} from "./exec-safe-bin-policy.js";
const SAFE_BIN_DOC_DENIED_FLAGS_START = "<!-- SAFE_BIN_DENIED_FLAGS:START -->";
const SAFE_BIN_DOC_DENIED_FLAGS_END = "<!-- SAFE_BIN_DENIED_FLAGS:END -->";
function buildDeniedFlagArgvVariants(flag: string): string[][] {
const value = "blocked";
if (flag.startsWith("--")) {
return [[`${flag}=${value}`], [flag, value], [flag]];
}
if (flag.startsWith("-")) {
return [[`${flag}${value}`], [flag, value], [flag]];
}
return [[flag]];
}
describe("exec safe bin policy grep", () => {
const grepProfile = SAFE_BIN_PROFILES.grep;
@@ -34,3 +55,32 @@ describe("exec safe bin policy sort", () => {
expect(validateSafeBinArgv(["--compress-program", "sh"], sortProfile)).toBe(false);
});
});
describe("exec safe bin policy denied-flag matrix", () => {
for (const [binName, fixture] of Object.entries(SAFE_BIN_PROFILE_FIXTURES)) {
const profile = SAFE_BIN_PROFILES[binName];
const deniedFlags = fixture.deniedFlags ?? [];
for (const deniedFlag of deniedFlags) {
const variants = buildDeniedFlagArgvVariants(deniedFlag);
for (const variant of variants) {
it(`${binName} denies ${deniedFlag} (${variant.join(" ")})`, () => {
expect(validateSafeBinArgv(variant, profile)).toBe(false);
});
}
}
}
});
describe("exec safe bin policy docs parity", () => {
it("keeps denied-flag docs in sync with policy fixtures", () => {
const docsPath = path.resolve(process.cwd(), "docs/tools/exec-approvals.md");
const docs = fs.readFileSync(docsPath, "utf8").replaceAll("\r\n", "\n");
const start = docs.indexOf(SAFE_BIN_DOC_DENIED_FLAGS_START);
const end = docs.indexOf(SAFE_BIN_DOC_DENIED_FLAGS_END);
expect(start).toBeGreaterThanOrEqual(0);
expect(end).toBeGreaterThan(start);
const actual = docs.slice(start + SAFE_BIN_DOC_DENIED_FLAGS_START.length, end).trim();
const expected = renderSafeBinDeniedFlagsDocBullets();
expect(actual).toBe(expected);
});
});