diff --git a/core/tests/doctor.test.ts b/core/tests/doctor.test.ts index 922ee83..32d5b92 100644 --- a/core/tests/doctor.test.ts +++ b/core/tests/doctor.test.ts @@ -958,6 +958,21 @@ describe("Ekklesia Doctor diagnostics", () => { expect(report.result).toBe("ready-with-warnings"); }); + it("says whose client-address configuration it checked: this process's, not a running API's", async () => { + for (const clientAddress of [ + undefined, + { header: "x-forwarded-for", mode: "trusted-proxy" as const, trustedProxies: ["10.0.0.1"] }, + { header: "x-forwarded-for", mode: "trusted-proxy" as const, trustedProxies: ["bad"] }, + ]) { + const report = await diagnoseEkklesia( + { ...options(), ...(clientAddress ? { clientAddress } : {}) }, + dependencies(), + ); + const details = check(report, "identity.client-address").details; + expect(details.some((detail) => detail.includes("environment Doctor runs with"))).toBe(true); + } + }); + it("passes client-address configuration with an explicitly configured trusted-proxy mode", async () => { const report = await diagnoseEkklesia( { diff --git a/scripts/smoke-deploy.sh b/scripts/smoke-deploy.sh index a133a65..26346d4 100755 --- a/scripts/smoke-deploy.sh +++ b/scripts/smoke-deploy.sh @@ -468,12 +468,16 @@ grep -q 'TLS required with certificate and hostname verification (explicit priva <<<"$doctor_output" || fail "Doctor did not report verify-full with the private CA." grep -q '✓ Object storage reachable' <<<"$doctor_output" || fail "Doctor could not reach object storage over HTTPS." +# Doctor runs as `migrate`; it must check the client-address configuration the API runs with, which +# behind the proxy is trusted-proxy mode, not the direct mode an unconfigured process reports. +grep -q 'Trusted-proxy client-address mode' <<<"$doctor_output" || + fail "Doctor did not check the API's trusted-proxy client-address configuration." for value in "$postgres_password" "$s3_secret_key" "$identity_secret"; do if grep -qF -- "$value" <<<"$doctor_output"; then fail "Doctor output contains a secret." fi done -echo "ok Doctor: READY, verify-full with the private CA, storage reachable, no secret printed" +echo "ok Doctor: READY, verify-full with the private CA, storage reachable, the API's client-address mode, no secret printed" api_logs="$("${compose[@]}" logs --no-color api 2>&1)" for value in "$postgres_password" "$s3_secret_key" "$identity_secret" "$owner_password"; do diff --git a/tests/deploy.test.ts b/tests/deploy.test.ts index 8dcfe6a..d072e9d 100644 --- a/tests/deploy.test.ts +++ b/tests/deploy.test.ts @@ -153,6 +153,11 @@ describe("reference deployment compose files", () => { EKKLESIA_CLIENT_ADDRESS_MODE: "trusted-proxy", EKKLESIA_CLIENT_ADDRESS_TRUSTED_PROXIES: `${proxyAddress}/32`, }); + // Doctor runs as `migrate`. Given anything else, it validates a configuration the API is not + // running, and reports "Direct" for an installation that trusts its proxy. + expect(proxyOverlay.services?.migrate?.environment).toEqual( + proxyOverlay.services?.api?.environment, + ); expect(proxyOverlay.networks?.edge?.ipam?.config).toEqual([ { ip_range: "${EKKLESIA_EDGE_DYNAMIC_RANGE:-10.249.250.0/25}",