feat: add Rancher/Cattle token detector#4793
feat: add Rancher/Cattle token detector#4793yunior123 wants to merge 4 commits intotrufflesecurity:mainfrom
Conversation
Adds detection for Rancher API tokens (CATTLE_TOKEN, RANCHER_TOKEN, etc.) with context-aware matching to reduce false positives. No verification since the Rancher server URL cannot be determined from the token alone. Closes trufflesecurity#4622 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
This PR adds a new TruffleHog detector for Rancher/Cattle API tokens (used with the Rancher Kubernetes management platform). The detector uses context-aware regex matching anchored to known Rancher env variable names, without verification (since the Rancher server URL cannot be derived from the token alone). It also registers the new detector in the engine's default list and adds the RancherToken type to the protobuf enum.
Changes:
- Adds new
ranchertokendetector package with regex pattern and unit tests - Registers the
RancherToken = 1043enum value inproto/detectors.proto - Wires the new scanner into
pkg/engine/defaults/defaults.go
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
pkg/detectors/ranchertoken/ranchertoken.go |
Core detector logic with context-aware regex and FromData implementation |
pkg/detectors/ranchertoken/ranchertoken_test.go |
Unit tests covering 6 pattern match scenarios |
proto/detectors.proto |
Adds RancherToken = 1043 to the DetectorType enum |
pkg/engine/defaults/defaults.go |
Imports and registers the new scanner in the default detector list |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| - name: RANCHER_TOKEN | ||
| value: "abc123def456ghi789jkl012mno345pqr678stu901vwx234yz567a" | ||
| `, | ||
| want: []string{"abc123def456ghi789jkl012mno345pqr678stu901vwx234yz567a"}, |
There was a problem hiding this comment.
The "valid pattern - yaml config" test case expects to find a token but the regex cannot match this input format. In the Kubernetes YAML env var format, RANCHER_TOKEN is the value of the name: key, and the actual token appears on the next line under the value: key. The regex RANCHER_TOKEN[\w]*\s*[=:]\s* requires RANCHER_TOKEN to be immediately followed (with optional whitespace) by = or :. In this YAML, after RANCHER_TOKEN there is a newline then value: "..." — the \s* consumes \n but then [=:] faces v from value, causing the match to fail. The want for this test case should be nil unless the regex is updated to support this YAML format.
| want: []string{"abc123def456ghi789jkl012mno345pqr678stu901vwx234yz567a"}, | |
| want: nil, |
| resMatch := strings.TrimSpace(match[1]) | ||
|
|
||
| s1 := detectors.Result{ | ||
| DetectorType: detectorspb.DetectorType_RancherToken, |
There was a problem hiding this comment.
The pkg/pb/detectorspb/detectors.pb.go file has not been regenerated after adding RancherToken = 1043 to proto/detectors.proto. As a result, detectorspb.DetectorType_RancherToken does not exist in the compiled Go package, and any build that includes the ranchertoken package will fail to compile with an "undefined: detectorspb.DetectorType_RancherToken" error. The PR description notes maintainers need to run make protos, but this must be done before the PR can be merged — the generated file must be committed alongside the .proto change.
| _ detectors.Detector = (*Scanner)(nil) | ||
|
|
||
| // Token pattern: 54-64 char lowercase alphanumeric, only when near context keywords. | ||
| tokenPat = regexp.MustCompile(`(?:CATTLE_TOKEN|RANCHER_TOKEN|CATTLE_BOOTSTRAP_PASSWORD|RANCHER_API_TOKEN|RANCHER_SECRET_KEY)[\w]*\s*[=:]\s*["']?([a-z0-9]{54,64})["']?`) |
There was a problem hiding this comment.
The regex in tokenPat only matches uppercase keyword names (e.g., CATTLE_TOKEN, RANCHER_TOKEN), but the Keywords() method returns lowercase strings. The aho-corasick pre-filter is case-insensitive (it lowercases both keywords and input), so it will trigger on both CATTLE_TOKEN=... and cattle_token=... in source data. However, when FromData is then called, the regex without (?i) will only match the uppercase form and silently miss lowercase occurrences like cattle_token=<value>, which are common in .env files and shell scripts. Adding (?i) at the start of the regex would fix this.
| tokenPat = regexp.MustCompile(`(?:CATTLE_TOKEN|RANCHER_TOKEN|CATTLE_BOOTSTRAP_PASSWORD|RANCHER_API_TOKEN|RANCHER_SECRET_KEY)[\w]*\s*[=:]\s*["']?([a-z0-9]{54,64})["']?`) | |
| tokenPat = regexp.MustCompile(`(?i)(?:CATTLE_TOKEN|RANCHER_TOKEN|CATTLE_BOOTSTRAP_PASSWORD|RANCHER_API_TOKEN|RANCHER_SECRET_KEY)[\w]*\s*[=:]\s*["']?([a-z0-9]{54,64})["']?`) |
- Add (?i) to regex so lowercase cattle_token/rancher_token in .env files and shell scripts are matched (Copilot review) - Replace Kubernetes YAML test with docker env format — the multiline name:/value: pattern can't match with a single-line regex (Cursor review) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
|
Addressed Cursor + Copilot review in 54664ca:
|
(?i) was making [a-z0-9] match uppercase letters, widening the token capture beyond the documented lowercase-only format. Now lists both CATTLE_TOKEN and cattle_token explicitly instead. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Addresses Cursor Bugbot feedback: replaces verbose dual-case keyword listing with scoped (?i:...) group. This catches mixed-case variants like Cattle_Token and Rancher_Api_Token while keeping the token capture group [a-z0-9] case-sensitive (lowercase-only format). Verified with standalone Go test: 10/10 cases pass. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Summary
Details
(?:CATTLE_TOKEN|RANCHER_TOKEN|CATTLE_BOOTSTRAP_PASSWORD|RANCHER_API_TOKEN|RANCHER_SECRET_KEY)[\w]*\s*[=:]\s*["']?([a-z0-9]{54,64})["']?cattle_token,rancher_token,cattle_bootstrap_password,rancher_api_token,rancher_secret_keyRancherToken = 1043(maintainers: please runmake protos)Test plan
make protosto regenerate pb.goCloses #4622
🤖 Generated with Claude Code
Note
Medium Risk
Medium risk due to updating the protobuf
DetectorTypeenum and adding a new default detector, which can change scan output/performance and requires regeneratingpkg/pb/detectorspb/detectors.pb.goto avoid build breaks.Overview
Adds a new
ranchertokendetector that flags 54–64 character lowercase alphanumeric tokens only when they appear alongside Rancher/Cattle context keys (e.g.,CATTLE_TOKEN,RANCHER_TOKEN), and includes unit tests covering positive/negative patterns.Registers the detector in
pkg/engine/defaults/defaults.goso it runs by default, and extendsproto/detectors.protowith the newRancherToken = 1043detector type (note: generated Go protobuf needs regeneration).Written by Cursor Bugbot for commit 1578ea3. This will update automatically on new commits. Configure here.