Skip to content

fix: More consistent protected env vars#3838

Merged
DrJosh9000 merged 1 commit intomainfrom
a-991-env-var-protection-clarity
Apr 22, 2026
Merged

fix: More consistent protected env vars#3838
DrJosh9000 merged 1 commit intomainfrom
a-991-env-var-protection-clarity

Conversation

@DrJosh9000
Copy link
Copy Markdown
Contributor

Description

Make the whole situation with env var protection clearer.

  • Apply normalisation when checking protection
  • Allow some env vars that are mutable from hooks and plugins to be modifiable from the Job API
  • Prevent mutating some env vars via hook wrapper

Context

https://linear.app/buildkite/issue/A-991, and others

Testing

  • Tests have run locally (with go test ./...). Buildkite employees may check this if the pipeline has run automatically.
  • Code is formatted (with go tool gofumpt -extra -w .)

Disclosures / Credits

The wet noodles of brain tissue curling around inside my skull

@DrJosh9000 DrJosh9000 requested review from a team as code owners April 20, 2026 07:52
@DrJosh9000 DrJosh9000 force-pushed the a-991-env-var-protection-clarity branch from 1dc7cce to bb51053 Compare April 21, 2026 00:47
Copy link
Copy Markdown
Contributor

@zhming0 zhming0 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks mostly good, I can see the rationale. I mainly have questions to prevent me misunderstanding this

Comment thread env/environment.go Outdated
Comment on lines +392 to +396
"BUILDKITE_GIT_CHECKOUT_FLAGS": {allowWriteFromJob: true},
"BUILDKITE_GIT_CLEAN_FLAGS": {allowWriteFromJob: true},
"BUILDKITE_GIT_CLONE_FLAGS": {allowWriteFromJob: true},
"BUILDKITE_GIT_CLONE_MIRROR_FLAGS": {allowWriteFromJob: true},
"BUILDKITE_GIT_FETCH_FLAGS": {allowWriteFromJob: true},
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this change a feature? it feels like a big expansion to plugin capabilities.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ah then is this change re envs that are created as part of Pipeline yaml??

Copy link
Copy Markdown
Contributor Author

@DrJosh9000 DrJosh9000 Apr 21, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All these env vars are ignored from the pipeline YAML or build creation dialog - that was already the case. The change here is to make it clearer that some of them can be set from plugins, hooks, or the command.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All these env vars are ignored from the pipeline YAML or build creation dialog

TIL! I thought I got it working via Pipeline yaml before.

I have doubt but all good for now 👍🏿

Comment thread env/environment.go Outdated
Comment on lines +370 to +371
// These variables cannot be overwritten by job-level environment variables or
// secrets, but some may still be set in hooks or plugins.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just for my understanding, why would we disallow an env to be mutated by job env var but instead allow it to be mutated by hook and plugin?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Might it be something worth writing down as well?

Copy link
Copy Markdown
Contributor Author

@DrJosh9000 DrJosh9000 Apr 21, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good question. The main question I ask is: if someone has rights to start a build and provide env vars, could an env var they set be able to bypass other restrictions like no-command-eval? And would the env var be a reasonable way for a plugin to set config. Git flags are an example. There are some shell injections possible via Git flag, so they should be rejected from the build creation dialog, but plugins should be able to adjust Git flags prior to checkout. (Plugins can also implement the checkout hook, bypassing the default checkout process entirely.)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've written some of this into the comment.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Interesting, I thought someone who has rights to start a build are often the one that has code commit permission, so this permission mechanism seems quite narrow.

But thanks for clarifying it!

Comment thread env/environment.go Outdated
Comment thread jobapi/env.go
Comment on lines +144 to +146
// The Job API is only accessible from within the job, so allow writes
// to vars that allow write from within job.
if env.IsProtectedFromWithinJob(c) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this change "Prevent mutating some env vars via hook wrapper"?

If I am not mistaken, we didn't add any new protected env var in this PR?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The lines where you've commented, the change is to allow more env vars to be changed via the Job API. Previously, the git flags vars would have been rejected here, even though they can be set via the hook wrapper.

The hook wrapper and Job API should have consistent logic, since they're both doing the same thing (allowing a script or command to change env vars), so the same check is now added to the hook wrapper.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍🏿 yeah, my question was mainly about where is the code change for this item in PR description?

Prevent mutating some env vars via hook wrapper

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The change in executor.go (

// Prevent any changes to vars that are protected even within the job.
// This is a courtesy to hook/plugin authors that write a hook that mutates
// an env var only to find out that the change has no effect, or perhaps
// breaks the rest of the job.
var protected []string
for k := range changes.Diff.Keys {
if env.IsProtectedFromWithinJob(k) {
protected = append(protected, k)
changes.Diff.Remove(k)
}
}
if len(protected) > 0 {
e.shell.Commentf("Changes to some env vars were blocked; the affected vars are: %v", protected)
}
)

@DrJosh9000 DrJosh9000 force-pushed the a-991-env-var-protection-clarity branch 2 times, most recently from 902fef3 to 0aef51d Compare April 21, 2026 07:09
Copy link
Copy Markdown
Contributor

@zhming0 zhming0 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM though I think it might be worth to re-clarify some names.

Comment thread env/environment.go Outdated
Comment on lines +413 to +417
"BUILDKITE_GIT_CHECKOUT_FLAGS": {allowWriteFromJob: true},
"BUILDKITE_GIT_CLEAN_FLAGS": {allowWriteFromJob: true},
"BUILDKITE_GIT_CLONE_FLAGS": {allowWriteFromJob: true},
"BUILDKITE_GIT_CLONE_MIRROR_FLAGS": {allowWriteFromJob: true},
"BUILDKITE_GIT_FETCH_FLAGS": {allowWriteFromJob: true},
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Without reading more context, the allowWriteFromJob seems to be saying allow Job environment to modify these env vars.

But the comments above say:

But we don't want the job environment to be able to set them, because git is riddled with shell injections

Comment thread env/environment.go Outdated
Comment on lines +392 to +396
"BUILDKITE_GIT_CHECKOUT_FLAGS": {allowWriteFromJob: true},
"BUILDKITE_GIT_CLEAN_FLAGS": {allowWriteFromJob: true},
"BUILDKITE_GIT_CLONE_FLAGS": {allowWriteFromJob: true},
"BUILDKITE_GIT_CLONE_MIRROR_FLAGS": {allowWriteFromJob: true},
"BUILDKITE_GIT_FETCH_FLAGS": {allowWriteFromJob: true},
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All these env vars are ignored from the pipeline YAML or build creation dialog

TIL! I thought I got it working via Pipeline yaml before.

I have doubt but all good for now 👍🏿

Comment thread jobapi/env.go
Comment on lines +144 to +146
// The Job API is only accessible from within the job, so allow writes
// to vars that allow write from within job.
if env.IsProtectedFromWithinJob(c) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍🏿 yeah, my question was mainly about where is the code change for this item in PR description?

Prevent mutating some env vars via hook wrapper

@DrJosh9000 DrJosh9000 force-pushed the a-991-env-var-protection-clarity branch 6 times, most recently from 5979d5a to 089b97a Compare April 22, 2026 01:52
Comment thread process/BUILD.bazel
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

bazel run :gazelle generated this

@DrJosh9000 DrJosh9000 force-pushed the a-991-env-var-protection-clarity branch from 089b97a to eee7173 Compare April 22, 2026 01:53
@DrJosh9000 DrJosh9000 merged commit ea88191 into main Apr 22, 2026
3 checks passed
@DrJosh9000 DrJosh9000 deleted the a-991-env-var-protection-clarity branch April 22, 2026 02:09
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.

2 participants