Skip to content

Commit 39fb313

Browse files
matt-aitkenclaude
andcommitted
fix(webapp): close two bypass paths around the REQUIRE_PLUGINS healthcheck
Two paths could silently skip the new plugin-load gate, found in review: - server.ts: when DASHBOARD_AND_API_DISABLED=true, /healthcheck was served by a static Express handler (200 OK) that bypassed the Remix loader entirely. Forward to createRequestHandler in that branch too so the loader's readiness checks (DB ping + rbac.isUsingPlugin()) run in every deployment mode. - healthcheck.tsx: rbac.isUsingPlugin() sat after the HEALTHCHECK_DATABASE_DISABLED early return, so it never ran when that flag was set. The rbac fallback doesn't touch the DB (fallback.ts isUsingPlugin returns false unconditionally), so move the rbac check above the DB-disabled guard — REQUIRE_PLUGINS protection now applies regardless of the DB-healthcheck setting. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent b0f944c commit 39fb313

2 files changed

Lines changed: 20 additions & 10 deletions

File tree

apps/webapp/app/routes/healthcheck.tsx

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,18 +5,20 @@ import { rbac } from "~/services/rbac.server";
55

66
export const loader: LoaderFunction = async ({ request }) => {
77
try {
8+
// Resolve the lazy plugin controller so plugin-load failures surface
9+
// during readiness probes. With REQUIRE_PLUGINS=1, a failed plugin
10+
// load throws here and the rollout's readiness probe fails. The
11+
// fallback path doesn't touch the DB, so this runs even when
12+
// HEALTHCHECK_DATABASE_DISABLED=1 — REQUIRE_PLUGINS protection must
13+
// not be silently bypassed by the DB-disabled flag.
14+
await rbac.isUsingPlugin();
15+
816
if (env.HEALTHCHECK_DATABASE_DISABLED === "1") {
917
return new Response("OK");
1018
}
1119

1220
await prisma.$queryRaw`SELECT 1`;
1321

14-
// Resolve the lazy plugin controller so plugin-load failures surface
15-
// during readiness probes. With REQUIRE_PLUGINS=1, a failed plugin
16-
// load throws here and the rollout's readiness probe fails. Without
17-
// REQUIRE_PLUGINS, the fallback resolves cleanly and this is a noop.
18-
await rbac.isUsingPlugin();
19-
2022
return new Response("OK");
2123
} catch (error: unknown) {
2224
console.log("healthcheck ❌", { error });

apps/webapp/server.ts

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -188,10 +188,18 @@ if (ENABLE_CLUSTER && cluster.isPrimary) {
188188
})
189189
);
190190
} else {
191-
// we need to do the health check here at /healthcheck
192-
app.get("/healthcheck", (req, res) => {
193-
res.status(200).send("OK");
194-
});
191+
// we need to do the health check here at /healthcheck — forward
192+
// to the Remix handler so the loader's readiness checks (DB ping,
193+
// REQUIRE_PLUGINS-gated plugin load) run in this mode too. A
194+
// static 200 here would silently mask a failed plugin load.
195+
app.get(
196+
"/healthcheck",
197+
// @ts-ignore
198+
createRequestHandler({
199+
build,
200+
mode: MODE,
201+
})
202+
);
195203
}
196204

197205
const server = app.listen(port, () => {

0 commit comments

Comments
 (0)