feat: add API key authentication to REST API (#507)#508
Merged
Conversation
Require Bearer token auth on all API endpoints except /api/health. On startup the key is read from KUBEFWD_API_KEY env var; if unset a random 32-char hex key is generated and the last 4 chars are printed to the console. Token comparison uses crypto/subtle.ConstantTimeCompare to prevent timing side-channel attacks. MCP HTTP client and `kubefwd mcp --api-key` flag updated to propagate the key automatically.
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #508 +/- ##
==========================================
- Coverage 81.14% 81.07% -0.07%
==========================================
Files 71 71
Lines 12779 12843 +64
==========================================
+ Hits 10370 10413 +43
- Misses 2005 2018 +13
- Partials 404 412 +8
🚀 New features to boost your workflow:
|
The last-4-chars log was flagged by CodeQL go/clear-text-logging yet was useless for authenticating. Print the full key instead so users can copy it into API/MCP clients (localhost-only dev tool, same security context as the launching user), and annotate the line with an lgtm suppression plus justification.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds Bearer-token authentication to the kubefwd REST API. Previously the API (
pkg/fwdapi) served every endpoint — including Kubernetes context enumeration, pod log reads, and port-forward creation — with no authentication. Since kubefwd runs as root viasudo -E, any local process could drive it against the victim's kubeconfig.This PR closes #507 and addresses the concern raised in advisory GHSA-vwjh-p4vp-9rp2.
How it works
KUBEFWD_API_KEYenvironment variable. If unset, a random 32-character hex key is generated./api/health(kept open for liveness probes).Authorization: Bearer <key>header. Missing or invalid keys get401 Unauthorized.crypto/subtle.ConstantTimeCompareto avoid timing side channels.Deterministic keys for automation
Setting
KUBEFWD_API_KEYlets automation/CI use a fixed, known key instead of scraping a generated one from logs:export KUBEFWD_API_KEY=my-known-key sudo -E kubefwd --apiMCP bridge
The
kubefwd mcpHTTP client now readsKUBEFWD_API_KEYautomatically and sends the Bearer header on every request. A new--api-keyflag overrides the env var:Changes
pkg/fwdapi/middleware/middleware.goAPIKeyAuthmiddleware (constant-time compare, 401 on failure)pkg/fwdapi/server.go/api/healthstays public; all other routes go through authpkg/fwdapi/manager.goresolveAPIKey()(env or random),APIKey()accessor, masked startup logpkg/fwdmcp/httpclient.goHTTPClientcarries an API key; all verbs send the Bearer headercmd/kubefwd/mcp/mcp.go--api-keyflag (overridesKUBEFWD_API_KEY)Test plan
make verifypasses (lint, race tests, build, SHA-pin validation)APIKeyAuth: valid key, no header, wrong key, missingBearerprefix, empty bearerresolveAPIKey: from env var, generated, length/uniquenessmiddlewarepackage retains 100% coveragesudo -E kubefwd --api, confirm 401 without key and 200 with keykubefwd mcpagainst an authenticated APINotes / follow-ups
/docs) still describes the API as unauthenticated; updating it can follow in a separate docs pass./api/healthis unauthenticated — it will connect but tool calls 401. Recommend settingKUBEFWD_API_KEYwhen using the MCP bridge. A fail-fast probe is a possible follow-up.