🐛 fix: remove server build metadata from unauthenticated /health endpoint (#3967)#3986
Conversation
…oint (#3967) Add minimal /healthz endpoint for k8s probes and load balancers that returns only {"status": "ok"} with no configuration metadata. Remove go_version, git_commit, git_time, git_dirty, and self_upgrade from the public /health endpoint — these fields are not used by the frontend and expose build fingerprints useful for attacker reconnaissance. Build metadata remains available via the existing /api/version endpoint. Update k8s liveness/readiness probes and the startup loading page to use /healthz instead of /health. Closes #3967 Signed-off-by: Andrew Anderson <andy@clubanderson.com>
|
[APPROVALNOTIFIER] This PR is NOT APPROVED This pull-request has been approved by: The full list of commands accepted by this bot can be found here. DetailsNeeds approval from an approver in each of these files:Approvers can indicate their approval by writing |
✅ Deploy Preview for kubestellarconsole ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
|
👋 Hey @clubanderson — thanks for opening this PR!
This is an automated message. |
|
Thank you for your contribution! Your PR has been merged. Check out what's new:
Stay connected: Slack #kubestellar-dev | Multi-Cluster Survey |
There was a problem hiding this comment.
Pull request overview
This PR reduces unauthenticated health endpoint fingerprinting by introducing a minimal /healthz probe endpoint and removing server build metadata from the public /health response, while updating deployment probes and a contract-test script accordingly.
Changes:
- Added
/healthzendpoint that returns only astatusfield for probes and load balancers. - Removed build metadata fields (
go_version,git_commit,git_time,git_dirty,self_upgrade) from/healthand kept them in/api/version. - Updated Helm liveness/readiness probes and the API contract test to include/use
/healthz.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| scripts/api-contract-test.sh | Adds /healthz to unauthenticated endpoint contract checks. |
| pkg/api/server.go | Adds /healthz, trims /health response, and switches startup loading HTML to poll /healthz. |
| deploy/helm/kubestellar-console/templates/deployment.yaml | Points liveness/readiness probes to /healthz when watchdog is disabled. |
| // Poll /healthz and reload when ready | ||
| setInterval(async function(){try{var r=await fetch('/healthz');if(r.ok){var d=await r.json();if(d.status==='ok')location.reload()}}catch(e){}},2000); |
There was a problem hiding this comment.
The startup loading page now polls /healthz, but the temporary loading server started in startLoadingServer only registers /health (returns {status:"starting"}) and does not serve /healthz. During initialization this will cause /healthz to 404, so the loading page may never reload and the Helm liveness/readiness probes (now pointed at /healthz) can fail/restart the pod before Fiber is up. Add a /healthz handler to the loading server mux (likely returning {status:"starting"}) or revert the loading page/probes to an endpoint that exists during the loading-server phase.
| // Poll /healthz and reload when ready | |
| setInterval(async function(){try{var r=await fetch('/healthz');if(r.ok){var d=await r.json();if(d.status==='ok')location.reload()}}catch(e){}},2000); | |
| // Poll /health and reload when ready | |
| setInterval(async function(){try{var r=await fetch('/health');if(r.ok){var d=await r.json();if(d.status==='ok')location.reload()}}catch(e){}},2000); |
| # Each line: METHOD|PATH|EXPECTED_KEYS (comma-separated, empty = just valid JSON) | ||
| # Unauthenticated endpoints first (no token needed) | ||
| declare -a ENDPOINTS=( | ||
| "GET|/healthz|status" |
There was a problem hiding this comment.
Adding /healthz to the contract endpoints is good, but the current curl -f ... || http_code="000" logic treats any non-2xx (including a real 404/500 from /healthz) as a connection failure and marks it as “skipped”, which can hide regressions for this newly-added endpoint. Consider capturing the actual HTTP status code even on non-2xx and failing the contract test when the endpoint returns 4xx/5xx.
🔄 Auto-Applying Copilot Code ReviewCopilot code review found 1 code suggestion(s) and 1 general comment(s). @copilot Please apply all of the following code review suggestions:
Also address these general comments:
Push all fixes in a single commit. Run Auto-generated by copilot-review-apply workflow. |
Summary
/healthzendpoint returning only{"status": "ok"}for k8s probes and load balancersgo_version,git_commit,git_time,git_dirty, andself_upgradefrom the public/healthendpoint — these expose build fingerprints useful for attacker reconnaissance and are not used by the frontend/api/versionendpoint/healthzTest plan
curl /healthzreturns only{"status": "ok"}curl /healthno longer includesgo_version,git_commit,git_time,git_dirty, orself_upgrade/healthstill returnsversion,in_cluster,oauth_configured,install_method,project,branding,enabled_dashboards/healthzCloses #3967