Add HMAC auth, user permissions, snake_case rename
Each request is signed with HMAC-SHA256 over timestamp+body using a per-user secret loaded from a --secrets file (never env vars or git). Users have a canApprove list controlling who may approve queued actions. Queue entries track submitted_by for permission checks on approve/deny. Also renames all identifiers to snake_case throughout the codebase. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
23
server/secrets.mjs
Normal file
23
server/secrets.mjs
Normal file
@@ -0,0 +1,23 @@
|
||||
import { readFileSync } from "fs";
|
||||
|
||||
export function load_secrets(file_path) {
|
||||
if (!file_path) {
|
||||
throw new Error("--secrets <path> is required");
|
||||
}
|
||||
let raw;
|
||||
try {
|
||||
raw = readFileSync(file_path, "utf8");
|
||||
} catch (err) {
|
||||
throw new Error(`Cannot read secrets file at ${file_path}: ${err.message}`);
|
||||
}
|
||||
let parsed;
|
||||
try {
|
||||
parsed = JSON.parse(raw);
|
||||
} catch (err) {
|
||||
throw new Error(`Secrets file is not valid JSON: ${err.message}`);
|
||||
}
|
||||
if (!parsed.users || typeof parsed.users !== "object") {
|
||||
throw new Error("Secrets file must have a top-level 'users' object");
|
||||
}
|
||||
return parsed;
|
||||
}
|
||||
Reference in New Issue
Block a user