51 lines
2.2 KiB
JavaScript
51 lines
2.2 KiB
JavaScript
import { readFile } from "node:fs/promises";
|
|
import { resolve } from "node:path";
|
|
import { describe, expect, it } from "vitest";
|
|
|
|
async function source(path) {
|
|
return readFile(resolve(process.cwd(), path), "utf8");
|
|
}
|
|
|
|
describe("infrastructure security contracts", () => {
|
|
it.each([
|
|
["infra/sentry/backup/backup.sh", "SENTRY_BACKUP_GPG_RECIPIENT", "SENTRY_SECRET_KEY"],
|
|
["infra/authentik/backup/backup.sh", "AUTHENTIK_BACKUP_GPG_RECIPIENT", "AUTHENTIK_SECRET_KEY"],
|
|
])("requires a dedicated recipient in %s and has no symmetric runtime-secret fallback", async (path, recipient, runtimeSecret) => {
|
|
const script = await source(path);
|
|
|
|
expect(script).toContain(`:\x20\"\${${recipient}:?${recipient} is required}\"`);
|
|
expect(script).toContain(`--recipient \"\${${recipient}}\"`);
|
|
expect(script).not.toContain("--symmetric");
|
|
expect(script).not.toContain("--passphrase");
|
|
expect(script).not.toContain(`${runtimeSecret} missing for symmetric fallback`);
|
|
});
|
|
|
|
it("keeps Prometheus internal and disables the unauthenticated lifecycle endpoint", async () => {
|
|
const compose = await source("infra/prometheus/docker-compose.yml");
|
|
|
|
expect(compose).not.toContain("--web.enable-lifecycle");
|
|
expect(compose).not.toMatch(/ports:\s*\n\s*-\s*["']?9090:9090/u);
|
|
expect(compose).toMatch(/expose:\s*\n\s*-\s*["']9090["']/u);
|
|
});
|
|
|
|
it("keeps deferred operational security risks discoverable without claiming they are fixed", async () => {
|
|
const followUps = await source("docs/security/SECURITY-AUDIT-2026-07-22.md");
|
|
const signing = await source("docs/security/image-signing.md");
|
|
const prodRollout = await source("docs/ops/prod-rollout-hivegrid.md");
|
|
const securityEntryPoint = await source("docs/security.md");
|
|
|
|
for (const marker of [
|
|
"SECURITY-FOLLOWUP-COSIGN",
|
|
"SECURITY-FOLLOWUP-REGISTRY-PULL",
|
|
"CI-FOLLOWUP-RESTORE-QUALITY-GATES",
|
|
]) {
|
|
expect(followUps).toContain(`## ${marker}`);
|
|
expect(securityEntryPoint).toContain(marker);
|
|
}
|
|
|
|
expect(signing).toContain("./SECURITY-AUDIT-2026-07-22.md#security-followup-cosign");
|
|
expect(prodRollout).toContain("../security/SECURITY-AUDIT-2026-07-22.md");
|
|
expect(prodRollout).not.toContain("VOLLSTÄNDIG LIVE + GEHÄRTET");
|
|
});
|
|
});
|