-
Notifications
You must be signed in to change notification settings - Fork 594
feat(loki.secretfilter): Add sampling for secretfilter entries #5663
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
9 commits
Select commit
Hold shift + click to select a range
5f730e1
Refactor tests to avoid issues with global variables in gitleaks
mikefat a5758e0
Add sampling for secretfilter entries
mikefat 33753ed
Update docs with secretfilter rate argument
mikefat 6247df3
Satisfy golangci-lint
mikefat ab72d20
Clean up comments
mikefat 9312ecb
Correct sampled vs unsampled usage
mikefat 0ab3b61
Merge branch 'main' into mgordo/273
mikefat 2e43e76
Make exported error string inline instead
mikefat 7f8c68f
Apply docs rewording suggestions
mikefat File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
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
48 changes: 48 additions & 0 deletions
48
internal/component/loki/secretfilter/extend/extend_test.go
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,48 @@ | ||
| package extend | ||
|
|
||
| import ( | ||
| "fmt" | ||
| "os" | ||
| "path/filepath" | ||
| "runtime" | ||
| "testing" | ||
|
|
||
| "github.com/grafana/alloy/internal/component/loki/secretfilter" | ||
| ) | ||
|
|
||
| // This test file is used to test the secretfilter component with a custom gitleaks config file. | ||
| // The reason why these tests are in a separate package is that the gitleaks library uses global variables | ||
| // when loading configs with [extend] useDefault = true. If we ran these | ||
| // tests in the same package as the main secretfilter tests, the extend logic does not work correctly. | ||
| // putting the extend tests in a separate package, "go test ./..." runs them in a | ||
| // different process, so they get a clean viper and gitleaks global state. | ||
|
|
||
| // gitleaksConfigPath returns the path to gitleaks.toml in the extend package directory. | ||
| func gitleaksConfigPath(t *testing.T) string { | ||
| t.Helper() | ||
| _, filename, _, _ := runtime.Caller(0) | ||
| dir := filepath.Dir(filename) | ||
| return filepath.Join(dir, "gitleaks.toml") | ||
| } | ||
|
|
||
| func TestSecretFiltering_WithGitleaksConfigFile(t *testing.T) { | ||
| configPath := gitleaksConfigPath(t) | ||
| if _, err := os.Stat(configPath); err != nil { | ||
| t.Skipf("gitleaks.toml not found at %s: %v", configPath, err) | ||
| } | ||
|
|
||
| config := fmt.Sprintf(` | ||
| forward_to = [] | ||
| gitleaks_config = %q | ||
| `, configPath) | ||
|
|
||
| // Same cases as default, plus the UUID allowlist case (generic-api-key when secret is a UUID). | ||
| cases := secretfilter.DefaultTestCases() | ||
| cases = append(cases, secretfilter.TestCase{ | ||
| Name: "generic_api_key_uuid_allowlisted", | ||
| InputLog: `{"message": "audit tokenID=550e8400-e29b-41d4-a716-446655440000 resourceID=6ba7b810-9dad-11d1-80b4-00c04fd430c8"}`, | ||
| ShouldRedact: false, | ||
| }) | ||
|
|
||
| secretfilter.RunTestCases(t, config, cases) | ||
| } |
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,14 @@ | ||
| title = "gitleakstests extended config" | ||
|
|
||
| [extend] | ||
| useDefault = true | ||
|
|
||
| # allowlist by secret – ignore when the “secret” is a UUID. | ||
| [[rules]] | ||
| id = "generic-api-key" | ||
| [[rules.allowlists]] | ||
| description = "ignore when extracted secret is a UUID" | ||
| regexTarget = "secret" | ||
| regexes = [ | ||
| '''^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$''', | ||
| ] |
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,68 @@ | ||
| // run_test_cases.go provides RunTestCases for use by secretfilter tests and the | ||
| // extend package. It lives in the secretfilter package so it can use | ||
| // secretfilter.Arguments/Exports and avoids testhelper importing secretfilter. | ||
|
|
||
| package secretfilter | ||
|
|
||
| import ( | ||
| "context" | ||
| "testing" | ||
| "time" | ||
|
|
||
| "github.com/grafana/alloy/internal/component" | ||
| "github.com/grafana/alloy/internal/component/common/loki" | ||
| "github.com/grafana/alloy/internal/component/loki/secretfilter/testhelper" | ||
| "github.com/grafana/alloy/internal/util" | ||
| "github.com/grafana/alloy/syntax" | ||
| "github.com/grafana/loki/pkg/push" | ||
| "github.com/prometheus/client_golang/prometheus" | ||
| "github.com/prometheus/common/model" | ||
| "github.com/stretchr/testify/require" | ||
| ) | ||
|
|
||
| // TestCase is a single test case for RunTestCases (name, log line, expected redaction). | ||
| type TestCase struct { | ||
| Name string | ||
| InputLog string | ||
| ShouldRedact bool | ||
| } | ||
|
|
||
| // RunTestCases runs all cases through a single component (one config load). | ||
| // It builds the component once and calls processEntry for each case. | ||
| func RunTestCases(t *testing.T, config string, cases []TestCase) { | ||
| t.Helper() | ||
| var args Arguments | ||
| require.NoError(t, syntax.Unmarshal([]byte(config), &args)) | ||
| args.ForwardTo = []loki.LogsReceiver{loki.NewLogsReceiver()} | ||
|
|
||
| opts := component.Options{ | ||
| Logger: util.TestLogger(t), | ||
| OnStateChange: func(component.Exports) {}, | ||
| GetServiceData: testhelper.GetServiceData, | ||
| Registerer: prometheus.NewRegistry(), | ||
| } | ||
| c, err := New(opts, args) | ||
| require.NoError(t, err) | ||
|
|
||
| for _, tc := range cases { | ||
| t.Run(tc.Name, func(t *testing.T) { | ||
| require.NotEmpty(t, tc.InputLog) | ||
| entry := loki.Entry{Labels: model.LabelSet{}, Entry: push.Entry{Timestamp: time.Now(), Line: tc.InputLog}} | ||
| got, _ := c.processEntry(context.Background(), entry) | ||
| if tc.ShouldRedact { | ||
| require.NotEqual(t, tc.InputLog, got.Line, "Expected log to be redacted but it was not") | ||
| } else { | ||
| require.Equal(t, tc.InputLog, got.Line, "Expected log to remain unchanged but it was modified") | ||
| } | ||
| }) | ||
| } | ||
| } | ||
|
|
||
| // DefaultTestCases returns the standard 7 cases from testhelper as []TestCase. | ||
| func DefaultTestCases() []TestCase { | ||
| out := make([]TestCase, 0, len(testhelper.DefaultCases)) | ||
| for _, c := range testhelper.DefaultCases { | ||
| out = append(out, TestCase{Name: c.Name, InputLog: c.InputLog, ShouldRedact: c.ShouldRedact}) | ||
| } | ||
| return out | ||
| } | ||
Oops, something went wrong.
Oops, something went wrong.
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.
Uh oh!
There was an error while loading. Please reload this page.