Skip to content

security(client): redact credentials in --debug output (SEC-07)#27

Merged
vks-team merged 1 commit into
mainfrom
security/sec-07-redact-debug
Jul 3, 2026
Merged

security(client): redact credentials in --debug output (SEC-07)#27
vks-team merged 1 commit into
mainfrom
security/sec-07-redact-debug

Conversation

@vks-team

@vks-team vks-team commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

Finding (SEC-07, the --debug leak vector)

--debug printed the raw request/response body (client.go). So grn vks update-kubeconfig --debug — which GETs the cluster kubeconfig — logged the embedded client cert/key/token (a long-lived credential; default --expiration-days 30) to stderr, landing in scrollback / CI logs.

Verified: --debug does NOT print the Authorization header (bearer token safe there), but it DID print the full response body, which for kubeconfig contains the credential.

Fix

redactDebugBody parses the JSON body and replaces credential-bearing field values with [REDACTED] in the debug view only — the real response used by the command is untouched. Applied to both the request-body and response-body debug prints.

Redacted keys: kubeConfig, token, client-certificate-data, client-key-data, client_secret/clientSecret, password, plus any key containing secret/password or ending in token/key-data. Non-JSON bodies pass through unchanged (VKS/vServer bodies are JSON).

Example (update-kubeconfig --debug) now logs:

[debug] response 200: {"kubeConfig":"[REDACTED]","renewalWarning":false,"status":"ACTIVE"}

Out of scope (server-side)

The deeper issue — VKS embeds a static N-day credential in the kubeconfig, whereas EKS/GKE use an exec-plugin that mints short-lived (~15 min / ~1 h) tokens on demand and stores nothing on disk. The VKS API exposes only GET/POST /kubeconfig (no short-lived token endpoint), so the exec-plugin model can't be done in the CLI alone — it needs a VKS control-plane capability. This PR closes the --debug leak; the model change is a backend proposal.

Testing

  • redact_test.go: kubeconfig masked, nested/token/clientSecret masked, non-sensitive kept, non-JSON passthrough.
  • go vet ./... clean; full go test ./... passes; build clean.

🤖 Generated with Claude Code

--debug printed the raw request/response body, so fetching a kubeconfig with
--debug logged the embedded client cert/key/token (a long-lived credential) to
stderr, into scrollback/CI logs. Redact credential-bearing fields (kubeConfig,
token, client-certificate-data, client-key-data, *secret*, password) to
"[REDACTED]" in the debug view only; the real response is untouched. Applied to
both request and response debug logging.

Note: this closes the --debug leak vector. The underlying model (VKS embeds a
static N-day credential in the kubeconfig, vs EKS/GKE exec-plugin short-lived
tokens) is server-side and out of scope.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@vks-team vks-team merged commit b44bf42 into main Jul 3, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant