docs(deploy): document user-owned session cutover

This commit is contained in:
User
2026-07-16 19:02:58 +02:00
parent c6a74c9ccb
commit cadc4c6947
12 changed files with 441 additions and 2 deletions
+51
View File
@@ -44,9 +44,60 @@ test("loadConfig accepts an authenticated upstream trust boundary", () => {
expect(loadConfig({
THOTH_PUBLIC_EXPOSURE: "true",
AUTH_MODE: "upstream",
THT_SESSION_STORAGE: "postgres",
THT_SESSION_DB_HOST: "db.internal",
THT_SESSION_DB_NAME: "thoth",
THT_SESSION_RUNTIME_USER: "thoth_sessions_app",
THT_SESSION_RUNTIME_PASSWORD_FILE: "/run/secrets/session_runtime_password",
THT_SESSION_DB_SSLMODE: "verify-full",
THT_SESSION_DB_SSLROOTCERT: "/run/secrets/session_ca.pem",
}).authMode).toBe("upstream");
});
test("loadConfig requires direct PostgreSQL TLS inputs for the public server session store", () => {
const env = {
THOTH_PUBLIC_EXPOSURE: "true",
AUTH_MODE: "upstream",
THT_SESSION_STORAGE: "postgres",
THT_SESSION_DB_HOST: "db.internal",
THT_SESSION_DB_NAME: "thoth",
THT_SESSION_RUNTIME_USER: "thoth_sessions_app",
THT_SESSION_RUNTIME_PASSWORD_FILE: "/run/secrets/session_runtime_password",
THT_SESSION_DB_SSLMODE: "verify-full",
THT_SESSION_DB_SSLROOTCERT: "/run/secrets/session_ca.pem",
};
expect(loadConfig(env).sessionStorage).toMatchObject({
mode: "postgres",
host: "db.internal",
port: 5432,
database: "thoth",
runtimeUser: "thoth_sessions_app",
runtimePasswordFile: "/run/secrets/session_runtime_password",
sslmode: "verify-full",
sslrootcert: "/run/secrets/session_ca.pem",
});
for (const required of [
"THT_SESSION_DB_HOST", "THT_SESSION_DB_NAME", "THT_SESSION_RUNTIME_USER",
"THT_SESSION_RUNTIME_PASSWORD_FILE", "THT_SESSION_DB_SSLMODE", "THT_SESSION_DB_SSLROOTCERT",
]) {
const missing = { ...env, [required]: undefined };
expect(() => loadConfig(missing)).toThrow(/server session storage configuration is invalid/);
}
});
test("loadConfig rejects public local storage and server storage without upstream auth", () => {
expect(() => loadConfig({
THOTH_PUBLIC_EXPOSURE: "true",
AUTH_MODE: "upstream",
THT_SESSION_STORAGE: "local",
})).toThrow(/local session storage requires loopback-only deployment/);
expect(() => loadConfig({
THT_SESSION_STORAGE: "postgres",
AUTH_MODE: "none",
})).toThrow(/server session storage requires AUTH_MODE=upstream/);
});
test("loadConfig accepts only an absolute generic model key file", () => {
expect(loadConfig({ THT_MODEL_API_KEY_FILE: "/run/secrets/model_api_key" }).modelApiKeyFile)
.toBe("/run/secrets/model_api_key");
+7
View File
@@ -15,6 +15,13 @@ test("GET /health remains available to container probes in upstream auth mode",
THT_HARNESS_DIR: "/tmp/h",
AUTH_MODE: "upstream",
THOTH_PUBLIC_EXPOSURE: "true",
THT_SESSION_STORAGE: "postgres",
THT_SESSION_DB_HOST: "db.internal",
THT_SESSION_DB_NAME: "thoth",
THT_SESSION_RUNTIME_USER: "thoth_sessions_app",
THT_SESSION_RUNTIME_PASSWORD_FILE: "/run/secrets/session_runtime_password",
THT_SESSION_DB_SSLMODE: "verify-full",
THT_SESSION_DB_SSLROOTCERT: "/run/secrets/session_ca.pem",
}));
const res = await app.inject({ method: "GET", url: "/health" });
expect(res.statusCode).toBe(200);