Summary
Starting the WhatCode CLI with a non-empty WHATCODE_PASSWORD still allows unauthenticated requests to WhatCode-owned routes. Both /project and /whatcode/identity return HTTP 200 without an Authorization header.
Environment
@whatcode-ai/whatcode@1.19.0
@whatcode-ai/sdk@1.19.0 (CLI dependency)
- Node.js
v24.14.1
- Windows 11 Pro, build 26200
- Tailscale mode enabled; behavior reproduces on loopback and through Tailscale Serve
Reproduction
-
Set a non-empty password without printing it:
$env:WHATCODE_PASSWORD = '<non-empty password>'
whatcode --tailscale --port 8192 --opencode-port 4096
-
Make requests with no authorization header:
curl.exe -o NUL -s -w '%{http_code}' http://127.0.0.1:8192/whatcode/identity
curl.exe -o NUL -s -w '%{http_code}' http://127.0.0.1:8192/project
-
Both requests return 200.
The OpenCode backend started with the same password correctly returns 401 for an unauthenticated request to http://127.0.0.1:4096/global/health, confirming the password is non-empty and available during startup.
Expected behavior
When WHATCODE_PASSWORD is set, every WhatCode endpoint should require valid HTTP Basic authentication as documented and return 401 otherwise.
Suspected area
In @whatcode-ai/sdk/dist/server.js, the password middleware is registered with:
.use(password ? opencodeBasicAuth(password) : new Elysia())
The password is passed through by the CLI, but the onBeforeHandle hook from that plugin does not appear to apply to the routes subsequently registered on the parent Elysia app. This may be a plugin scoping/lifecycle issue.
Security impact
WhatCode listens on all interfaces by default. On systems where the firewall permits the Node process, unauthenticated local-network or tailnet clients can access at least machine identity and project metadata despite password protection being configured.
Summary
Starting the WhatCode CLI with a non-empty
WHATCODE_PASSWORDstill allows unauthenticated requests to WhatCode-owned routes. Both/projectand/whatcode/identityreturn HTTP 200 without anAuthorizationheader.Environment
@whatcode-ai/whatcode@1.19.0@whatcode-ai/sdk@1.19.0(CLI dependency)v24.14.1Reproduction
Set a non-empty password without printing it:
Make requests with no authorization header:
Both requests return
200.The OpenCode backend started with the same password correctly returns
401for an unauthenticated request tohttp://127.0.0.1:4096/global/health, confirming the password is non-empty and available during startup.Expected behavior
When
WHATCODE_PASSWORDis set, every WhatCode endpoint should require valid HTTP Basic authentication as documented and return401otherwise.Suspected area
In
@whatcode-ai/sdk/dist/server.js, the password middleware is registered with:The password is passed through by the CLI, but the
onBeforeHandlehook from that plugin does not appear to apply to the routes subsequently registered on the parent Elysia app. This may be a plugin scoping/lifecycle issue.Security impact
WhatCode listens on all interfaces by default. On systems where the firewall permits the Node process, unauthenticated local-network or tailnet clients can access at least machine identity and project metadata despite password protection being configured.