-
Notifications
You must be signed in to change notification settings - Fork 18
Fix condition for secrets eligibility to be redacted + Add related unit tests #146
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
base: main
Are you sure you want to change the base?
Conversation
So we can mock the `buildkite-agent` interactions more easily in tests
- `Agent` types inside their own modules are ok as they're already disambiguated by `sshagent.Agent` vs `buildkiteagent.Agent`. So this renames `type BuildkiteAgent struct` to `type Agent struct` in the `buildkiteagent` package. - But the `interface` types in `secrets.go` both live in the `secrets` module and benefit from having a differentiating name in that file, i.e. `type SSHAgent interface` vs `type BuildkiteAgent interface`. So this also renames the `Agent interface` interface to `SSHAgent interface` - Similarly in `secrets_test.go`, `fakeAgent` variables and `FakeAgent struct` stub have been renamed `fakeSSHAgent` and `FakeSSHAgent struct` respectively
|
cc @DrJosh9000 not sure you saw that PR (and I don't have permissions to add reviewers to the PR) 🙂 |
|
Thanks @AliSoftware , I did see this and I do mean to get back to this soon! |
|
Hey @AliSoftware, thanks again for working on this PR. On reflection, I think the right approach is along the lines of your comment here, where the agent command can optionally apply the name and length-based filtering using keys in the JSON object. s3-secrets-hooks will still need updating both to pass the new flag and to perform the filtering itself when the flag is not available. There's a lot happening in this PR, especially considering the size and scope of the bugs that are being fixed. I can see why you might want to introduce an interface and test double for Buildkite Agent (for tests), but I think this offers no meaningful improvement in fidelity. These new tests are testing that the methods of an interface are called. For better fidelity, you want to test that |
|
Hi @DrJosh9000 thanks for the review.
That was actually my first implementation (up to this commit) but:
Yeah, I can agree to that. If you want, we could split this in multiple PRs:
That way with the test double in (3) we'd be able to have test coverage on all use cases (binary present or not), and be able to run that test suite even on machines that don't have |
|
It's becoming apparent to me that at least a few problems I might have here are actually problems in the existing code. To take the unexported field example, there's no reason unit tests must be in a separate package to the code under test - I typically leave them in the same package. Using a separate package forces all the tests to be agnostic to internal details, but also gets in the way of adding tests that test the internal details. To take nondeterminism based on whether the agent is present or not, I can see why we (at Buildkite) might just assume the agent is present, but maybe a better solution is to structure things so the input to the agent is ready whether or not the agent is present. I may be rambling. I admit that this repo isn't my usual wheelhouse, and at the moment we've got some large reliability-shaped projects underway (such as end-to-end tests over in the agent), that have much more of my attention. So perhaps we're better off accepting this PR pretty much as-is. |
Fixes buildkite/agent#3588
Why / Context
When testing if secrets should be redacted based on their env var names, the current implementation was:
Containsinstead ofHasSuffix.This made env vars like
DISABLE_PASSWORD_PROMPTfor example be redacted despite_PASSWORDbeing in the middle of that env var name, not as a suffix. Likewise,DISABLE_PASSWORD=1made any"1"appearing in the logs be redacted as we didn't filter secrets < 6 bytes.How / The Fix
Red-Green-Refactoring approach:
secretsToRedactto highlight the 2 problems (and ensure we have failing tests in case of a regression in the future on this)strings.Contains(key, suffix)withstrings.HasSuffix(key, suffix)redactSecret(…)BuildkiteAgentinterface+type that wraps all theexec.Commandcalls tobuildkite-agentinto a dedicated type (similar toClientandAgent), so we can stub them in tests more cleanlyNotes
🤖 I used Cursor and its AI agent to help me work on this. While I proofread the code it generated, corrected it, and iterated on it until I was happy and confident the logic looked correct and made sense, I still wanted to make note of my use of AI for transparency.
🌻 Also, I have never written code in Go before (hence enrolling a bit of AI to guide me), so it's very possible that I might not have used the best patterns for some implementations
(for example I'm not sure about the use of[EDIT: Solved with a different approach since])config_test.gofile to expose the private field from thepackage secretsonly to test code… is that good Go practice?Future directions
💡 Some potential ideas for future PRs:
os.Getenv('BUILDKITE_REDACTED_VARS')and instead of using hardcodeddefaultSecretSuffixes? Which would mean update the condition logic inisSecretVaragain, this time to be able to do a fnmatch-style matching instead of usingstrings.HasSuffix.