Six modules take their secrets from files; the rest say precisely why not

From the survey of every env-file secret (ADR 0086, issue 041): amqp-ping,
minio, mongodb and grafana use the _FILE twin their software honours;
mesh-catalog and model-usage read DATABASE_URL_FILE (a file the mesh
templates, mounted where only the runtime reads it); grafana's secret files
belong to its own account. Two dead deliveries removed: a line nothing read
in amqp-email-forwarder, and mailu's secret.env on four containers that
never read it. The 25 exceptions that remain carry the surveyed reason —
convertible and awaiting a bed, convertible through a generated config file,
the application's own code, or not convertible.
This commit is contained in:
2026-09-21 12:29:25 +02:00
parent db597bcb71
commit 1a28e5aec6
26 changed files with 106 additions and 96 deletions
+15 -1
View File
@@ -1,3 +1,4 @@
import { readFileSync } from "node:fs";
// The vendor-neutral usage store (novox/hq ADR 0054). ONE table holds BOTH grains — licence and
// session — which differ only in `consumer`; a reading is one row `(licence, consumer, period,
// metric, value)` plus its `raw` vendor payload. The store keeps the LATEST reading per
@@ -47,7 +48,10 @@ export class UsageStore {
/** Build a store from the resolved environment — DATABASE_URL is the granted postgres connection,
* templated into the module's env-file from the mesh's binding (umami's DATABASE_URL precedent). */
static fromEnv(env: NodeJS.ProcessEnv = process.env): UsageStore {
return new UsageStore(new Pool({ connectionString: requireEnv("DATABASE_URL", env) }));
// As a file first (novox/hq ADR 0086): the connection string carries the password.
const url = env["DATABASE_URL"] ?? readMaybe(env["DATABASE_URL_FILE"]);
if (!url) throw new Error("DATABASE_URL_FILE (or DATABASE_URL) is not set — model-usage cannot reach its database");
return new UsageStore(new Pool({ connectionString: url }));
}
/** Create the one table if it is not there. Run once by the migrate entry before the consumer
@@ -84,3 +88,13 @@ export class UsageStore {
await this.pool.end();
}
}
/** The content of a file the environment names, its line ending gone — or undefined when it names none. */
function readMaybe(path: string | undefined): string | undefined {
if (!path) return undefined;
try {
return readFileSync(path, "utf8").replace(/\r?\n$/, "");
} catch {
return undefined;
}
}