Files
sshkeyvault/tests/geheimnisse-grenze.test.ts
T
florian.wildeandClaude Opus 5.5 9b807c13ae feat(worker): Private Keys im Worker versiegeln, Deployment-Key (#006)
Der zweite Teil von #006 bindet den Kern an Datenbank und Worker. Nur
src/worker/geheimnisse.ts liest Chiffrat und Data-Key; ein struktureller
Test haelt fest, dass der Webprozess nichts von dort importiert und so
nie an den Master-Key kommt.

Die Zusatzdaten binden jedes Chiffrat an ID und Fingerprint seines
Schluessels: kopiert man es in eine andere Zeile, laesst es sich dort
nicht oeffnen. Der Deployment-Key entsteht beim ersten Start; ein Test
prueft, dass ein pg_dump keinen Klartext enthaelt.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 09:33:18 +02:00

42 lines
1.6 KiB
TypeScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { readFileSync, readdirSync, statSync } from "node:fs";
import path from "node:path";
import { describe, expect, it } from "vitest";
/**
* Strukturell (#006): Nur der Worker liest Chiffrat und Data-Key, und der Webprozess
* importiert nichts aus src/worker – sonst laege der Master-Key-Zugriff im Web.
*/
function dateien(verzeichnis: string): string[] {
return readdirSync(verzeichnis).flatMap((name) => {
const pfad = path.join(verzeichnis, name);
if (statSync(pfad).isDirectory()) return name === "generated" ? [] : dateien(pfad);
return /\.(ts|tsx)$/.test(name) ? [pfad.split(path.sep).join("/")] : [];
});
}
const ALLE = dateien("src");
/** Dateien, die die Namen tragen, ohne die Datenbank zu lesen – mit Begruendung. */
const NAMEN_ERLAUBT: Record<string, string> = {
"src/worker/geheimnisse.ts": "die eine Stelle, die liest",
"src/lib/krypto/umschlag.ts": "Feldname des Umschlags, rein rechnerisch",
"src/lib/protokoll-schwaerzen.ts": "Feldname in der Schwaerz-Liste",
};
describe("Grenze um die Private Keys", () => {
it("nur src/worker/geheimnisse.ts liest privatVerschluesselt und dekVerschluesselt", () => {
const verstoesse = ALLE.filter(
(datei) =>
!NAMEN_ERLAUBT[datei] && /privatVerschluesselt|dekVerschluesselt/.test(readFileSync(datei, "utf8")),
);
expect(verstoesse).toEqual([]);
});
it("nichts ausserhalb von src/worker importiert aus src/worker", () => {
const verstoesse = ALLE.filter(
(datei) => !datei.startsWith("src/worker/") && /from ["']@\/worker\//.test(readFileSync(datei, "utf8")),
);
expect(verstoesse).toEqual([]);
});
});