Skip to content

feat: pass tunnel token via Kubernetes Secret instead of command args#270

Open
STRRL wants to merge 3 commits intomasterfrom
STRRL/secret-tunnel-token
Open

feat: pass tunnel token via Kubernetes Secret instead of command args#270
STRRL wants to merge 3 commits intomasterfrom
STRRL/secret-tunnel-token

Conversation

@STRRL
Copy link
Copy Markdown
Owner

@STRRL STRRL commented Feb 12, 2026

Summary

  • Store the Cloudflare tunnel token in a Kubernetes Secret (controlled-cloudflared-token) instead of passing it as a --token command-line argument to cloudflared
  • Inject the token into cloudflared pods via the TUNNEL_TOKEN environment variable, which cloudflared reads natively
  • Add RBAC permissions for the controller to manage secrets in the namespace
  • The controller automatically creates and updates the secret when the token changes

This prevents the tunnel token from being easily readable in pod specs, deployment manifests, and process listings.

Closes #136

Test plan

  • Unit tests updated and passing (make unit-test)
  • Integration tests updated and passing (make integration-test) — 14/14 specs pass
  • New test case added: verifies secret is updated when token changes
  • Existing test case enhanced: verifies TUNNEL_TOKEN env var references the secret and --token is NOT in command args
  • Pre-commit hooks (gofmt, go vet, golangci-lint) all pass

Store the Cloudflare tunnel token in a Kubernetes Secret
(controlled-cloudflared-token) and inject it into cloudflared pods
via the TUNNEL_TOKEN environment variable, instead of passing it as
a --token command-line argument. This prevents the token from being
easily readable in pod specs and process listings.

Closes #136
@claude
Copy link
Copy Markdown
Contributor

claude bot commented Feb 12, 2026

Claude finished @STRRL's task —— View job


Code Review: Security Enhancement - Tunnel Token via Kubernetes Secret ✅

This PR successfully implements a significant security improvement by moving tunnel tokens from command-line arguments to Kubernetes Secrets. Here's my comprehensive review:

Excellent Security Improvements

  1. Token Protection: Tunnel tokens are no longer visible in:

    • Pod specifications
    • Process lists (ps aux)
    • Deployment manifests
    • Kubernetes resource descriptions
  2. RBAC Implementation: Proper secret permissions added to role.yaml:18-27 with minimal, scoped access (get, create, update on secrets)

  3. Environment Variable Approach: Using TUNNEL_TOKEN env var that cloudflared natively supports is the right approach

Code Quality & Best Practices

Well-Structured Implementation:

  • Clean separation of concerns with createOrUpdateTunnelTokenSecret() function
  • Proper error handling with descriptive error wrapping
  • Good use of constants for secret name/key (tunnelTokenSecretName, tunnelTokenSecretKey)

Robust Update Logic:

  • Smart token comparison at controlled-cloudflared-connector.go:143-145 prevents unnecessary updates
  • Uses StringData for cleaner secret creation
  • Proper Kubernetes resource labeling for management

Excellent Test Coverage

Comprehensive Integration Tests:

  • Verifies secret creation and content
  • Confirms TUNNEL_TOKEN env var setup with correct secret reference
  • Validates absence of --token in command args (controlled_cloudflared_connector_test.go:95-97)
  • Tests token update scenarios when tunnel token changes
  • Good use of mock tunnel client for isolated testing

Good Unit Test Coverage:

  • Tests command building logic thoroughly
  • Includes edge cases (nil args, empty args, multiple args)

⚠️ Minor Considerations

  1. Secret Cleanup: The implementation doesn't handle cleanup of secrets when deployments are removed. Consider adding finalizers or owner references for automatic cleanup.

  2. Secret Update Race Condition: At controlled-cloudflared-connector.go:147, updating StringData on existing secret could potentially race with other operations. Using Data field with base64 encoding might be more atomic.

  3. Error Context: The error at line 34 could include the namespace for better debugging: "create or update tunnel token secret in namespace %s", namespace

Performance Considerations

  • Minimal performance impact
  • Secret operations are efficient
  • No unnecessary API calls due to token comparison logic

Security Assessment

  • High Impact Improvement: Removes sensitive data from easily accessible locations
  • No New Vulnerabilities: Implementation follows Kubernetes security best practices
  • Proper RBAC: Minimal necessary permissions granted

Overall Assessment

This is a high-quality security enhancement that addresses issue #136 effectively. The implementation is clean, well-tested, and follows Kubernetes best practices. The minor considerations above are not blocking issues but could be addressed in future iterations.

Recommendation: ✅ APPROVE - This PR significantly improves security with solid implementation quality.


@codecov
Copy link
Copy Markdown

codecov bot commented Feb 12, 2026

Codecov Report

❌ Patch coverage is 83.33333% with 10 lines in your changes missing coverage. Please review.
✅ Project coverage is 49.53%. Comparing base (908b5e5) to head (a567cd4).

Files with missing lines Patch % Lines
pkg/controller/controlled-cloudflared-connector.go 83.33% 5 Missing and 5 partials ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master     #270      +/-   ##
==========================================
+ Coverage   47.08%   49.53%   +2.44%     
==========================================
  Files          11       11              
  Lines         703      749      +46     
==========================================
+ Hits          331      371      +40     
- Misses        349      352       +3     
- Partials       23       26       +3     
Flag Coverage Δ
integration 28.87% <83.33%> (+3.80%) ⬆️
unit 23.96% <3.33%> (-1.64%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Collect pod logs, describe output, events, secrets, and deployment
status from the controller namespace after e2e tests run (pass or
fail). Files are saved under test/e2e/artifacts/logs/ and uploaded
as part of the existing artifact step.
The RoleBinding for controlled-cloudflared-connector was referencing
kind: ClusterRole, but the resource is a Role. This caused the
secrets permissions (needed for the tunnel token secret) to never
be applied, preventing the controller from creating the secret and
thus the cloudflared deployment.
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.

Feature request: Pass tunnel token to cloudflared using secret

1 participant