feat(policy-loader): 8.7 — env-var deprecation warnings (v8.0.0 removal)

This commit is contained in:
Kjell Tore Guttormsen 2026-04-30 17:11:07 +02:00
commit ba5f2b64ad
8 changed files with 252 additions and 24 deletions

View file

@ -1,9 +1,12 @@
// audit-trail.mjs — Structured JSONL audit trail writer
// Writes SIEM-ready events to the path specified by LLM_SECURITY_AUDIT_LOG.
// No-op when env var is not set. Zero external dependencies.
// Resolves the audit-log path via getPolicyValueWithEnvWarn so the env-var
// LLM_SECURITY_AUDIT_LOG and policy.json key audit.log_path stay in sync,
// with a one-time deprecation warning when both are explicitly set.
// No-op when neither env nor policy provides a path. Zero external dependencies.
import { appendFileSync, writeFileSync, accessSync, constants } from 'node:fs';
import { dirname } from 'node:path';
import { getPolicyValueWithEnvWarn } from './policy-loader.mjs';
let auditPath = null;
let initialized = false;
@ -16,19 +19,22 @@ function initAuditTrail() {
if (initialized) return auditPath !== null;
initialized = true;
const envPath = process.env.LLM_SECURITY_AUDIT_LOG;
if (!envPath) return false;
// D3 (v7.3.0): env still wins, deprecation warning when policy also set.
const resolved = getPolicyValueWithEnvWarn(
'audit', 'log_path', 'LLM_SECURITY_AUDIT_LOG', null
);
if (!resolved) return false;
try {
// Ensure parent directory exists and is writable
const dir = dirname(envPath);
const dir = dirname(resolved);
accessSync(dir, constants.W_OK);
// Touch file if it doesn't exist
try { accessSync(envPath); } catch { writeFileSync(envPath, ''); }
auditPath = envPath;
try { accessSync(resolved); } catch { writeFileSync(resolved, ''); }
auditPath = resolved;
return true;
} catch (err) {
process.stderr.write(`[llm-security] Audit trail path not writable: ${envPath} (${err.message})\n`);
process.stderr.write(`[llm-security] Audit trail path not writable: ${resolved} (${err.message})\n`);
return false;
}
}