import assert from "node:assert/strict"; import { spawn } from "node:child_process"; import http from "node:http"; import path from "node:path"; import { describe, it } from "vitest"; const scriptPath = path.resolve("scripts/coolify-deploy.mjs"); const bearerToken = "coolify-test-token-sentinel"; const deployRevision = "a".repeat(40); const resourceUuid = "r".repeat(24); const otherResourceUuid = "s".repeat(24); const deploymentUuid = "d".repeat(24); const otherDeploymentUuid = "e".repeat(24); const mcpResourceUuid = "m".repeat(24); const apiResourceUuid = "a".repeat(24); const hocuspocusResourceUuid = "h".repeat(24); const portalDomainControllerResourceUuid = "c".repeat(24); const workerGroupResourceUuids = Object.freeze({ general: "g".repeat(24), mail: "l".repeat(24), import: "i".repeat(24), webhook: "v".repeat(24), plugin: "q".repeat(24), }); const workerResourceUuid = "w".repeat(24); const legacyMcpResourceUuid = "c".repeat(24); const webResourceUuid = "b".repeat(24); const adminResourceUuid = "n".repeat(24); const portalResourceUuid = "p".repeat(24); const adminDeploymentUuid = "f".repeat(24); const mcpImage = "registry.example.test/toolctrl-labs/hivegrid/mcp"; const workerImage = "registry.example.test/toolctrl-labs/hivegrid/worker"; const webImage = "registry.example.test/toolctrl-labs/hivegrid/web"; const apiImage = "registry.example.test/toolctrl-labs/hivegrid/api"; const hocuspocusImage = "registry.example.test/toolctrl-labs/hivegrid/hocuspocus"; const portalDomainControllerImage = "registry.example.test/toolctrl-labs/hivegrid/portal-domain-controller"; const webDigest = `sha256:${"f".repeat(64)}`; const sharedCryptoSecret = "shared-tenant-envelope-secret-sentinel"; const sharedAdminConnectionMasterKey = "shared-admin-connection-master-key-sentinel"; const gdprExportSseCKey = Buffer.alloc(32, 7).toString("base64"); const alternateGdprExportSseCKey = Buffer.alloc(32, 8).toString("base64"); const workerRedisSecrets = Object.freeze( Object.fromEntries(Object.keys(workerGroupResourceUuids).map((group) => [group, `worker-${group}-redis-secret-sentinel`])) ); const gdprExportStorageEnv = Object.freeze({ STORAGE_ENDPOINT: "https://storage.example.test", STORAGE_REGION: "eu-central-1", STORAGE_BUCKET: "private-exports", STORAGE_ACCESS_KEY_ID: "storage-access-key-sentinel", STORAGE_SECRET_ACCESS_KEY: "storage-secret-key-sentinel", STORAGE_FORCE_PATH_STYLE: "false", GDPR_EXPORT_SSE_C_KEY_BASE64: gdprExportSseCKey, }); const portalGdprExportStorageEnv = Object.freeze({ ...gdprExportStorageEnv, STORAGE_ACCESS_KEY_ID: "portal-storage-access-key-sentinel", STORAGE_SECRET_ACCESS_KEY: "portal-storage-secret-key-sentinel", }); const importGdprExportStorageEnv = Object.freeze({ ...gdprExportStorageEnv, STORAGE_ACCESS_KEY_ID: "import-storage-access-key-sentinel", STORAGE_SECRET_ACCESS_KEY: "import-storage-secret-key-sentinel", }); const GDPR_EXPORT_STORAGE_TEST_KEYS = new Set(Object.keys(gdprExportStorageEnv)); const gdprExportRetentionStorageEnv = Object.freeze( Object.fromEntries( Object.entries({ ...gdprExportStorageEnv, STORAGE_ACCESS_KEY_ID: "general-storage-access-key-sentinel", STORAGE_SECRET_ACCESS_KEY: "general-storage-secret-key-sentinel", }).filter(([key]) => key !== "GDPR_EXPORT_SSE_C_KEY_BASE64") ) ); const validRuntimeResourceLimits = Object.freeze({ limits_cpus: ".5", limits_memory: "512m" }); const validWebSurfaceResourceLimits = validRuntimeResourceLimits; const vapidSubject = "mailto:ops@hivegrid.de"; const vapidPublicKey = (() => { const bytes = Buffer.alloc(65, 1); bytes[0] = 0x04; return bytes.toString("base64url"); })(); const alternateVapidPublicKey = (() => { const bytes = Buffer.alloc(65, 3); bytes[0] = 0x04; return bytes.toString("base64url"); })(); const vapidPrivateKey = Buffer.alloc(32, 2).toString("base64url"); function portalRuntimeEnv(overrides = {}) { const values = { DATABASE_URL: "postgres://hivegrid_portal:portal-secret-sentinel@db.example.test:6432/hivegrid", DATABASE_READ_URL: "postgres://hivegrid_portal:portal-read-secret-sentinel@db.example.test/hivegrid", DATABASE_RUNTIME_ROLE: "hivegrid_portal", DATABASE_POOL_MAX: "10", RLS_RUNTIME_MODE: "required", WEB_RUNTIME_SURFACE: "portal", PORTAL_SESSION_SECRET: "dedicated-portal-session-secret-sentinel", CAPTCHA_PROVIDER: "mcaptcha", MCAPTCHA_INSTANCE_URL: "https://captcha.example.test", MCAPTCHA_SITEKEY_LOGIN: "portal-login-sitekey", MCAPTCHA_ACCOUNT_SECRET: "portal-mcaptcha-secret-sentinel", REDIS_URL: "rediss://portal-redis-secret-sentinel@redis.example.test:6380/3", ...overrides, }; return Object.entries(values) .filter(([, value]) => value !== undefined) .map(([key, value]) => ({ key, value })); } function runtimeDatabaseEnv(role, overrides = {}) { const values = { DATABASE_URL: `postgres://${role}:runtime-secret-sentinel@db.example.test:6432/hivegrid`, DATABASE_READ_URL: `postgres://${role}:read-secret-sentinel@db.example.test/hivegrid`, DATABASE_RUNTIME_ROLE: role, DATABASE_POOL_MAX: "10", RLS_RUNTIME_MODE: "required", ...overrides, }; return Object.entries(values) .filter(([, value]) => value !== undefined) .map(([key, value]) => ({ key, value })); } function runtimePreflightFixture() { const apps = [ { uuid: webResourceUuid, name: "hivegrid-web", build_pack: "dockerimage", docker_registry_image_name: webImage, ...validRuntimeResourceLimits, }, { uuid: portalResourceUuid, name: "hivegrid-portal", build_pack: "dockerimage", docker_registry_image_name: webImage, ...validRuntimeResourceLimits, }, { uuid: adminResourceUuid, name: "hivegrid-admin", build_pack: "dockerimage", docker_registry_image_name: webImage, ...validRuntimeResourceLimits, }, { uuid: apiResourceUuid, name: "hivegrid-api", docker_registry_image_name: apiImage, ...validRuntimeResourceLimits }, { uuid: mcpResourceUuid, name: "hivegrid-mcp", docker_registry_image_name: mcpImage, ...validRuntimeResourceLimits }, { uuid: hocuspocusResourceUuid, name: "hivegrid-hocuspocus", docker_registry_image_name: hocuspocusImage, ...validRuntimeResourceLimits }, { uuid: portalDomainControllerResourceUuid, name: "hivegrid-portal-domain-controller", docker_registry_image_name: portalDomainControllerImage, ...validRuntimeResourceLimits, }, ...Object.entries(workerGroupResourceUuids).map(([group, uuid]) => ({ uuid, name: `worker-${group}`, docker_registry_image_name: workerImage, ...validRuntimeResourceLimits, })), ]; const envByUuid = new Map([ [ webResourceUuid, runtimeDatabaseEnv("hivegrid_app", { WEB_RUNTIME_SURFACE: "core", PORTAL_APP_HOST: "portal.example.test", APP_BASE_DOMAIN: "example.test", WEB_APP_HOST: "app.example.test", ADMIN_APP_HOST: "admin.example.test", API_HOST: "api.example.test", CRYPTO_SECRET: sharedCryptoSecret, ADMIN_CONNECTION_MASTER_KEY: sharedAdminConnectionMasterKey, REDIS_URL: "rediss://core-redis-secret-sentinel@redis.example.test:6380/2", WEB_PUSH_VAPID_PUBLIC_KEY: vapidPublicKey, ...gdprExportStorageEnv, }), ], [ adminResourceUuid, runtimeDatabaseEnv("hivegrid_app", { WEB_RUNTIME_SURFACE: "admin", SESSION_SECRET: "dedicated-admin-session-secret-sentinel", ADMIN_FALLBACK_LOGIN_ENABLED: "false", AUTHENTIK_ISSUER_URL: "https://auth.example.test/application/o/hivegrid-admin/", AUTHENTIK_ADMIN_CLIENT_ID: "hivegrid-admin", AUTHENTIK_ADMIN_CLIENT_SECRET: "authentik-admin-client-secret-sentinel", AUTHENTIK_ADMIN_REDIRECT_URI: "https://admin.example.test/auth/admin/callback", AUTHENTIK_ADMIN_JIT_DATABASE_URL: "postgres://hivegrid_authentik_jit:jit-secret-sentinel@db.example.test/hivegrid", PORTAL_APP_HOST: "portal.example.test", APP_BASE_DOMAIN: "example.test", WEB_APP_HOST: "app.example.test", ADMIN_APP_HOST: "admin.example.test", API_HOST: "api.example.test", ADMIN_CONNECTION_MASTER_KEY: sharedAdminConnectionMasterKey, REDIS_URL: "rediss://admin-redis-secret-sentinel@redis.example.test:6380/5", ...gdprExportStorageEnv, }), ], [ portalResourceUuid, portalRuntimeEnv({ DATABASE_POOL_MAX: "6", PORTAL_APP_HOST: "https://Portal.Example.Test:443", APP_PROTOCOL: "https", ...portalGdprExportStorageEnv, }), ], [ apiResourceUuid, runtimeDatabaseEnv("hivegrid_app", { ADMIN_CONNECTION_MASTER_KEY: sharedAdminConnectionMasterKey, }), ], [mcpResourceUuid, runtimeDatabaseEnv("hivegrid_app")], [hocuspocusResourceUuid, runtimeDatabaseEnv("hivegrid_app")], ...Object.entries(workerGroupResourceUuids).map(([group, uuid]) => [ uuid, runtimeDatabaseEnv("hivegrid_worker", { WORKER_QUEUE_GROUP: group, ADMIN_CONNECTION_MASTER_KEY: sharedAdminConnectionMasterKey, BULLMQ_REDIS_URL: `rediss://${workerRedisSecrets[group]}@redis.example.test:6380/4`, ...(group === "mail" ? { PORTAL_APP_HOST: "portal.example.test:443" } : {}), ...(group === "mail" ? { APP_PROTOCOL: "https" } : {}), ...(group === "mail" ? { CRYPTO_SECRET: sharedCryptoSecret } : {}), ...(group === "general" ? { ...gdprExportRetentionStorageEnv, MEILI_URL: "http://meili.internal.test:7700", MEILI_API_KEY: "hivegrid-scoped-meili-key-sentinel", EXPORT_RETENTION_QUEUE_ENABLED: "true", } : {}), ...(group === "import" ? { ...importGdprExportStorageEnv, IMPORT_QUEUE_ENABLED: "false", IMPORT_QUEUE_RUNTIME_READY: "false", PORTAL_GDPR_EXPORT_QUEUE_ENABLED: "true", } : {}), ...(group === "webhook" ? { WEB_PUSH_VAPID_SUBJECT: vapidSubject, WEB_PUSH_VAPID_PUBLIC_KEY: vapidPublicKey, WEB_PUSH_VAPID_PRIVATE_KEY: vapidPrivateKey, } : {}), }), ]), ]); return { apps, envByUuid, allowedCsv: apps.map(({ uuid }) => uuid).join(","), }; } function runRuntimePreflight(serverUrl, allowedCsv) { return runHelper(serverUrl, "assert-runtime-preflight", allowedCsv, webImage, apiImage, mcpImage, hocuspocusImage, workerImage); } function webPushEnvPayload(requestUrl, overrides = {}) { if (requestUrl === `/applications/${webResourceUuid}/envs`) { return overrides.web ?? [{ key: "WEB_PUSH_VAPID_PUBLIC_KEY", value: vapidPublicKey }]; } if (requestUrl === `/applications/${workerResourceUuid}/envs`) { return ( overrides.worker ?? [ { key: "WEB_PUSH_VAPID_SUBJECT", value: vapidSubject }, { key: "WEB_PUSH_VAPID_PUBLIC_KEY", value: vapidPublicKey }, { key: "WEB_PUSH_VAPID_PRIVATE_KEY", value: vapidPrivateKey }, ] ); } return []; } function expectedMcpHealthConfig() { return { docker_registry_image_tag: deployRevision, health_check_enabled: true, health_check_type: "cmd", health_check_command: `node apps/mcp/dist/deploy-health.js ${deployRevision}`, health_check_interval: 30, health_check_timeout: 10, health_check_retries: 3, health_check_start_period: 20, }; } function runHelperWithEnv(serverUrl, envOverrides, ...args) { return new Promise((resolve) => { const child = spawn(process.execPath, [scriptPath, ...args], { env: { PATH: process.env.PATH || "", NODE_ENV: "test", SELECTED_COOLIFY_API_URL: serverUrl, SELECTED_COOLIFY_TOKEN: bearerToken, MCP_IMAGE: mcpImage, WORKER_IMAGE: workerImage, ...envOverrides, }, stdio: ["ignore", "pipe", "pipe"], }); let stdout = ""; let stderr = ""; child.stdout.setEncoding("utf8"); child.stderr.setEncoding("utf8"); child.stdout.on("data", (chunk) => { stdout += chunk; }); child.stderr.on("data", (chunk) => { stderr += chunk; }); child.on("close", (status) => { resolve({ status, stdout, stderr }); }); }); } function runHelper(serverUrl, ...args) { return runHelperWithEnv(serverUrl, {}, ...args); } async function readBody(request) { let body = ""; request.setEncoding("utf8"); for await (const chunk of request) { body += chunk; } return body; } function startServer(responder) { const requests = []; const serverErrors = []; const server = http.createServer(async (request, response) => { const recorded = { method: request.method, url: request.url, authorization: request.headers.authorization, body: await readBody(request), }; requests.push(recorded); try { const result = await responder(recorded, requests.length); response.writeHead(result?.status || 200, { "content-type": "application/json" }); response.end(JSON.stringify(result?.payload ?? {})); } catch (error) { serverErrors.push(error); response.writeHead(500, { "content-type": "application/json" }); response.end(JSON.stringify({ message: "test server assertion failed" })); } }); return new Promise((resolve, reject) => { server.once("error", reject); server.listen(0, "127.0.0.1", () => { resolve({ url: `http://127.0.0.1:${server.address().port}`, requests, serverErrors, close: () => new Promise((closeResolve, closeReject) => server.close((error) => (error ? closeReject(error) : closeResolve()))), }); }); }); } function assertSecretSafe(result) { assert.doesNotMatch(result.stdout, new RegExp(bearerToken)); assert.doesNotMatch(result.stderr, new RegExp(bearerToken)); for (const value of [ gdprExportStorageEnv.STORAGE_ACCESS_KEY_ID, gdprExportStorageEnv.STORAGE_SECRET_ACCESS_KEY, portalGdprExportStorageEnv.STORAGE_ACCESS_KEY_ID, portalGdprExportStorageEnv.STORAGE_SECRET_ACCESS_KEY, importGdprExportStorageEnv.STORAGE_ACCESS_KEY_ID, importGdprExportStorageEnv.STORAGE_SECRET_ACCESS_KEY, gdprExportRetentionStorageEnv.STORAGE_ACCESS_KEY_ID, gdprExportRetentionStorageEnv.STORAGE_SECRET_ACCESS_KEY, gdprExportSseCKey, alternateGdprExportSseCKey, ...Object.values(workerRedisSecrets), ]) { assert.doesNotMatch(`${result.stdout}${result.stderr}`, new RegExp(value)); } } function assertWebPushValuesSafe(result) { assertSecretSafe(result); for (const value of [vapidPublicKey, alternateVapidPublicKey, vapidPrivateKey]) { assert.doesNotMatch(`${result.stdout}${result.stderr}`, new RegExp(value)); } } describe("coolify-deploy CLI", () => { it("triggers the canonical deploy endpoint and emits only the deployment UUID", async () => { const server = await startServer(() => ({ payload: { deployments: [ { resource_uuid: otherResourceUuid, deployment_uuid: otherDeploymentUuid }, { resource_uuid: resourceUuid, deployment_uuid: deploymentUuid }, ], }, })); try { const result = await runHelper(server.url, "trigger", resourceUuid); assert.equal(result.status, 0, result.stderr); assert.equal(result.stdout.trim(), deploymentUuid); assert.equal(result.stderr, ""); assertSecretSafe(result); assert.deepEqual(server.serverErrors, []); assert.deepEqual(server.requests, [ { method: "POST", url: `/deploy?uuid=${resourceUuid}&force=true`, authorization: `Bearer ${bearerToken}`, body: "", }, ]); } finally { await server.close(); } }); it("fails closed when the deployment array does not contain the requested resource", async () => { const server = await startServer(() => ({ payload: { deployments: [{ resource_uuid: otherResourceUuid, deployment_uuid: otherDeploymentUuid }], }, })); try { const result = await runHelper(server.url, "trigger", resourceUuid); assert.equal(result.status, 1); assert.equal(result.stdout, ""); assert.match(result.stderr, /deployment UUID was not returned/); assert.doesNotMatch(result.stderr, new RegExp(otherDeploymentUuid)); assertSecretSafe(result); assert.deepEqual(server.serverErrors, []); assert.equal(server.requests.length, 1); } finally { await server.close(); } }); it("does not accept a legacy UUID when Coolify returns an empty deployment array", async () => { const server = await startServer(() => ({ payload: { deployments: [], deployment_uuid: "stale-legacy-deployment" }, })); try { const result = await runHelper(server.url, "trigger", resourceUuid); assert.equal(result.status, 1); assert.equal(result.stdout, ""); assert.match(result.stderr, /deployment UUID was not returned/); assert.doesNotMatch(result.stderr, /stale-legacy-deployment/); assertSecretSafe(result); } finally { await server.close(); } }); it("fails closed when the matching deployment entry has no UUID", async () => { const server = await startServer(() => ({ payload: { deployments: [{ resource_uuid: resourceUuid }] }, })); try { const result = await runHelper(server.url, "trigger", resourceUuid); assert.equal(result.status, 1); assert.equal(result.stdout, ""); assert.match(result.stderr, /deployment UUID was not returned/); assertSecretSafe(result); } finally { await server.close(); } }); it("rejects malformed resource and deployment IDs without emitting injectable output", async () => { const server = await startServer(() => ({ payload: { deployments: [{ resource_uuid: resourceUuid, deployment_uuid: `${deploymentUuid}\nINJECTED=value` }], }, })); try { const invalidResource = await runHelper(server.url, "trigger", `${resourceUuid}\nINJECTED=value`); assert.equal(invalidResource.status, 1); assert.equal(invalidResource.stdout, ""); assert.match(invalidResource.stderr, /valid Coolify CUID/); assert.deepEqual(server.requests, []); const invalidDeployment = await runHelper(server.url, "trigger", resourceUuid); assert.equal(invalidDeployment.status, 1); assert.equal(invalidDeployment.stdout, ""); assert.match(invalidDeployment.stderr, /deployment UUID was not returned/); assert.doesNotMatch(invalidDeployment.stderr, /INJECTED/); assertSecretSafe(invalidResource); assertSecretSafe(invalidDeployment); } finally { await server.close(); } }); it("accepts only applications without an APP_REVISION Coolify override", async () => { const cleanServer = await startServer(() => ({ payload: [] })); try { const result = await runHelper(cleanServer.url, "assert-no-app-revision-override", webResourceUuid); assert.equal(result.status, 0, result.stderr); assert.match(result.stdout, /override absent/); assert.deepEqual( cleanServer.requests.map(({ method, url }) => ({ method, url })), [{ method: "GET", url: `/applications/${webResourceUuid}/envs` }] ); assertSecretSafe(result); } finally { await cleanServer.close(); } const overrideServer = await startServer(() => ({ payload: [{ key: "APP_REVISION", value: "" }] })); try { const result = await runHelper(overrideServer.url, "assert-no-app-revision-override", webResourceUuid); assert.equal(result.status, 1); assert.equal(result.stdout, ""); assert.match(result.stderr, /APP_REVISION override must be removed/); assert.deepEqual( overrideServer.requests.map(({ method }) => method), ["GET"] ); assertSecretSafe(result); } finally { await overrideServer.close(); } }); it("retries legacy Coolify 4.0 environment reads with explicit decryption", async () => { const server = await startServer(({ url }) => url === `/applications/${webResourceUuid}/envs` ? { status: 404, payload: { message: "Not found" } } : { payload: [] } ); try { const result = await runHelper(server.url, "assert-no-app-revision-override", webResourceUuid); assert.equal(result.status, 0, result.stderr); assert.match(result.stdout, /override absent/); assert.deepEqual( server.requests.map(({ method, url }) => ({ method, url })), [ { method: "GET", url: `/applications/${webResourceUuid}/envs` }, { method: "GET", url: `/applications/${webResourceUuid}/envs?decrypt=true` }, ] ); assertSecretSafe(result); } finally { await server.close(); } }); it("fails closed on malformed revision-override environment responses", async () => { const server = await startServer(() => ({ payload: { unexpected: [] } })); try { const result = await runHelper(server.url, "assert-no-app-revision-override", webResourceUuid); assert.equal(result.status, 1); assert.match(result.stderr, /environment response was malformed/); assert.deepEqual( server.requests.map(({ method }) => method), ["GET"] ); assertSecretSafe(result); } finally { await server.close(); } }); it("accepts only a required-RLS runtime credential for the declared role", async () => { const server = await startServer(() => ({ payload: [ { key: "DATABASE_URL", value: "postgres://hivegrid_app:runtime-secret-sentinel@db.example.test:6432/hivegrid" }, { key: "DATABASE_READ_URL", value: "postgres://hivegrid_app:read-secret-sentinel@db.example.test/hivegrid" }, { key: "DATABASE_RUNTIME_ROLE", value: "hivegrid_app" }, { key: "DATABASE_POOL_MAX", value: "10" }, { key: "RLS_RUNTIME_MODE", value: "required" }, { key: "WEB_RUNTIME_SURFACE", value: "core" }, ], })); try { const result = await runHelper(server.url, "assert-runtime-db-env", webResourceUuid, "hivegrid_app", "web"); assert.equal(result.status, 0, result.stderr); assert.match(result.stdout, /verified for hivegrid_app/); assert.doesNotMatch(result.stdout, /runtime-secret-sentinel/); assertSecretSafe(result); } finally { await server.close(); } }); it("accepts the dedicated portal role and rejects core, OAuth, billing, migrator, and ingress credentials", async () => { const base = portalRuntimeEnv(); const cleanServer = await startServer(() => ({ payload: base })); try { const result = await runHelper(cleanServer.url, "assert-runtime-db-env", portalResourceUuid, "hivegrid_portal", "portal"); assert.equal(result.status, 0, result.stderr); assert.match(result.stdout, /verified for hivegrid_portal/); assert.doesNotMatch(`${result.stdout}${result.stderr}`, /secret-sentinel/); assertSecretSafe(result); } finally { await cleanServer.close(); } for (const key of [ "SESSION_SECRET", "AUTHENTIK_ADMIN_CLIENT_SECRET", "OAUTH_CLIENT_SECRET", "LAGO_API_KEY", "MIGRATOR_DATABASE_URL", "COOLIFY_TOKEN", "SSH_PRIVATE_KEY", "TRAEFIK_API_TOKEN", "PORTAL_DOMAIN_CONTROLLER_TOKEN", "PORTAL_SERVER_API_TOKEN", ]) { const server = await startServer(() => ({ payload: [...base, { key, value: "forbidden-secret-sentinel" }] })); try { const result = await runHelper(server.url, "assert-runtime-db-env", portalResourceUuid, "hivegrid_portal", "portal"); assert.equal(result.status, 1, `${key} unexpectedly passed`); assert.doesNotMatch(`${result.stdout}${result.stderr}`, /secret-sentinel/); assertSecretSafe(result); } finally { await server.close(); } } }); it("rejects an optional DATABASE_READ_URL whose username differs from the declared runtime role", async () => { const cases = [ { resource: webResourceUuid, role: "hivegrid_app", surface: "web", payload: [ { key: "DATABASE_URL", value: "postgres://hivegrid_app:runtime-secret-sentinel@db.example.test/hivegrid" }, { key: "DATABASE_READ_URL", value: "postgres://hivegrid_worker:read-secret-sentinel@db.example.test/hivegrid" }, { key: "DATABASE_RUNTIME_ROLE", value: "hivegrid_app" }, { key: "RLS_RUNTIME_MODE", value: "required" }, { key: "WEB_RUNTIME_SURFACE", value: "core" }, ], }, { resource: portalResourceUuid, role: "hivegrid_portal", surface: "portal", payload: portalRuntimeEnv({ DATABASE_READ_URL: "postgres://hivegrid_app:read-secret-sentinel@db.example.test/hivegrid", }), }, { resource: workerResourceUuid, role: "hivegrid_worker", surface: "service", payload: [ { key: "DATABASE_URL", value: "postgres://hivegrid_worker:runtime-secret-sentinel@db.example.test/hivegrid" }, { key: "DATABASE_READ_URL", value: "postgres://hivegrid_app:read-secret-sentinel@db.example.test/hivegrid" }, { key: "DATABASE_RUNTIME_ROLE", value: "hivegrid_worker" }, { key: "RLS_RUNTIME_MODE", value: "required" }, ], }, ]; for (const { resource, role, surface, payload } of cases) { const server = await startServer(() => ({ payload })); try { const result = await runHelper(server.url, "assert-runtime-db-env", resource, role, surface); assert.equal(result.status, 1, `${role} unexpectedly accepted a mismatched read role`); assert.match(result.stderr, /read database credential does not match DATABASE_RUNTIME_ROLE/); assert.doesNotMatch(`${result.stdout}${result.stderr}`, /secret-sentinel/); assertSecretSafe(result); } finally { await server.close(); } } }); it("accepts Cap portal login verification with a login-specific or shared secret", async () => { for (const secret of [{ CAP_SITE_SECRET_LOGIN: "cap-login-secret-sentinel" }, { CAP_SITE_SECRET: "cap-shared-secret-sentinel" }]) { const payload = portalRuntimeEnv({ CAPTCHA_PROVIDER: "cap", MCAPTCHA_INSTANCE_URL: undefined, MCAPTCHA_SITEKEY_LOGIN: undefined, MCAPTCHA_ACCOUNT_SECRET: undefined, CAP_INSTANCE_URL: "https://cap.example.test", CAP_SITEKEY_LOGIN: "portal-cap-login-sitekey", ...secret, }); const server = await startServer(() => ({ payload })); try { const result = await runHelper(server.url, "assert-runtime-db-env", portalResourceUuid, "hivegrid_portal", "portal"); assert.equal(result.status, 0, result.stderr); assert.doesNotMatch(`${result.stdout}${result.stderr}`, /secret-sentinel/); assertSecretSafe(result); } finally { await server.close(); } } }); it("rejects incomplete provider-specific portal CAPTCHA contracts", async () => { const capBase = { CAPTCHA_PROVIDER: "cap", CAP_INSTANCE_URL: "https://cap.example.test", CAP_SITEKEY_LOGIN: "portal-cap-login-sitekey", CAP_SITE_SECRET_LOGIN: "cap-login-secret-sentinel", }; const cases = [ { overrides: { CAPTCHA_PROVIDER: undefined }, expectedKey: "CAPTCHA_PROVIDER" }, { overrides: { CAPTCHA_PROVIDER: "unsupported" }, expectedKey: "CAPTCHA_PROVIDER" }, { overrides: { MCAPTCHA_INSTANCE_URL: undefined }, expectedKey: "MCAPTCHA_INSTANCE_URL" }, { overrides: { MCAPTCHA_SITEKEY_LOGIN: undefined }, expectedKey: "MCAPTCHA_SITEKEY_LOGIN" }, { overrides: { MCAPTCHA_ACCOUNT_SECRET: undefined }, expectedKey: "MCAPTCHA_ACCOUNT_SECRET" }, { overrides: { ...capBase, CAP_INSTANCE_URL: undefined }, expectedKey: "CAP_INSTANCE_URL" }, { overrides: { ...capBase, CAP_SITEKEY_LOGIN: undefined }, expectedKey: "CAP_SITEKEY_LOGIN" }, { overrides: { ...capBase, CAP_SITE_SECRET_LOGIN: undefined, CAP_SITE_SECRET: undefined }, expectedKey: "CAP_SITE_SECRET_LOGIN" }, ]; for (const { overrides, expectedKey } of cases) { const server = await startServer(() => ({ payload: portalRuntimeEnv(overrides) })); try { const result = await runHelper(server.url, "assert-runtime-db-env", portalResourceUuid, "hivegrid_portal", "portal"); assert.equal(result.status, 1, `${expectedKey} unexpectedly passed`); assert.match(result.stderr, new RegExp(expectedKey)); assert.doesNotMatch(`${result.stdout}${result.stderr}`, /secret-sentinel/); assertSecretSafe(result); } finally { await server.close(); } } }); it("rejects missing or invalid portal Redis and BullMQ connections", async () => { const cases = [ { overrides: { REDIS_URL: undefined }, expectedKey: "REDIS_URL" }, { overrides: { REDIS_URL: "https://redis-secret-sentinel.example.test" }, expectedKey: "REDIS_URL" }, { overrides: { BULLMQ_REDIS_URL: "redis://redis.example.test/not-a-database" }, expectedKey: "BULLMQ_REDIS_URL" }, ]; for (const { overrides, expectedKey } of cases) { const server = await startServer(() => ({ payload: portalRuntimeEnv(overrides) })); try { const result = await runHelper(server.url, "assert-runtime-db-env", portalResourceUuid, "hivegrid_portal", "portal"); assert.equal(result.status, 1, `${expectedKey} unexpectedly passed`); assert.match(result.stderr, new RegExp(expectedKey)); assert.doesNotMatch(`${result.stdout}${result.stderr}`, /secret-sentinel/); assertSecretSafe(result); } finally { await server.close(); } } }); it("requires the explicit core and portal runtime surfaces", async () => { for (const [role, surface, entries] of [ [ "hivegrid_app", "web", [ { key: "DATABASE_URL", value: "postgres://hivegrid_app:secret@db.example.test/hivegrid" }, { key: "DATABASE_RUNTIME_ROLE", value: "hivegrid_app" }, { key: "RLS_RUNTIME_MODE", value: "required" }, ], ], [ "hivegrid_portal", "portal", [ { key: "DATABASE_URL", value: "postgres://hivegrid_portal:secret@db.example.test/hivegrid" }, { key: "DATABASE_RUNTIME_ROLE", value: "hivegrid_portal" }, { key: "RLS_RUNTIME_MODE", value: "required" }, { key: "PORTAL_SESSION_SECRET", value: "portal-secret" }, ], ], ]) { const server = await startServer(() => ({ payload: entries })); try { const result = await runHelper(server.url, "assert-runtime-db-env", surface === "web" ? webResourceUuid : portalResourceUuid, role, surface); assert.equal(result.status, 1); assert.match(result.stderr, /WEB_RUNTIME_SURFACE/); } finally { await server.close(); } } }); it("requires an explicit positive pool cap and PgBouncer primary URL for every runtime", async () => { const base = runtimeDatabaseEnv("hivegrid_app", { WEB_RUNTIME_SURFACE: "core" }); const cases = [ { payload: base.filter(({ key }) => key !== "DATABASE_POOL_MAX"), error: /explicit positive DATABASE_POOL_MAX/, }, { payload: base.map((entry) => (entry.key === "DATABASE_POOL_MAX" ? { ...entry, value: "0" } : entry)), error: /explicit positive DATABASE_POOL_MAX/, }, { payload: base.map((entry) => entry.key === "DATABASE_URL" ? { ...entry, value: "postgres://hivegrid_app:runtime-secret-sentinel@db.example.test:5432/hivegrid" } : entry ), error: /PgBouncer port 6432/, }, ]; for (const { payload, error } of cases) { const server = await startServer(() => ({ payload })); try { const result = await runHelper(server.url, "assert-runtime-db-env", webResourceUuid, "hivegrid_app", "web"); assert.equal(result.status, 1); assert.match(result.stderr, error); assert.doesNotMatch(`${result.stdout}${result.stderr}`, /secret-sentinel/); assertSecretSafe(result); } finally { await server.close(); } } }); it("verifies positive hard caps on all twelve allowlisted runtimes with GET-only requests before migration", async () => { const fixture = runtimePreflightFixture(); const server = await startServer((request) => ({ payload: request.url === "/applications" ? fixture.apps : (fixture.envByUuid.get(request.url.split("/").at(-2)) ?? []), })); try { const result = await runRuntimePreflight(server.url, fixture.allowedCsv); assert.equal(result.status, 0, result.stderr); assert.match(result.stdout, /read-only runtime preflight verified/); assert.equal(result.stderr, ""); assert.equal(server.requests.length, 12); assert.ok(server.requests.every(({ method }) => method === "GET")); assert.equal(new Set(server.requests.map(({ url }) => url)).size, 12); assertSecretSafe(result); } finally { await server.close(); } }); it("rejects missing or invalid hard caps on API, MCP, and Hocuspocus runtimes", async () => { const cases = [ { uuid: apiResourceUuid, field: "limits_cpus", value: undefined, label: "API" }, { uuid: mcpResourceUuid, field: "limits_cpus", value: "0", label: "MCP" }, { uuid: hocuspocusResourceUuid, field: "limits_memory", value: "512", label: "Hocuspocus" }, ]; for (const { uuid, field, value, label } of cases) { const fixture = runtimePreflightFixture(); fixture.apps = fixture.apps.map((app) => (app.uuid === uuid ? { ...app, [field]: value } : app)); const server = await startServer((request) => ({ payload: request.url === "/applications" ? fixture.apps : (fixture.envByUuid.get(request.url.split("/").at(-2)) ?? []), })); try { const result = await runRuntimePreflight(server.url, fixture.allowedCsv); assert.equal(result.status, 1, `${label} resource limits unexpectedly passed`); assert.match(result.stderr, new RegExp(`Coolify ${label} runtime must set positive limits_cpus and unit-suffixed limits_memory hard caps`)); assert.ok(server.requests.every(({ method }) => method === "GET")); assertSecretSafe(result); } finally { await server.close(); } } }); it("rejects missing or invalid hard caps on every worker runtime", async () => { const invalidLimits = [ { field: "limits_cpus", value: undefined }, { field: "limits_cpus", value: "Infinity" }, { field: "limits_memory", value: undefined }, { field: "limits_memory", value: "0m" }, { field: "limits_memory", value: "1.5g" }, ]; for (const [index, [group, uuid]] of Object.entries(workerGroupResourceUuids).entries()) { const fixture = runtimePreflightFixture(); const { field, value } = invalidLimits[index]; fixture.apps = fixture.apps.map((app) => (app.uuid === uuid ? { ...app, [field]: value } : app)); const server = await startServer((request) => ({ payload: request.url === "/applications" ? fixture.apps : (fixture.envByUuid.get(request.url.split("/").at(-2)) ?? []), })); try { const result = await runRuntimePreflight(server.url, fixture.allowedCsv); assert.equal(result.status, 1, `worker-${group} resource limits unexpectedly passed`); assert.match(result.stderr, new RegExp(`Coolify worker-${group} runtime must set positive limits_cpus and unit-suffixed limits_memory hard caps`)); assert.ok(server.requests.every(({ method }) => method === "GET")); assertSecretSafe(result); } finally { await server.close(); } } }); it("requires positive CPU and unit-suffixed memory hard caps on the portal-domain-controller", async () => { for (const invalid of [{ limits_cpus: "0" }, { limits_memory: "512mb" }]) { const fixture = runtimePreflightFixture(); fixture.apps = fixture.apps.map((app) => (app.uuid === portalDomainControllerResourceUuid ? { ...app, ...invalid } : app)); const server = await startServer((request) => ({ payload: request.url === "/applications" ? fixture.apps : (fixture.envByUuid.get(request.url.split("/").at(-2)) ?? []), })); try { const result = await runRuntimePreflight(server.url, fixture.allowedCsv); assert.equal(result.status, 1, "portal-domain-controller resource limits unexpectedly passed"); assert.match( result.stderr, /Coolify portal-domain-controller runtime must set positive limits_cpus and unit-suffixed limits_memory hard caps/ ); assert.ok(server.requests.every(({ method }) => method === "GET")); assertSecretSafe(result); } finally { await server.close(); } } }); it("fails the runtime preflight when core lacks the distributed GDPR download Redis contract", async () => { for (const value of [undefined, "https://redis-secret-sentinel.example.test"]) { const fixture = runtimePreflightFixture(); fixture.envByUuid.set( webResourceUuid, fixture.envByUuid .get(webResourceUuid) .filter(({ key }) => key !== "REDIS_URL") .concat(value === undefined ? [] : [{ key: "REDIS_URL", value }]) ); const server = await startServer((request) => ({ payload: request.url === "/applications" ? fixture.apps : (fixture.envByUuid.get(request.url.split("/").at(-2)) ?? []), })); try { const result = await runRuntimePreflight(server.url, fixture.allowedCsv); assert.equal(result.status, 1); assert.match(result.stderr, /hivegrid-web runtime requires a valid REDIS_URL for distributed GDPR export download gates/); assert.doesNotMatch(`${result.stdout}${result.stderr}`, /redis-secret-sentinel/); assert.ok(server.requests.every(({ method }) => method === "GET")); assertSecretSafe(result); } finally { await server.close(); } } }); it("rejects APP_REVISION overrides on every pre-migration runtime without leaking values", async () => { const runtimeUuids = [...runtimePreflightFixture().envByUuid.keys()]; for (const uuid of runtimeUuids) { const fixture = runtimePreflightFixture(); fixture.envByUuid.set(uuid, [...fixture.envByUuid.get(uuid), { key: "APP_REVISION", value: `secret-${uuid}` }]); const server = await startServer((request) => ({ payload: request.url === "/applications" ? fixture.apps : (fixture.envByUuid.get(request.url.split("/").at(-2)) ?? []), })); try { const result = await runRuntimePreflight(server.url, fixture.allowedCsv); assert.equal(result.status, 1, `${uuid} APP_REVISION unexpectedly passed`); assert.match(result.stderr, /APP_REVISION overrides must be removed before migration/); assert.doesNotMatch(`${result.stdout}${result.stderr}`, new RegExp(`secret-${uuid}`)); assert.ok(server.requests.every(({ method }) => method === "GET")); assertSecretSafe(result); } finally { await server.close(); } } }); it("rejects the portal session secret on the core web runtime", async () => { const fixture = runtimePreflightFixture(); fixture.envByUuid.set(webResourceUuid, [ ...fixture.envByUuid.get(webResourceUuid), { key: "PORTAL_SESSION_SECRET", value: "core-portal-session-secret-sentinel" }, ]); const server = await startServer((request) => ({ payload: request.url === "/applications" ? fixture.apps : (fixture.envByUuid.get(request.url.split("/").at(-2)) ?? []), })); try { const result = await runRuntimePreflight(server.url, fixture.allowedCsv); assert.equal(result.status, 1); assert.match(result.stderr, /hivegrid-web runtime must not contain PORTAL_SESSION_SECRET/); assert.doesNotMatch(`${result.stdout}${result.stderr}`, /core-portal-session-secret-sentinel/); assert.ok(server.requests.every(({ method }) => method === "GET")); assertSecretSafe(result); } finally { await server.close(); } }); it("fails the runtime preflight when a worker group is missing or outside the allowlist", async () => { for (const mode of ["missing", "not-allowlisted"]) { const fixture = runtimePreflightFixture(); if (mode === "missing") { fixture.apps = fixture.apps.filter(({ uuid }) => uuid !== workerGroupResourceUuids.import); } else { fixture.allowedCsv = fixture.allowedCsv .split(",") .filter((uuid) => uuid !== workerGroupResourceUuids.import) .join(","); } const server = await startServer((request) => ({ payload: request.url === "/applications" ? fixture.apps : (fixture.envByUuid.get(request.url.split("/").at(-2)) ?? []), })); try { const result = await runRuntimePreflight(server.url, fixture.allowedCsv); assert.equal(result.status, 1, `${mode} worker unexpectedly passed`); assert.match(result.stderr, /worker-import runtime is missing, ambiguous, or outside the resource allowlist/); assert.ok(server.requests.every(({ method }) => method === "GET")); assertSecretSafe(result); } finally { await server.close(); } } }); it("fails the runtime preflight on portal-host or HTTPS drift across boundary consumers", async () => { const cases = [ { uuid: webResourceUuid, key: "PORTAL_APP_HOST", value: "other-portal.example.test", error: /same normalized PORTAL_APP_HOST/, }, { uuid: workerGroupResourceUuids.mail, key: "PORTAL_APP_HOST", value: "other-portal.example.test", error: /same normalized PORTAL_APP_HOST/, }, { uuid: workerGroupResourceUuids.mail, key: "PORTAL_APP_HOST", value: "portal.example.test:444", error: /same normalized PORTAL_APP_HOST/, }, { uuid: portalResourceUuid, key: "APP_PROTOCOL", value: "http", error: /must set APP_PROTOCOL=https/, }, { uuid: workerGroupResourceUuids.mail, key: "APP_PROTOCOL", value: "http", error: /must set APP_PROTOCOL=https/, }, ]; for (const testCase of cases) { const fixture = runtimePreflightFixture(); fixture.envByUuid.set( testCase.uuid, fixture.envByUuid.get(testCase.uuid).map((entry) => (entry.key === testCase.key ? { ...entry, value: testCase.value } : entry)) ); const server = await startServer((request) => ({ payload: request.url === "/applications" ? fixture.apps : (fixture.envByUuid.get(request.url.split("/").at(-2)) ?? []), })); try { const result = await runRuntimePreflight(server.url, fixture.allowedCsv); assert.equal(result.status, 1); assert.match(result.stderr, testCase.error); assert.ok(server.requests.every(({ method }) => method === "GET")); assertSecretSafe(result); } finally { await server.close(); } } }); it("fails the runtime preflight when worker-mail lacks the exact hivegrid-web envelope key without leaking either value", async () => { const cases = [ { uuid: webResourceUuid, mode: "missing" }, { uuid: workerGroupResourceUuids.mail, mode: "missing" }, { uuid: workerGroupResourceUuids.mail, mode: "mismatch" }, ]; for (const testCase of cases) { const fixture = runtimePreflightFixture(); const mismatchedSecret = `mismatched-${sharedCryptoSecret}`; fixture.envByUuid.set( testCase.uuid, testCase.mode === "missing" ? fixture.envByUuid.get(testCase.uuid).filter(({ key }) => key !== "CRYPTO_SECRET") : fixture.envByUuid.get(testCase.uuid).map((entry) => (entry.key === "CRYPTO_SECRET" ? { ...entry, value: mismatchedSecret } : entry)) ); const server = await startServer((request) => ({ payload: request.url === "/applications" ? fixture.apps : (fixture.envByUuid.get(request.url.split("/").at(-2)) ?? []), })); try { const result = await runRuntimePreflight(server.url, fixture.allowedCsv); assert.equal(result.status, 1); assert.match(result.stderr, /hivegrid-web and worker-mail must share the same non-empty CRYPTO_SECRET/); assert.doesNotMatch(`${result.stdout}${result.stderr}`, new RegExp(sharedCryptoSecret)); assert.doesNotMatch(`${result.stdout}${result.stderr}`, new RegExp(mismatchedSecret)); assert.ok(server.requests.every(({ method }) => method === "GET")); assertSecretSafe(result); } finally { await server.close(); } } }); it("fails the runtime preflight when the admin connection master-key boundary is missing, weak, mismatched, reused, or leaked to portal", async () => { const cases = [ { uuid: webResourceUuid, mutate: (entries) => entries.filter(({ key }) => key !== "ADMIN_CONNECTION_MASTER_KEY"), error: /ADMIN_CONNECTION_MASTER_KEY with at least 32 bytes on: hivegrid-web/, }, { uuid: apiResourceUuid, mutate: (entries) => entries.map((entry) => (entry.key === "ADMIN_CONNECTION_MASTER_KEY" ? { ...entry, value: "too-short" } : entry)), error: /ADMIN_CONNECTION_MASTER_KEY with at least 32 bytes on: hivegrid-api/, }, { uuid: workerGroupResourceUuids.general, mutate: (entries) => entries.map((entry) => (entry.key === "ADMIN_CONNECTION_MASTER_KEY" ? { ...entry, value: "mismatched-admin-connection-key-sentinel" } : entry)), error: /must share the same ADMIN_CONNECTION_MASTER_KEY/, }, { uuid: webResourceUuid, mutate: (entries) => entries.map((entry) => (entry.key === "CRYPTO_SECRET" ? { ...entry, value: sharedAdminConnectionMasterKey } : entry)), error: /must be independent from SESSION_SECRET and CRYPTO_SECRET on: hivegrid-web/, }, { uuid: portalResourceUuid, mutate: (entries) => [...entries, { key: "ADMIN_CONNECTION_MASTER_KEY", value: sharedAdminConnectionMasterKey }], error: /hivegrid-portal must not contain ADMIN_CONNECTION_MASTER_KEY/, }, ]; for (const testCase of cases) { const fixture = runtimePreflightFixture(); fixture.envByUuid.set(testCase.uuid, testCase.mutate(fixture.envByUuid.get(testCase.uuid))); const server = await startServer((request) => ({ payload: request.url === "/applications" ? fixture.apps : (fixture.envByUuid.get(request.url.split("/").at(-2)) ?? []), })); try { const result = await runRuntimePreflight(server.url, fixture.allowedCsv); assert.equal(result.status, 1); assert.match(result.stderr, testCase.error); assert.doesNotMatch(`${result.stdout}${result.stderr}`, new RegExp(sharedAdminConnectionMasterKey)); assert.ok(server.requests.every(({ method }) => method === "GET")); assertSecretSafe(result); } finally { await server.close(); } } }); it("fails the runtime preflight on encrypted GDPR export storage, key, or dedicated import-gate drift without leaking values", async () => { const cases = [ { uuid: webResourceUuid, key: "STORAGE_ENDPOINT", mode: "missing", error: /hivegrid-web runtime is missing required encrypted GDPR export environment keys: STORAGE_ENDPOINT/, }, { uuid: portalResourceUuid, key: "STORAGE_ENDPOINT", value: "http://storage.example.test", error: /hivegrid-portal runtime must set STORAGE_ENDPOINT to a valid HTTPS URL/, }, { uuid: workerGroupResourceUuids.import, key: "GDPR_EXPORT_SSE_C_KEY_BASE64", value: "not-canonical-base64", error: /worker-import runtime must set GDPR_EXPORT_SSE_C_KEY_BASE64 to canonical base64 for exactly 32 bytes/, }, { uuid: workerGroupResourceUuids.import, key: "GDPR_EXPORT_SSE_C_KEY_BASE64", value: alternateGdprExportSseCKey, error: /encrypted GDPR export runtime values must match after normalization for: GDPR_EXPORT_SSE_C_KEY_BASE64/, }, { uuid: workerGroupResourceUuids.import, key: "IMPORT_QUEUE_ENABLED", value: "true", error: /worker-import must use idle mode, full mode.*or dedicated GDPR export mode/, }, { uuid: workerGroupResourceUuids.import, key: "IMPORT_QUEUE_RUNTIME_READY", value: "true", error: /worker-import must use idle mode, full mode.*or dedicated GDPR export mode/, }, { uuid: workerGroupResourceUuids.import, key: "PORTAL_GDPR_EXPORT_QUEUE_ENABLED", value: "banana", error: /worker-import PORTAL_GDPR_EXPORT_QUEUE_ENABLED must be exactly true or false when configured/, redactedValue: true, }, { uuid: workerGroupResourceUuids.general, key: "EXPORT_RETENTION_QUEUE_ENABLED", value: "false", error: /worker-general must set EXPORT_RETENTION_QUEUE_ENABLED=true/, }, { uuid: workerGroupResourceUuids.general, key: "MEILI_URL", mode: "missing", error: /worker-general runtime is missing required tenant hard-delete search environment keys: MEILI_URL/, }, { uuid: workerGroupResourceUuids.general, key: "MEILI_API_KEY", mode: "missing", error: /worker-general runtime is missing required tenant hard-delete search environment keys: MEILI_API_KEY/, }, { uuid: workerGroupResourceUuids.general, key: "STORAGE_BUCKET", value: "other-private-exports", error: /GDPR export-retention storage values must match.*STORAGE_BUCKET/, }, ]; for (const testCase of cases) { const fixture = runtimePreflightFixture(); fixture.envByUuid.set( testCase.uuid, testCase.mode === "missing" ? fixture.envByUuid.get(testCase.uuid).filter(({ key }) => key !== testCase.key) : fixture.envByUuid.get(testCase.uuid).map((entry) => (entry.key === testCase.key ? { ...entry, value: testCase.value } : entry)) ); const server = await startServer((request) => ({ payload: request.url === "/applications" ? fixture.apps : (fixture.envByUuid.get(request.url.split("/").at(-2)) ?? []), })); try { const result = await runRuntimePreflight(server.url, fixture.allowedCsv); assert.equal(result.status, 1); assert.match(result.stderr, testCase.error); if (testCase.redactedValue) assert.doesNotMatch(`${result.stdout}${result.stderr}`, new RegExp(testCase.value)); assert.ok(server.requests.every(({ method }) => method === "GET")); assertSecretSafe(result); } finally { await server.close(); } } }); it("accepts full worker-import mode with encrypted GDPR export storage and an unset dedicated gate", async () => { const fixture = runtimePreflightFixture(); fixture.envByUuid.set( workerGroupResourceUuids.import, fixture.envByUuid .get(workerGroupResourceUuids.import) .filter(({ key }) => key !== "PORTAL_GDPR_EXPORT_QUEUE_ENABLED") .map((entry) => (entry.key === "IMPORT_QUEUE_ENABLED" || entry.key === "IMPORT_QUEUE_RUNTIME_READY" ? { ...entry, value: "true" } : entry)) ); const server = await startServer((request) => ({ payload: request.url === "/applications" ? fixture.apps : (fixture.envByUuid.get(request.url.split("/").at(-2)) ?? []), })); try { const result = await runRuntimePreflight(server.url, fixture.allowedCsv); assert.equal(result.status, 0, result.stderr); assert.match(result.stdout, /read-only runtime preflight verified/); assert.ok(server.requests.every(({ method }) => method === "GET")); assertSecretSafe(result); } finally { await server.close(); } }); it("accepts one shared storage credential across all GDPR export consumers without leaking it", async () => { const fixture = runtimePreflightFixture(); for (const uuid of [portalResourceUuid, workerGroupResourceUuids.import, workerGroupResourceUuids.general]) { fixture.envByUuid.set( uuid, fixture.envByUuid.get(uuid).map((entry) => { if (entry.key === "STORAGE_ACCESS_KEY_ID") { return { ...entry, value: gdprExportStorageEnv.STORAGE_ACCESS_KEY_ID }; } if (entry.key === "STORAGE_SECRET_ACCESS_KEY") { return { ...entry, value: gdprExportStorageEnv.STORAGE_SECRET_ACCESS_KEY }; } return entry; }) ); } const server = await startServer((request) => ({ payload: request.url === "/applications" ? fixture.apps : (fixture.envByUuid.get(request.url.split("/").at(-2)) ?? []), })); try { const result = await runRuntimePreflight(server.url, fixture.allowedCsv); assert.equal(result.status, 0, result.stderr); assert.match(result.stdout, /read-only runtime preflight verified/); assert.ok(server.requests.every(({ method }) => method === "GET")); assertSecretSafe(result); } finally { await server.close(); } }); it("rejects an SSE-C read key on the delete-only general worker without leaking it", async () => { const fixture = runtimePreflightFixture(); fixture.envByUuid.set(workerGroupResourceUuids.general, [ ...fixture.envByUuid.get(workerGroupResourceUuids.general), { key: "GDPR_EXPORT_SSE_C_KEY_BASE64", value: alternateGdprExportSseCKey }, ]); const server = await startServer((request) => ({ payload: request.url === "/applications" ? fixture.apps : (fixture.envByUuid.get(request.url.split("/").at(-2)) ?? []), })); try { const result = await runRuntimePreflight(server.url, fixture.allowedCsv); assert.equal(result.status, 1); assert.match(result.stderr, /worker-general must not contain GDPR_EXPORT_SSE_C_KEY_BASE64 because it is delete-only/); assertSecretSafe(result); } finally { await server.close(); } }); it("requires worker-import and worker-general to share a valid tenant-export barrier Redis target without leaking credentials", async () => { const cases = [ { uuid: workerGroupResourceUuids.import, mutate: (entries) => entries.filter(({ key }) => key !== "BULLMQ_REDIS_URL" && key !== "REDIS_URL"), error: /worker-import runtime requires a valid REDIS_URL or BULLMQ_REDIS_URL/, }, { uuid: workerGroupResourceUuids.general, mutate: (entries) => entries.map((entry) => (entry.key === "BULLMQ_REDIS_URL" ? { ...entry, value: "https://general-redis-secret-sentinel.example.test/4" } : entry)), error: /worker-general runtime requires a valid REDIS_URL or BULLMQ_REDIS_URL/, }, { uuid: workerGroupResourceUuids.import, mutate: (entries) => entries.map((entry) => entry.key === "BULLMQ_REDIS_URL" ? { ...entry, value: "rediss://import-drift-secret-sentinel@redis.example.test:6380/5" } : entry ), error: /worker-import and worker-general must use the same Redis endpoint and database/, }, ]; for (const testCase of cases) { const fixture = runtimePreflightFixture(); fixture.envByUuid.set(testCase.uuid, testCase.mutate(fixture.envByUuid.get(testCase.uuid))); const server = await startServer((request) => ({ payload: request.url === "/applications" ? fixture.apps : (fixture.envByUuid.get(request.url.split("/").at(-2)) ?? []), })); try { const result = await runRuntimePreflight(server.url, fixture.allowedCsv); assert.equal(result.status, 1); assert.match(result.stderr, testCase.error); assert.doesNotMatch(`${result.stdout}${result.stderr}`, /general-redis-secret|import-drift-secret/); assertSecretSafe(result); } finally { await server.close(); } } }); it("accepts idle worker-import mode without export storage while web surfaces retain the encrypted download contract", async () => { const fixture = runtimePreflightFixture(); fixture.envByUuid.set( workerGroupResourceUuids.import, fixture.envByUuid .get(workerGroupResourceUuids.import) .filter( ({ key }) => !GDPR_EXPORT_STORAGE_TEST_KEYS.has(key) && key !== "IMPORT_QUEUE_ENABLED" && key !== "IMPORT_QUEUE_RUNTIME_READY" && key !== "PORTAL_GDPR_EXPORT_QUEUE_ENABLED" ) ); const server = await startServer((request) => ({ payload: request.url === "/applications" ? fixture.apps : (fixture.envByUuid.get(request.url.split("/").at(-2)) ?? []), })); try { const result = await runRuntimePreflight(server.url, fixture.allowedCsv); assert.equal(result.status, 0, result.stderr); assert.match(result.stdout, /read-only runtime preflight verified/); assert.ok(server.requests.every(({ method }) => method === "GET")); assertSecretSafe(result); } finally { await server.close(); } }); it("rejects normalized storage-target drift across encrypted GDPR export consumers", async () => { const cases = [ { uuid: portalResourceUuid, key: "STORAGE_ENDPOINT", value: "https://other-storage.example.test", expectedKey: "STORAGE_ENDPOINT" }, { uuid: workerGroupResourceUuids.import, key: "STORAGE_REGION", value: "eu-west-1", expectedKey: "STORAGE_REGION" }, { uuid: webResourceUuid, key: "STORAGE_BUCKET", value: "other-private-exports", expectedKey: "STORAGE_BUCKET" }, { uuid: portalResourceUuid, key: "STORAGE_FORCE_PATH_STYLE", value: "true", expectedKey: "STORAGE_FORCE_PATH_STYLE" }, ]; for (const testCase of cases) { const fixture = runtimePreflightFixture(); fixture.envByUuid.set( testCase.uuid, fixture.envByUuid.get(testCase.uuid).map((entry) => (entry.key === testCase.key ? { ...entry, value: testCase.value } : entry)) ); const server = await startServer((request) => ({ payload: request.url === "/applications" ? fixture.apps : (fixture.envByUuid.get(request.url.split("/").at(-2)) ?? []), })); try { const result = await runRuntimePreflight(server.url, fixture.allowedCsv); assert.equal(result.status, 1); assert.match(result.stderr, new RegExp(`must match after normalization for: ${testCase.expectedKey}`)); assert.doesNotMatch(`${result.stdout}${result.stderr}`, new RegExp(testCase.value)); assert.ok(server.requests.every(({ method }) => method === "GET")); assertSecretSafe(result); } finally { await server.close(); } } }); it("rejects a portal host that aliases any canonical HTTPS core origin", async () => { for (const key of ["APP_BASE_DOMAIN", "WEB_APP_HOST", "ADMIN_APP_HOST", "API_HOST"]) { const fixture = runtimePreflightFixture(); fixture.envByUuid.set( webResourceUuid, fixture.envByUuid.get(webResourceUuid).map((entry) => (entry.key === key ? { ...entry, value: "https://PORTAL.EXAMPLE.TEST:443" } : entry)) ); const server = await startServer((request) => ({ payload: request.url === "/applications" ? fixture.apps : (fixture.envByUuid.get(request.url.split("/").at(-2)) ?? []), })); try { const result = await runRuntimePreflight(server.url, fixture.allowedCsv); assert.equal(result.status, 1, `${key} :443 alias unexpectedly passed`); assert.match(result.stderr, /PORTAL_APP_HOST must be distinct from core APP_BASE_DOMAIN, WEB_APP_HOST, ADMIN_APP_HOST, and API_HOST/); assert.ok(server.requests.every(({ method }) => method === "GET")); assertSecretSafe(result); } finally { await server.close(); } } }); it("includes the existing Web Push contract in the full read-only runtime preflight", async () => { const fixture = runtimePreflightFixture(); fixture.envByUuid.set( workerGroupResourceUuids.webhook, fixture.envByUuid.get(workerGroupResourceUuids.webhook).filter(({ key }) => key !== "WEB_PUSH_VAPID_PRIVATE_KEY") ); const server = await startServer((request) => ({ payload: request.url === "/applications" ? fixture.apps : (fixture.envByUuid.get(request.url.split("/").at(-2)) ?? []), })); try { const result = await runRuntimePreflight(server.url, fixture.allowedCsv); assert.equal(result.status, 1); assert.match(result.stderr, /WEB_PUSH_VAPID_PRIVATE_KEY/); assert.ok(server.requests.every(({ method }) => method === "GET")); assertSecretSafe(result); } finally { await server.close(); } }); it("fails the runtime preflight when any application or worker loses the pool cap", async () => { for (const uuid of [apiResourceUuid, workerGroupResourceUuids.general]) { const fixture = runtimePreflightFixture(); fixture.envByUuid.set( uuid, fixture.envByUuid.get(uuid).filter(({ key }) => key !== "DATABASE_POOL_MAX") ); const server = await startServer((request) => ({ payload: request.url === "/applications" ? fixture.apps : (fixture.envByUuid.get(request.url.split("/").at(-2)) ?? []), })); try { const result = await runRuntimePreflight(server.url, fixture.allowedCsv); assert.equal(result.status, 1); assert.match(result.stderr, /explicit positive DATABASE_POOL_MAX/); assert.ok(server.requests.every(({ method }) => method === "GET")); assertSecretSafe(result); } finally { await server.close(); } } }); it("accepts a complete shared Web Push runtime contract without emitting key material", async () => { const server = await startServer((request) => ({ payload: webPushEnvPayload(request.url) })); try { const result = await runHelper(server.url, "assert-web-push-env", webResourceUuid, workerResourceUuid); assert.equal(result.status, 0, result.stderr); assert.match(result.stdout, /Web Push runtime environment verified/); assert.equal(result.stderr, ""); assertWebPushValuesSafe(result); assert.deepEqual( new Set(server.requests.map(({ method, url }) => `${method} ${url}`)), new Set([`GET /applications/${webResourceUuid}/envs`, `GET /applications/${workerResourceUuid}/envs`]) ); } finally { await server.close(); } }); it("rejects every missing Web Push runtime key without emitting configured values", async () => { const cases = [ { overrides: { web: [] }, expectedKey: "WEB_PUSH_VAPID_PUBLIC_KEY" }, { overrides: { worker: [ { key: "WEB_PUSH_VAPID_PUBLIC_KEY", value: vapidPublicKey }, { key: "WEB_PUSH_VAPID_PRIVATE_KEY", value: vapidPrivateKey }, ], }, expectedKey: "WEB_PUSH_VAPID_SUBJECT", }, { overrides: { worker: [ { key: "WEB_PUSH_VAPID_SUBJECT", value: vapidSubject }, { key: "WEB_PUSH_VAPID_PRIVATE_KEY", value: vapidPrivateKey }, ], }, expectedKey: "WEB_PUSH_VAPID_PUBLIC_KEY", }, { overrides: { worker: [ { key: "WEB_PUSH_VAPID_SUBJECT", value: vapidSubject }, { key: "WEB_PUSH_VAPID_PUBLIC_KEY", value: vapidPublicKey }, ], }, expectedKey: "WEB_PUSH_VAPID_PRIVATE_KEY", }, ]; for (const { overrides, expectedKey } of cases) { const server = await startServer((request) => ({ payload: webPushEnvPayload(request.url, overrides) })); try { const result = await runHelper(server.url, "assert-web-push-env", webResourceUuid, workerResourceUuid); assert.equal(result.status, 1); assert.match(result.stderr, new RegExp(expectedKey)); assertWebPushValuesSafe(result); } finally { await server.close(); } } }); it("rejects invalid Web Push subjects and keys without emitting configured values", async () => { const cases = [ { worker: [ { key: "WEB_PUSH_VAPID_SUBJECT", value: "https://user:password@example.test/#fragment" }, { key: "WEB_PUSH_VAPID_PUBLIC_KEY", value: vapidPublicKey }, { key: "WEB_PUSH_VAPID_PRIVATE_KEY", value: vapidPrivateKey }, ], expectedKey: "WEB_PUSH_VAPID_SUBJECT", }, { web: [{ key: "WEB_PUSH_VAPID_PUBLIC_KEY", value: "not-base64url!" }], expectedKey: "WEB_PUSH_VAPID_PUBLIC_KEY" }, { worker: [ { key: "WEB_PUSH_VAPID_SUBJECT", value: vapidSubject }, { key: "WEB_PUSH_VAPID_PUBLIC_KEY", value: Buffer.alloc(64, 1).toString("base64url") }, { key: "WEB_PUSH_VAPID_PRIVATE_KEY", value: vapidPrivateKey }, ], expectedKey: "WEB_PUSH_VAPID_PUBLIC_KEY", }, { worker: [ { key: "WEB_PUSH_VAPID_SUBJECT", value: vapidSubject }, { key: "WEB_PUSH_VAPID_PUBLIC_KEY", value: vapidPublicKey }, { key: "WEB_PUSH_VAPID_PRIVATE_KEY", value: Buffer.alloc(31, 2).toString("base64url") }, ], expectedKey: "WEB_PUSH_VAPID_PRIVATE_KEY", }, ]; for (const { expectedKey, ...overrides } of cases) { const server = await startServer((request) => ({ payload: webPushEnvPayload(request.url, overrides) })); try { const result = await runHelper(server.url, "assert-web-push-env", webResourceUuid, workerResourceUuid); assert.equal(result.status, 1); assert.match(result.stderr, new RegExp(expectedKey)); assertWebPushValuesSafe(result); } finally { await server.close(); } } }); it("rejects different valid web and webhook-worker public keys", async () => { const worker = [ { key: "WEB_PUSH_VAPID_SUBJECT", value: vapidSubject }, { key: "WEB_PUSH_VAPID_PUBLIC_KEY", value: alternateVapidPublicKey }, { key: "WEB_PUSH_VAPID_PRIVATE_KEY", value: vapidPrivateKey }, ]; const server = await startServer((request) => ({ payload: webPushEnvPayload(request.url, { worker }) })); try { const result = await runHelper(server.url, "assert-web-push-env", webResourceUuid, workerResourceUuid); assert.equal(result.status, 1); assert.match(result.stderr, /WEB_PUSH_VAPID_PUBLIC_KEY values must match/); assertWebPushValuesSafe(result); } finally { await server.close(); } }); it("fails closed on preview-only or duplicate Web Push runtime keys", async () => { const cases = [ { web: [{ key: "WEB_PUSH_VAPID_PUBLIC_KEY", value: vapidPublicKey, is_preview: true }] }, { worker: [ { key: "WEB_PUSH_VAPID_SUBJECT", value: vapidSubject }, { key: "WEB_PUSH_VAPID_PUBLIC_KEY", value: vapidPublicKey }, { key: "WEB_PUSH_VAPID_PUBLIC_KEY", value: alternateVapidPublicKey }, { key: "WEB_PUSH_VAPID_PRIVATE_KEY", value: vapidPrivateKey }, ], }, ]; for (const overrides of cases) { const server = await startServer((request) => ({ payload: webPushEnvPayload(request.url, overrides) })); try { const result = await runHelper(server.url, "assert-web-push-env", webResourceUuid, workerResourceUuid); assert.equal(result.status, 1); assertWebPushValuesSafe(result); } finally { await server.close(); } } }); it("rejects privileged env keys, disabled RLS, and a mismatched runtime DSN without leaking credentials", async () => { for (const payload of [ [ { key: "DATABASE_URL", value: "postgres://hivegrid_app:runtime-secret-sentinel@db.example.test:6432/hivegrid" }, { key: "DATABASE_RUNTIME_ROLE", value: "hivegrid_app" }, { key: "DATABASE_POOL_MAX", value: "10" }, { key: "RLS_RUNTIME_MODE", value: "required" }, { key: "WEB_RUNTIME_SURFACE", value: "core" }, { key: "DIRECT_URL", value: "postgres://owner:owner-secret-sentinel@db.example.test/hivegrid" }, ], [ { key: "DATABASE_URL", value: "postgres://hivegrid_worker:runtime-secret-sentinel@db.example.test/hivegrid" }, { key: "DATABASE_RUNTIME_ROLE", value: "hivegrid_app" }, { key: "RLS_RUNTIME_MODE", value: "off" }, ], ]) { const server = await startServer(() => ({ payload })); try { const result = await runHelper(server.url, "assert-runtime-db-env", webResourceUuid, "hivegrid_app", "web"); assert.equal(result.status, 1); assert.doesNotMatch(result.stdout, /secret-sentinel/); assert.doesNotMatch(result.stderr, /secret-sentinel/); assertSecretSafe(result); } finally { await server.close(); } } }); it("accepts a complete admin-only Authentik Admin JIT credential for the dedicated role", async () => { const server = await startServer(() => ({ payload: [ { key: "DATABASE_URL", value: "postgres://hivegrid_app:runtime-secret-sentinel@db.example.test:6432/hivegrid" }, { key: "DATABASE_RUNTIME_ROLE", value: "hivegrid_app" }, { key: "DATABASE_POOL_MAX", value: "10" }, { key: "RLS_RUNTIME_MODE", value: "required" }, { key: "WEB_RUNTIME_SURFACE", value: "admin" }, { key: "SESSION_SECRET", value: "dedicated-admin-session-secret-sentinel" }, { key: "ADMIN_FALLBACK_LOGIN_ENABLED", value: "false" }, { key: "AUTHENTIK_ISSUER_URL", value: "https://auth.example.test/application/o/hivegrid-admin-panel/" }, { key: "AUTHENTIK_ADMIN_CLIENT_ID", value: "hivegrid-admin-panel" }, { key: "AUTHENTIK_ADMIN_CLIENT_SECRET", value: "oidc-secret-sentinel" }, { key: "AUTHENTIK_ADMIN_REDIRECT_URI", value: "https://admin.example.test/auth/admin/callback" }, { key: "AUTHENTIK_ADMIN_JIT_DATABASE_URL", value: "postgres://hivegrid_authentik_jit:jit-secret-sentinel@db.example.test/hivegrid", }, ], })); try { const result = await runHelper(server.url, "assert-runtime-db-env", adminResourceUuid, "hivegrid_app", "admin"); assert.equal(result.status, 0, result.stderr); assert.doesNotMatch(`${result.stdout}${result.stderr}`, /secret-sentinel/); assertSecretSafe(result); } finally { await server.close(); } }); it("rejects incomplete or wrongly authenticated admin JIT configuration without leaking credentials", async () => { for (const authentikEntries of [ [{ key: "AUTHENTIK_ISSUER_URL", value: "https://auth.example.test/application/o/hivegrid-admin-panel/" }], [ { key: "AUTHENTIK_ISSUER_URL", value: "https://auth.example.test/application/o/hivegrid-admin-panel/" }, { key: "AUTHENTIK_ADMIN_CLIENT_ID", value: "hivegrid-admin-panel" }, { key: "AUTHENTIK_ADMIN_CLIENT_SECRET", value: "oidc-secret-sentinel" }, { key: "AUTHENTIK_ADMIN_REDIRECT_URI", value: "https://admin.example.test/auth/admin/callback" }, { key: "AUTHENTIK_ADMIN_JIT_DATABASE_URL", value: "postgres://hivegrid_app:jit-secret-sentinel@db.example.test/hivegrid", }, ], ]) { const server = await startServer(() => ({ payload: [ { key: "DATABASE_URL", value: "postgres://hivegrid_app:runtime-secret-sentinel@db.example.test/hivegrid" }, { key: "DATABASE_RUNTIME_ROLE", value: "hivegrid_app" }, { key: "DATABASE_POOL_MAX", value: "10" }, { key: "RLS_RUNTIME_MODE", value: "required" }, { key: "WEB_RUNTIME_SURFACE", value: "admin" }, { key: "SESSION_SECRET", value: "dedicated-admin-session-secret-sentinel" }, { key: "ADMIN_FALLBACK_LOGIN_ENABLED", value: "false" }, ...authentikEntries, ], })); try { const result = await runHelper(server.url, "assert-runtime-db-env", adminResourceUuid, "hivegrid_app", "admin"); assert.equal(result.status, 1); assert.doesNotMatch(`${result.stdout}${result.stderr}`, /secret-sentinel/); assertSecretSafe(result); } finally { await server.close(); } } }); it("rejects every Authentik Admin secret outside the admin resource", async () => { for (const authentikEntry of [ { key: "AUTHENTIK_ADMIN_CLIENT_SECRET", value: "oidc-secret-sentinel" }, { key: "AUTHENTIK_ADMIN_JIT_DATABASE_URL", value: "postgres://hivegrid_authentik_jit:jit-secret-sentinel@db.example.test/hivegrid", }, ]) { const server = await startServer(() => ({ payload: [ { key: "DATABASE_URL", value: "postgres://hivegrid_worker:runtime-secret-sentinel@db.example.test/hivegrid" }, { key: "DATABASE_RUNTIME_ROLE", value: "hivegrid_worker" }, { key: "RLS_RUNTIME_MODE", value: "required" }, authentikEntry, ], })); try { const result = await runHelper(server.url, "assert-runtime-db-env", workerResourceUuid, "hivegrid_worker", "service"); assert.equal(result.status, 1); assert.match(result.stderr, /restricted to the admin resource/); assert.doesNotMatch(`${result.stdout}${result.stderr}`, /secret-sentinel/); assertSecretSafe(result); } finally { await server.close(); } } }); it("resolves exactly the named hivegrid-web, hivegrid-admin, and hivegrid-portal resources sharing the web image", async () => { const server = await startServer((request) => ({ payload: request.url === "/applications" ? [ { uuid: webResourceUuid, name: "hivegrid-web", build_pack: "dockerimage", docker_registry_image_name: webImage, ...validWebSurfaceResourceLimits, }, { uuid: adminResourceUuid, name: "hivegrid-admin", build_pack: "dockerimage", docker_registry_image_name: webImage, ...validWebSurfaceResourceLimits, }, { uuid: portalResourceUuid, name: "hivegrid-portal", build_pack: "dockerimage", docker_registry_image_name: webImage, ...validWebSurfaceResourceLimits, }, { uuid: otherResourceUuid, name: "hivegrid-api", docker_registry_image_name: apiImage }, ] : [], })); try { const result = await runHelper( server.url, "resolve-web-surfaces", `${webResourceUuid},${adminResourceUuid},${portalResourceUuid},${otherResourceUuid}`, webImage ); assert.equal(result.status, 0, result.stderr); assert.equal(result.stdout, `${webResourceUuid},${adminResourceUuid},${portalResourceUuid}`); assert.deepEqual( server.requests.map(({ method, url }) => `${method} ${url}`), [ "GET /applications", `GET /applications/${webResourceUuid}/envs`, `GET /applications/${adminResourceUuid}/envs`, `GET /applications/${portalResourceUuid}/envs`, ] ); assertSecretSafe(result); } finally { await server.close(); } }); it("rejects a Dockerfile web surface because digest pinning requires Coolify dockerimage mode", async () => { const server = await startServer((request) => ({ payload: request.url === "/applications" ? [ { uuid: webResourceUuid, name: "hivegrid-web", build_pack: "dockerimage", docker_registry_image_name: webImage, ...validWebSurfaceResourceLimits, }, { uuid: adminResourceUuid, name: "hivegrid-admin", build_pack: "dockerimage", docker_registry_image_name: webImage, ...validWebSurfaceResourceLimits, }, { uuid: portalResourceUuid, name: "hivegrid-portal", build_pack: "dockerfile", docker_registry_image_name: webImage, ...validWebSurfaceResourceLimits, }, ] : [], })); try { const result = await runHelper(server.url, "resolve-web-surfaces", `${webResourceUuid},${adminResourceUuid},${portalResourceUuid}`, webImage); assert.equal(result.status, 1); assert.match(result.stderr, /must use Coolify dockerimage mode for OCI digest pinning/); assert.deepEqual( server.requests.map(({ method, url }) => `${method} ${url}`), ["GET /applications"] ); assertSecretSafe(result); } finally { await server.close(); } }); it("requires independent positive CPU and unit-suffixed memory hard caps during web-trio inventory", async () => { const invalidLimits = [ { limits_cpus: undefined }, { limits_cpus: "0" }, { limits_cpus: "Infinity" }, { limits_memory: undefined }, { limits_memory: "0" }, { limits_memory: "0m" }, { limits_memory: "512" }, { limits_memory: ".5g" }, { limits_memory: "1.5g" }, { limits_memory: "512mb" }, ]; for (const target of ["core", "admin", "portal"]) { for (const invalid of invalidLimits) { const apps = [ { uuid: webResourceUuid, name: "hivegrid-web", build_pack: "dockerimage", docker_registry_image_name: webImage, ...validWebSurfaceResourceLimits, }, { uuid: adminResourceUuid, name: "hivegrid-admin", build_pack: "dockerimage", docker_registry_image_name: webImage, ...validWebSurfaceResourceLimits, }, { uuid: portalResourceUuid, name: "hivegrid-portal", build_pack: "dockerimage", docker_registry_image_name: webImage, ...validWebSurfaceResourceLimits, }, ]; Object.assign(apps[target === "core" ? 0 : target === "admin" ? 1 : 2], invalid); const server = await startServer(() => ({ payload: apps })); try { const result = await runHelper(server.url, "resolve-web-surfaces", `${webResourceUuid},${adminResourceUuid},${portalResourceUuid}`, webImage); assert.equal(result.status, 1, `${target} unexpectedly accepted ${JSON.stringify(invalid)}`); assert.match(result.stderr, /positive limits_cpus and unit-suffixed limits_memory hard caps/); assert.deepEqual( server.requests.map(({ method, url }) => `${method} ${url}`), ["GET /applications"] ); } finally { await server.close(); } } } }); it("rejects image-first, missing, extra, or revision-overridden web surface inventories", async () => { const cases = [ [ { uuid: webResourceUuid, name: "some-web", docker_registry_image_name: webImage }, { uuid: portalResourceUuid, name: "hivegrid-portal", docker_registry_image_name: webImage }, ], [{ uuid: webResourceUuid, name: "hivegrid-web", docker_registry_image_name: webImage }], [ { uuid: webResourceUuid, name: "hivegrid-web", docker_registry_image_name: webImage }, { uuid: portalResourceUuid, name: "hivegrid-portal", docker_registry_image_name: webImage }, { uuid: otherResourceUuid, name: "hivegrid-web-copy", docker_registry_image_name: webImage }, ], ]; for (const apps of cases) { const server = await startServer((request) => ({ payload: request.url === "/applications" ? apps : [] })); try { const result = await runHelper(server.url, "resolve-web-surfaces", `${webResourceUuid},${portalResourceUuid},${otherResourceUuid}`, webImage); assert.equal(result.status, 1); assert.match(result.stderr, /exactly the explicit hivegrid-web, hivegrid-admin, and hivegrid-portal/); assert.equal(server.requests.filter(({ method }) => method !== "GET").length, 0); } finally { await server.close(); } } const overrideServer = await startServer((request) => ({ payload: request.url === "/applications" ? [ { uuid: webResourceUuid, name: "hivegrid-web", build_pack: "dockerimage", docker_registry_image_name: webImage, ...validWebSurfaceResourceLimits, }, { uuid: adminResourceUuid, name: "hivegrid-admin", build_pack: "dockerimage", docker_registry_image_name: webImage, ...validWebSurfaceResourceLimits, }, { uuid: portalResourceUuid, name: "hivegrid-portal", build_pack: "dockerimage", docker_registry_image_name: webImage, ...validWebSurfaceResourceLimits, }, ] : request.url === `/applications/${portalResourceUuid}/envs` ? [{ key: "APP_REVISION", value: "" }] : [], })); try { const result = await runHelper(overrideServer.url, "resolve-web-surfaces", `${webResourceUuid},${adminResourceUuid},${portalResourceUuid}`, webImage); assert.equal(result.status, 1); assert.match(result.stderr, /web surface APP_REVISION overrides/); } finally { await overrideServer.close(); } }); it("patches and rereads all three explicit web surfaces with one full SHA and digest", async () => { const apps = new Map([ [ webResourceUuid, { uuid: webResourceUuid, name: "hivegrid-web", build_pack: "dockerimage", docker_registry_image_name: webImage, docker_registry_image_tag: "e".repeat(40), ...validWebSurfaceResourceLimits, }, ], [ adminResourceUuid, { uuid: adminResourceUuid, name: "hivegrid-admin", build_pack: "dockerimage", docker_registry_image_name: webImage, docker_registry_image_tag: "e".repeat(40), ...validWebSurfaceResourceLimits, }, ], [ portalResourceUuid, { uuid: portalResourceUuid, name: "hivegrid-portal", build_pack: "dockerimage", docker_registry_image_name: webImage, docker_registry_image_tag: "e".repeat(40), ...validWebSurfaceResourceLimits, }, ], ]); const server = await startServer(async (request) => { const uuid = request.url.split("/").at(-1); const app = apps.get(uuid); if (request.method === "PATCH") { Object.assign(app, JSON.parse(request.body)); } return { payload: app }; }); try { const result = await runHelper( server.url, "set-web-surface-release", webResourceUuid, adminResourceUuid, portalResourceUuid, webImage, deployRevision, webDigest ); assert.equal(result.status, 0, result.stderr); assert.match(result.stdout, new RegExp(`${webImage}@${webDigest}`)); const patches = server.requests.filter(({ method }) => method === "PATCH"); assert.equal(patches.length, 3); for (const patchRequest of patches) { assert.deepEqual(JSON.parse(patchRequest.body), { pre_deployment_command: "", post_deployment_command: "", docker_registry_image_tag: `sha256-${"f".repeat(64)}`, }); } assert.equal(apps.get(webResourceUuid).docker_registry_image_tag, `sha256-${"f".repeat(64)}`); assert.equal(apps.get(adminResourceUuid).docker_registry_image_tag, `sha256-${"f".repeat(64)}`); assert.equal(apps.get(portalResourceUuid).docker_registry_image_tag, `sha256-${"f".repeat(64)}`); assertSecretSafe(result); } finally { await server.close(); } }); it("rejects missing hard caps when explicit web UUIDs are reread before release mutation", async () => { const apps = new Map([ [ webResourceUuid, { uuid: webResourceUuid, name: "hivegrid-web", build_pack: "dockerimage", docker_registry_image_name: webImage, ...validWebSurfaceResourceLimits, }, ], [ adminResourceUuid, { uuid: adminResourceUuid, name: "hivegrid-admin", build_pack: "dockerimage", docker_registry_image_name: webImage, ...validWebSurfaceResourceLimits, }, ], [ portalResourceUuid, { uuid: portalResourceUuid, name: "hivegrid-portal", build_pack: "dockerimage", docker_registry_image_name: webImage, limits_cpus: "1", limits_memory: "0", }, ], ]); const server = await startServer((request) => ({ payload: apps.get(request.url.split("/").at(-1)) })); try { const result = await runHelper( server.url, "set-web-surface-release", webResourceUuid, adminResourceUuid, portalResourceUuid, webImage, deployRevision, webDigest ); assert.equal(result.status, 1); assert.match(result.stderr, /positive limits_cpus and unit-suffixed limits_memory hard caps/); assert.deepEqual( server.requests.map(({ method }) => method), ["GET", "GET", "GET"] ); assertSecretSafe(result); } finally { await server.close(); } }); it("proves all three completed web deployments are healthy and pinned to the same registry digest", async () => { const digestTag = `sha256-${"f".repeat(64)}`; const server = await startServer((request) => { if (request.url === `/applications/${webResourceUuid}`) { return { payload: { id: 101, uuid: webResourceUuid, name: "hivegrid-web", build_pack: "dockerimage", status: "running:healthy", docker_registry_image_name: webImage, docker_registry_image_tag: digestTag, ...validWebSurfaceResourceLimits, }, }; } if (request.url === `/applications/${adminResourceUuid}`) { return { payload: { id: 103, uuid: adminResourceUuid, name: "hivegrid-admin", build_pack: "dockerimage", status: "running:healthy", docker_registry_image_name: webImage, docker_registry_image_tag: digestTag, ...validWebSurfaceResourceLimits, }, }; } if (request.url === `/applications/${portalResourceUuid}`) { return { payload: { id: 102, uuid: portalResourceUuid, name: "hivegrid-portal", build_pack: "dockerimage", status: "running:healthy", docker_registry_image_name: webImage, docker_registry_image_tag: digestTag, ...validWebSurfaceResourceLimits, }, }; } if (request.url === `/deployments/${deploymentUuid}`) { return { payload: { application_id: "101", application_name: "hivegrid-web", deployment_uuid: deploymentUuid, status: "finished", }, }; } if (request.url === `/deployments/${otherDeploymentUuid}`) { return { payload: { application_id: "102", application_name: "hivegrid-portal", deployment_uuid: otherDeploymentUuid, status: "finished", }, }; } if (request.url === `/deployments/${adminDeploymentUuid}`) { return { payload: { application_id: "103", application_name: "hivegrid-admin", deployment_uuid: adminDeploymentUuid, status: "finished", }, }; } return { status: 404, payload: {} }; }); try { const result = await runHelper( server.url, "assert-web-surface-release", webResourceUuid, adminResourceUuid, portalResourceUuid, webImage, deployRevision, webDigest, deploymentUuid, adminDeploymentUuid, otherDeploymentUuid ); assert.equal(result.status, 0, result.stderr); assert.match(result.stdout, new RegExp(`${webImage}:${deployRevision} at ${webImage}@${webDigest}`)); const requests = server.requests.map(({ method, url }) => `${method} ${url}`); assert.deepEqual( requests.slice(0, 3).sort(), [`GET /applications/${webResourceUuid}`, `GET /applications/${adminResourceUuid}`, `GET /applications/${portalResourceUuid}`].sort() ); assert.deepEqual( requests.slice(3).sort(), [`GET /deployments/${deploymentUuid}`, `GET /deployments/${adminDeploymentUuid}`, `GET /deployments/${otherDeploymentUuid}`].sort() ); assertSecretSafe(result); } finally { await server.close(); } }); it("rejects digest drift and a deployment that is not bound to the expected surface", async () => { for (const drift of ["digest", "deployment"]) { const digestTag = `sha256-${"f".repeat(64)}`; const server = await startServer((request) => { const isPortal = request.url === `/applications/${portalResourceUuid}`; const isAdmin = request.url === `/applications/${adminResourceUuid}`; if (request.url === `/applications/${webResourceUuid}` || isAdmin || isPortal) { return { payload: { id: isPortal ? 102 : isAdmin ? 103 : 101, uuid: isPortal ? portalResourceUuid : isAdmin ? adminResourceUuid : webResourceUuid, name: isPortal ? "hivegrid-portal" : isAdmin ? "hivegrid-admin" : "hivegrid-web", build_pack: "dockerimage", status: "running:healthy", docker_registry_image_name: webImage, docker_registry_image_tag: drift === "digest" && isPortal ? `sha256-${"e".repeat(64)}` : digestTag, ...validWebSurfaceResourceLimits, }, }; } const isPortalDeployment = request.url === `/deployments/${otherDeploymentUuid}`; const isAdminDeployment = request.url === `/deployments/${adminDeploymentUuid}`; return { payload: { application_id: isPortalDeployment ? "102" : isAdminDeployment ? "103" : "101", application_name: drift === "deployment" && isPortalDeployment ? "hivegrid-web" : isPortalDeployment ? "hivegrid-portal" : "hivegrid-web", ...(isAdminDeployment ? { application_name: "hivegrid-admin" } : {}), deployment_uuid: isPortalDeployment ? otherDeploymentUuid : isAdminDeployment ? adminDeploymentUuid : deploymentUuid, status: "finished", }, }; }); try { const result = await runHelper( server.url, "assert-web-surface-release", webResourceUuid, adminResourceUuid, portalResourceUuid, webImage, deployRevision, webDigest, deploymentUuid, adminDeploymentUuid, otherDeploymentUuid ); assert.equal(result.status, 1); assert.match(result.stderr, drift === "digest" ? /not pinned to the expected registry digest/ : /expected named application/); assertSecretSafe(result); } finally { await server.close(); } } }); it("compensates the first web surface when the paired release mutation cannot update the second", async () => { const previousRevision = "e".repeat(40); const apps = new Map([ [ webResourceUuid, { uuid: webResourceUuid, name: "hivegrid-web", build_pack: "dockerimage", docker_registry_image_name: webImage, docker_registry_image_tag: previousRevision, ...validWebSurfaceResourceLimits, pre_deployment_command: "old-pre", post_deployment_command: "old-post", }, ], [ adminResourceUuid, { uuid: adminResourceUuid, name: "hivegrid-admin", build_pack: "dockerimage", docker_registry_image_name: webImage, docker_registry_image_tag: previousRevision, ...validWebSurfaceResourceLimits, }, ], [ portalResourceUuid, { uuid: portalResourceUuid, name: "hivegrid-portal", build_pack: "dockerimage", docker_registry_image_name: webImage, docker_registry_image_tag: previousRevision, ...validWebSurfaceResourceLimits, }, ], ]); let portalPatchFailed = false; const server = await startServer((request) => { const uuid = request.url.split("/").at(-1); const app = apps.get(uuid); if (request.method === "PATCH" && uuid === portalResourceUuid && !portalPatchFailed) { portalPatchFailed = true; return { status: 500, payload: { message: "sentinel must stay redacted" } }; } if (request.method === "PATCH") Object.assign(app, JSON.parse(request.body)); return { payload: app }; }); try { const result = await runHelper( server.url, "set-web-surface-release", webResourceUuid, adminResourceUuid, portalResourceUuid, webImage, deployRevision, webDigest ); assert.equal(result.status, 1); assert.match(result.stderr, /previous resource configuration was restored/); assert.equal(apps.get(webResourceUuid).docker_registry_image_tag, previousRevision); assert.equal(apps.get(webResourceUuid).pre_deployment_command, "old-pre"); assert.equal(apps.get(webResourceUuid).post_deployment_command, "old-post"); assert.equal(apps.get(adminResourceUuid).docker_registry_image_tag, previousRevision); assert.equal(server.requests.filter(({ method }) => method === "PATCH").length, 5); assertSecretSafe(result); } finally { await server.close(); } }); it("validates the exact allowlisted web, API, and MCP image inventory before mutations", async () => { const server = await startServer((request) => ({ payload: request.url === "/applications" ? [ { uuid: resourceUuid, docker_registry_image_name: webImage }, { uuid: otherResourceUuid, docker_registry_image_name: apiImage }, { uuid: mcpResourceUuid, docker_registry_image_name: mcpImage }, { uuid: webResourceUuid, docker_registry_image_name: mcpImage }, ] : [], })); try { const result = await runHelper( server.url, "validate-required-images", `${resourceUuid},${otherResourceUuid},${mcpResourceUuid}`, webImage, apiImage, mcpImage ); assert.equal(result.status, 0, result.stderr); assert.match(result.stdout, /inventory validated/); assert.deepEqual( server.requests.map(({ method, url }) => ({ method, url })), [ { method: "GET", url: "/applications" }, { method: "GET", url: `/applications/${resourceUuid}/envs` }, { method: "GET", url: `/applications/${otherResourceUuid}/envs` }, { method: "GET", url: `/applications/${mcpResourceUuid}/envs` }, ] ); assertSecretSafe(result); } finally { await server.close(); } }); it("rejects core APP_REVISION overrides during the read-only inventory preflight", async () => { const server = await startServer((request) => ({ payload: request.url === "/applications" ? [ { uuid: resourceUuid, docker_registry_image_name: webImage }, { uuid: otherResourceUuid, docker_registry_image_name: apiImage }, { uuid: mcpResourceUuid, docker_registry_image_name: mcpImage }, ] : request.url === `/applications/${mcpResourceUuid}/envs` ? [{ key: "APP_REVISION", value: "" }] : [], })); try { const result = await runHelper( server.url, "validate-required-images", `${resourceUuid},${otherResourceUuid},${mcpResourceUuid}`, webImage, apiImage, mcpImage ); assert.equal(result.status, 1); assert.match(result.stderr, /core application APP_REVISION overrides must be removed/); assert.equal(server.requests.filter(({ method }) => method !== "GET").length, 0); assertSecretSafe(result); } finally { await server.close(); } }); it("fails required image inventory validation when a target is missing or ambiguous", async () => { const server = await startServer(() => ({ payload: [ { uuid: resourceUuid, docker_registry_image_name: webImage }, { uuid: otherResourceUuid, docker_registry_image_name: apiImage }, { uuid: mcpResourceUuid, docker_registry_image_name: apiImage }, ], })); try { const result = await runHelper( server.url, "validate-required-images", `${resourceUuid},${otherResourceUuid},${mcpResourceUuid}`, webImage, apiImage, mcpImage ); assert.equal(result.status, 1); assert.equal(result.stdout, ""); assert.match(result.stderr, /inventory is missing, ambiguous, or invalid/); assert.deepEqual( server.requests.map(({ method }) => method), ["GET"] ); assertSecretSafe(result); } finally { await server.close(); } }); for (const [order, entries] of [ [ "preview-first", [ { key: "MIGRATE_ON_BOOT", value: "true", is_preview: true }, { key: "MIGRATE_ON_BOOT", value: "false", is_preview: false }, ], ], [ "runtime-first", [ { key: "MIGRATE_ON_BOOT", value: "false", is_preview: false }, { key: "MIGRATE_ON_BOOT", value: "true", is_preview: true }, ], ], ]) { it(`updates the non-preview runtime env independent of ${order} Coolify ordering`, async () => { const server = await startServer((request) => ({ payload: request.method === "GET" ? entries : {} })); try { const result = await runHelper(server.url, "set-envs", webResourceUuid, "MIGRATE_ON_BOOT=true"); assert.equal(result.status, 0, result.stderr); assert.match(result.stdout, /env MIGRATE_ON_BOOT updated/); assert.deepEqual( server.requests.map(({ method }) => method), ["GET", "PATCH"] ); assert.deepEqual(JSON.parse(server.requests[1].body), { key: "MIGRATE_ON_BOOT", value: "true", is_literal: true, is_preview: false, is_multiline: false, is_shown_once: false, }); assertSecretSafe(result); } finally { await server.close(); } }); } it("rejects duplicate non-preview env keys before set-envs mutation", async () => { const server = await startServer(() => ({ payload: [ { key: "MIGRATE_ON_BOOT", value: "false", is_preview: false }, { key: "MIGRATE_ON_BOOT", value: "true", is_preview: false }, ], })); try { const result = await runHelper(server.url, "set-envs", webResourceUuid, "MIGRATE_ON_BOOT=true"); assert.equal(result.status, 1); assert.match(result.stderr, /duplicate non-preview keys/); assert.deepEqual( server.requests.map(({ method }) => method), ["GET"] ); assertSecretSafe(result); } finally { await server.close(); } }); it("configures MCP command health and verifies the persisted state", async () => { const app = { uuid: mcpResourceUuid, docker_registry_image_name: mcpImage, docker_registry_image_tag: "previous", health_check_enabled: false, custom_healthcheck_found: false, }; const server = await startServer((request) => { if (request.method === "GET" && request.url.endsWith("/envs")) { return { payload: [] }; } if (request.method === "GET") { return { payload: app }; } if (request.method === "PATCH") { Object.assign(app, JSON.parse(request.body)); return { payload: app }; } return { status: 405, payload: { message: "method not allowed" } }; }); try { const result = await runHelper(server.url, "configure-mcp-healthcheck", mcpResourceUuid, deployRevision); assert.equal(result.status, 0, result.stderr); assert.equal(result.stderr, ""); assertSecretSafe(result); assert.deepEqual(server.serverErrors, []); assert.equal(server.requests.length, 4); assert.deepEqual( server.requests.map(({ method, url, authorization }) => ({ method, url, authorization })), [ { method: "GET", url: `/applications/${mcpResourceUuid}/envs`, authorization: `Bearer ${bearerToken}` }, { method: "GET", url: `/applications/${mcpResourceUuid}`, authorization: `Bearer ${bearerToken}` }, { method: "PATCH", url: `/applications/${mcpResourceUuid}`, authorization: `Bearer ${bearerToken}` }, { method: "GET", url: `/applications/${mcpResourceUuid}`, authorization: `Bearer ${bearerToken}` }, ] ); assert.equal(server.requests[0].body, ""); assert.equal(server.requests[1].body, ""); assert.deepEqual(JSON.parse(server.requests[2].body), expectedMcpHealthConfig()); assert.equal(server.requests[3].body, ""); } finally { await server.close(); } }); it("does not patch MCP health config that already matches the immutable revision", async () => { const server = await startServer((request) => ({ payload: request.url.endsWith("/envs") ? [] : { uuid: mcpResourceUuid, docker_registry_image_name: mcpImage, ...expectedMcpHealthConfig(), custom_healthcheck_found: false }, })); try { const result = await runHelper(server.url, "configure-mcp-healthcheck", mcpResourceUuid, deployRevision); assert.equal(result.status, 0, result.stderr); assert.equal(result.stderr, ""); assertSecretSafe(result); assert.deepEqual(server.serverErrors, []); assert.deepEqual(server.requests, [ { method: "GET", url: `/applications/${mcpResourceUuid}/envs`, authorization: `Bearer ${bearerToken}`, body: "", }, { method: "GET", url: `/applications/${mcpResourceUuid}`, authorization: `Bearer ${bearerToken}`, body: "", }, ]); } finally { await server.close(); } }); it("fails when MCP command health config is not persisted after the patch", async () => { const server = await startServer((request) => ({ payload: request.url.endsWith("/envs") ? [] : { uuid: mcpResourceUuid, docker_registry_image_name: mcpImage, docker_registry_image_tag: "previous", health_check_enabled: false, custom_healthcheck_found: false, }, })); try { const result = await runHelper(server.url, "configure-mcp-healthcheck", mcpResourceUuid, deployRevision); assert.equal(result.status, 1); assert.equal(result.stdout, ""); assert.match(result.stderr, /configuration was not persisted/); assertSecretSafe(result); assert.deepEqual(server.serverErrors, []); assert.deepEqual( server.requests.map(({ method }) => method), ["GET", "GET", "PATCH", "GET"] ); } finally { await server.close(); } }); it("rejects MCP APP_REVISION overrides before mutating application config", async () => { const server = await startServer((request) => ({ payload: request.url.endsWith("/envs") ? [{ key: "APP_REVISION", real_value: "" }] : {}, })); try { const result = await runHelper(server.url, "configure-mcp-healthcheck", mcpResourceUuid, deployRevision); assert.equal(result.status, 1); assert.equal(result.stdout, ""); assert.match(result.stderr, /APP_REVISION override must be removed/); assert.deepEqual( server.requests.map(({ method }) => method), ["GET"] ); assertSecretSafe(result); } finally { await server.close(); } }); it("rejects malformed MCP environment responses before mutating application config", async () => { const server = await startServer(() => ({ payload: { unexpected: [] } })); try { const result = await runHelper(server.url, "configure-mcp-healthcheck", mcpResourceUuid, deployRevision); assert.equal(result.status, 1); assert.equal(result.stdout, ""); assert.match(result.stderr, /environment response was malformed/); assert.deepEqual( server.requests.map(({ method }) => method), ["GET"] ); assertSecretSafe(result); } finally { await server.close(); } }); it("rejects MCP images whose built-in healthcheck would override command health", async () => { const server = await startServer((request) => ({ payload: request.url.endsWith("/envs") ? [] : { uuid: mcpResourceUuid, docker_registry_image_name: mcpImage, custom_healthcheck_found: true }, })); try { const result = await runHelper(server.url, "configure-mcp-healthcheck", mcpResourceUuid, deployRevision); assert.equal(result.status, 1); assert.equal(result.stdout, ""); assert.match(result.stderr, /image healthcheck must be absent/); assert.deepEqual( server.requests.map(({ method }) => method), ["GET", "GET"] ); assertSecretSafe(result); } finally { await server.close(); } }); it("rejects an MCP CUID that resolves to a different image before mutation", async () => { const server = await startServer((request) => ({ payload: request.url.endsWith("/envs") ? [] : { uuid: mcpResourceUuid, docker_registry_image_name: webImage, custom_healthcheck_found: false }, })); try { const result = await runHelperWithEnv(server.url, { MCP_IMAGE: mcpImage }, "configure-mcp-healthcheck", mcpResourceUuid, deployRevision); assert.equal(result.status, 1); assert.match(result.stderr, /does not use the expected MCP image/); assert.deepEqual( server.requests.map(({ method }) => method), ["GET", "GET"] ); assertSecretSafe(result); } finally { await server.close(); } }); it("rejects MCP targeting when no exact expected image identity is configured", async () => { const server = await startServer((request) => ({ payload: request.url.endsWith("/envs") ? [] : { uuid: mcpResourceUuid, docker_registry_image_name: mcpImage, custom_healthcheck_found: false }, })); try { const result = await runHelperWithEnv( server.url, { MCP_IMAGE: "", WORKER_IMAGE: "", REGISTRY: "", IMAGE_NAMESPACE: "", IMAGE_PREFIX: "" }, "configure-mcp-healthcheck", mcpResourceUuid, deployRevision ); assert.equal(result.status, 1); assert.match(result.stderr, /does not use the expected MCP image/); assert.deepEqual( server.requests.map(({ method }) => method), ["GET", "GET"] ); assertSecretSafe(result); } finally { await server.close(); } }); it("rejects a mutable MCP health revision before calling Coolify", async () => { const server = await startServer(() => ({ payload: {} })); try { const result = await runHelper(server.url, "configure-mcp-healthcheck", mcpResourceUuid, "staging"); assert.equal(result.status, 1); assert.equal(result.stdout, ""); assert.match(result.stderr, /full lowercase Git SHA/); assert.deepEqual(server.requests, []); assertSecretSafe(result); } finally { await server.close(); } }); it("atomically configures and rereads degraded legacy rollback health", async () => { const app = { uuid: workerResourceUuid, name: "legacy-worker", docker_registry_image_name: workerImage, docker_registry_image_tag: "newer", health_check_enabled: true, health_check_command: "new-command", }; const server = await startServer((request) => { if (request.method === "GET" && request.url.endsWith("/envs")) { return { payload: [{ key: "WORKER_QUEUE_GROUP", real_value: "'mail'" }] }; } if (request.method === "PATCH") { Object.assign(app, JSON.parse(request.body)); return { payload: app }; } if (request.method === "GET") { return { payload: app }; } return { status: 405, payload: {} }; }); try { const result = await runHelper(server.url, "configure-legacy-rollback-healthcheck", workerResourceUuid, deployRevision, "mail"); assert.equal(result.status, 0, result.stderr); assert.equal(result.stderr, ""); assert.match(result.stdout, /Legacy rollback image health configured/); assert.deepEqual( server.requests.map(({ method }) => method), ["GET", "GET", "PATCH", "GET"] ); assert.deepEqual(JSON.parse(server.requests[2].body), { docker_registry_image_tag: deployRevision, health_check_enabled: false, health_check_command: "", }); assertSecretSafe(result); } finally { await server.close(); } }); for (const [order, envs] of [ [ "preview-first", [ { key: "WORKER_QUEUE_GROUP", value: "general", is_preview: true }, { key: "WORKER_QUEUE_GROUP", value: "mail", is_preview: false }, ], ], [ "runtime-first", [ { key: "WORKER_QUEUE_GROUP", value: "mail", is_preview: false }, { key: "WORKER_QUEUE_GROUP", value: "general", is_preview: true }, ], ], ]) { it(`uses the non-preview worker group for legacy rollback with ${order} env ordering`, async () => { const app = { uuid: workerResourceUuid, docker_registry_image_name: workerImage, docker_registry_image_tag: "newer", health_check_enabled: true, health_check_command: "new-command", }; const server = await startServer((request) => { if (request.url.endsWith("/envs")) return { payload: envs }; if (request.method === "PATCH") { Object.assign(app, JSON.parse(request.body)); return { payload: app }; } return { payload: app }; }); try { const result = await runHelper(server.url, "configure-legacy-rollback-healthcheck", workerResourceUuid, deployRevision, "mail"); assert.equal(result.status, 0, result.stderr); assert.deepEqual( server.requests.map(({ method }) => method), ["GET", "GET", "PATCH", "GET"] ); assertSecretSafe(result); } finally { await server.close(); } }); } it("does not let a preview worker group authorize legacy runtime rollback", async () => { const server = await startServer((request) => ({ payload: request.url.endsWith("/envs") ? [ { key: "WORKER_QUEUE_GROUP", value: "mail", is_preview: true }, { key: "WORKER_QUEUE_GROUP", value: "general", is_preview: false }, ] : { docker_registry_image_name: workerImage }, })); try { const result = await runHelper(server.url, "configure-legacy-rollback-healthcheck", workerResourceUuid, deployRevision, "mail"); assert.equal(result.status, 1); assert.match(result.stderr, /worker group does not match/); assert.deepEqual( server.requests.map(({ method }) => method), ["GET", "GET"] ); assertSecretSafe(result); } finally { await server.close(); } }); it("fails closed when legacy rollback health config is not persisted", async () => { const server = await startServer((request) => ({ payload: request.url.endsWith("/envs") ? [] : { name: "legacy-mcp", docker_registry_image_name: mcpImage, docker_registry_image_tag: "newer", health_check_enabled: true, health_check_command: "new-command", }, })); try { const result = await runHelper(server.url, "configure-legacy-rollback-healthcheck", legacyMcpResourceUuid, deployRevision); assert.equal(result.status, 1); assert.equal(result.stdout, ""); assert.match(result.stderr, /configuration was not persisted/); assert.deepEqual( server.requests.map(({ method }) => method), ["GET", "GET", "PATCH", "GET"] ); assertSecretSafe(result); } finally { await server.close(); } }); it("rejects legacy rollback revision overrides and worker-group drift before mutation", async () => { const overrideServer = await startServer((request) => ({ payload: request.url.endsWith("/envs") ? [{ key: "APP_REVISION", value: "" }] : {}, })); try { const result = await runHelper(overrideServer.url, "configure-legacy-rollback-healthcheck", workerResourceUuid, deployRevision, "mail"); assert.equal(result.status, 1); assert.match(result.stderr, /APP_REVISION override must be removed/); assert.deepEqual( overrideServer.requests.map(({ method }) => method), ["GET"] ); assertSecretSafe(result); } finally { await overrideServer.close(); } const groupServer = await startServer((request) => ({ payload: request.url.endsWith("/envs") ? [{ key: "WORKER_QUEUE_GROUP", value: "general" }] : { name: "legacy-worker", docker_registry_image_name: workerImage }, })); try { const result = await runHelper(groupServer.url, "configure-legacy-rollback-healthcheck", workerResourceUuid, deployRevision, "mail"); assert.equal(result.status, 1); assert.match(result.stderr, /worker group does not match/); assert.deepEqual( groupServer.requests.map(({ method }) => method), ["GET", "GET"] ); assertSecretSafe(result); } finally { await groupServer.close(); } }); it("requires a group for legacy workers and rejects non-MCP/non-worker resources", async () => { const workerServer = await startServer((request) => ({ payload: request.url.endsWith("/envs") ? [{ key: "WORKER_QUEUE_GROUP", value: "mail" }] : { name: "legacy-worker", docker_registry_image_name: workerImage }, })); try { const result = await runHelper(workerServer.url, "configure-legacy-rollback-healthcheck", workerResourceUuid, deployRevision); assert.equal(result.status, 1); assert.match(result.stderr, /requires the exact worker group/); assert.deepEqual( workerServer.requests.map(({ method }) => method), ["GET", "GET"] ); assertSecretSafe(result); } finally { await workerServer.close(); } const webServer = await startServer((request) => ({ payload: request.url.endsWith("/envs") ? [] : { name: "legacy-worker-mcp", description: "worker mcp", docker_registry_image_name: webImage }, })); try { const result = await runHelper(webServer.url, "configure-legacy-rollback-healthcheck", webResourceUuid, deployRevision); assert.equal(result.status, 1); assert.match(result.stderr, /restricted to MCP and worker resources/); assert.deepEqual( webServer.requests.map(({ method }) => method), ["GET", "GET"] ); assertSecretSafe(result); } finally { await webServer.close(); } }); it("does not infer a legacy rollback target from spoofed names or descriptions", async () => { const server = await startServer((request) => ({ payload: request.url.endsWith("/envs") ? [{ key: "WORKER_QUEUE_GROUP", value: "mail" }] : { name: "worker-mail", description: "legacy mcp worker", docker_registry_image_name: webImage }, })); try { const result = await runHelper(server.url, "configure-legacy-rollback-healthcheck", webResourceUuid, deployRevision, "mail"); assert.equal(result.status, 1); assert.match(result.stderr, /restricted to MCP and worker resources/); assert.deepEqual( server.requests.map(({ method }) => method), ["GET", "GET"] ); assertSecretSafe(result); } finally { await server.close(); } }); it("rejects a different product's worker image before legacy rollback mutation", async () => { const server = await startServer((request) => ({ payload: request.url.endsWith("/envs") ? [{ key: "WORKER_QUEUE_GROUP", value: "mail" }] : { name: "worker-mail", docker_registry_image_name: "registry.example.test/other-product/worker" }, })); try { const result = await runHelper(server.url, "configure-legacy-rollback-healthcheck", workerResourceUuid, deployRevision, "mail"); assert.equal(result.status, 1); assert.match(result.stderr, /restricted to MCP and worker resources/); assert.deepEqual( server.requests.map(({ method }) => method), ["GET", "GET"] ); assert.equal(server.requests.filter(({ method }) => method === "PATCH").length, 0); assertSecretSafe(result); } finally { await server.close(); } }); it("rejects mutable legacy rollback revisions and invalid worker groups without calling Coolify", async () => { const server = await startServer(() => ({ payload: {} })); try { const mutableResult = await runHelper(server.url, "configure-legacy-rollback-healthcheck", workerResourceUuid, "main", "mail"); assert.equal(mutableResult.status, 1); assert.match(mutableResult.stderr, /full lowercase Git SHA/); const groupResult = await runHelper(server.url, "configure-legacy-rollback-healthcheck", workerResourceUuid, deployRevision, "all"); assert.equal(groupResult.status, 1); assert.match(groupResult.stderr, /valid worker group/); assert.deepEqual(server.requests, []); assertSecretSafe(mutableResult); assertSecretSafe(groupResult); } finally { await server.close(); } }); it("fails immediately for Coolify cancelled-by-user deployments", async () => { const server = await startServer(() => ({ payload: { status: "cancelled-by-user" } })); try { const result = await runHelper(server.url, "wait", deploymentUuid, "dependent"); assert.equal(result.status, 1); assert.match(result.stdout, /cancelled-by-user/); assert.match(result.stderr, /deployment failed/); assert.equal(server.requests.length, 1); assertSecretSafe(result); } finally { await server.close(); } }); it("redacts API response bodies when Coolify returns an error", async () => { const responseSentinel = "sensitive-coolify-response-sentinel"; const server = await startServer(() => ({ status: 401, payload: { message: responseSentinel }, })); try { const result = await runHelper(server.url, "trigger", resourceUuid); assert.equal(result.status, 1); assert.equal(result.stdout, ""); assert.match(result.stderr, /HTTP 401/); assert.doesNotMatch(result.stderr, new RegExp(responseSentinel)); assertSecretSafe(result); } finally { await server.close(); } }); it("bounds and redacts stalled Coolify API requests", async () => { const server = await startServer(async () => { await new Promise((resolve) => setTimeout(resolve, 100)); return { payload: { deployments: [] } }; }); try { const result = await runHelperWithEnv(server.url, { COOLIFY_API_TIMEOUT_MS: "10" }, "trigger", resourceUuid); assert.equal(result.status, 1); assert.equal(result.stdout, ""); assert.match(result.stderr, /failed or timed out/); assertSecretSafe(result); } finally { await server.close(); } }); });