Skip to content

Kubernetes: Support allowPrivilegeEscalation and capabilities backend_options#6307

Merged
6543 merged 1 commit into
woodpecker-ci:mainfrom
Aex12:main
Apr 28, 2026
Merged

Kubernetes: Support allowPrivilegeEscalation and capabilities backend_options#6307
6543 merged 1 commit into
woodpecker-ci:mainfrom
Aex12:main

Conversation

@Aex12

@Aex12 Aex12 commented Mar 23, 2026

Copy link
Copy Markdown
Contributor

With this PR changes, we can finally run workflows in a restricted namespace in the Kubernetes backend.

Related to #5346. I wouldn't say it closes it, but improves the situation by providing means to run in a fully unprivileged namespace.

Also, I'm not sure how should I backport this to v3.13.x, I can't find the release/v3.13 branch

@qwerty287 qwerty287 left a 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.

Thanks! Is it possible to use these options to do something dangerous that could compromise the agent? Right now I think you can use them in any pipeline. (Sorry I don't have k8s experience...)

Backport is not required.

Comment thread pipeline/backend/kubernetes/backend_options.go Outdated
@qwerty287 qwerty287 added enhancement improve existing features backend/kubernetes labels Mar 23, 2026
@Aex12

Aex12 commented Mar 23, 2026

Copy link
Copy Markdown
Contributor Author

Thanks! Is it possible to use these options to do something dangerous that could compromise the agent? Right now I think you can use them in any pipeline. (Sorry I don't have k8s experience...)

Backport is not required.

@qwerty287 Currently, most kubernetes distributions run pods with allowPrivilegeEscalation: true and without dropping the default runtime Linux capabilities unless explicitly configured otherwise. That means workflows today already run with a relatively permissive security context in Kubernetes.

This PR allows users to tighten the workflow pod security context, so they can run in namespaces enforcing the Pod Security Standards.

That said, we could change this so that allowPrivilegeEscalation can only be set to false, this would allow workflow pods to run in restricted namespaces, while avoiding potential harmful behavior if on the future the default value is changed by some container runtime.

Regarding capabilities, while it's true it defaults to the the default set of capabilities granted by the container runtime, Kubernetes documents it can also be used to add non-default capabilities. We could restrict this even further by only allowing to drop capabilities.

I think this changes make sense, I'll submit a new commit with them.

@Aex12 Aex12 requested a review from qwerty287 March 23, 2026 15:10
@qwerty287 qwerty287 requested a review from a team March 23, 2026 15:18
@woodpecker-bot

woodpecker-bot commented Mar 23, 2026

Copy link
Copy Markdown
Contributor

Surge PR preview deployment was removed

@Aex12

Aex12 commented Mar 23, 2026

Copy link
Copy Markdown
Contributor Author

Sorry @qwerty287, I forgot to relaunch the tests after my last commit. I just added a new commit that fixes the test.

SecurityContext is being set because privileged steps set the SecurityContext.Privileged field to true unless set otherwise. This was the existing behavior prior to my changes, which is preserved.

@codecov

codecov Bot commented Mar 23, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 34.24%. Comparing base (ff71578) to head (27f74e1).
⚠️ Report is 116 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #6307      +/-   ##
==========================================
+ Coverage   34.17%   34.24%   +0.06%     
==========================================
  Files         426      426              
  Lines       28541    28562      +21     
==========================================
+ Hits         9755     9782      +27     
+ Misses      17898    17892       -6     
  Partials      888      888              

☔ 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.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@qwerty287

qwerty287 commented Mar 24, 2026

Copy link
Copy Markdown
Contributor

Code itself seems fine, @woodpecker-ci/maintainers could someone check out the k8s impact?

@xoxys

xoxys commented Mar 31, 2026

Copy link
Copy Markdown
Member

@Aex12 can you rebase once again? Implementation looks good to me. @henkka @MartinSchmidt as you contributed multiple times to the K8s backend and seem to user it on a daily basis you might want to take a look as well :)

@Aex12

Aex12 commented Apr 1, 2026

Copy link
Copy Markdown
Contributor Author

Hi @xoxys, just rebased from main and squashed my commits.

@6543 6543 merged commit 43dcdc1 into woodpecker-ci:main Apr 28, 2026
9 checks passed
6543 pushed a commit that referenced this pull request Apr 28, 2026
### Problem
When the working directory is set to a directory that doesn't exists (for example, as `plugin-git` does), kubelet will pre-create it with ownership set to `root:root` and permissions `0755` . This makes pods running as non-root unable to write to it, causing permission errors.

### Solution
Added a `podInitContainer` function that conditionally creates an init container to pre-create the working directory with the correct permissions before the main step container starts.

### Behavior
- If the pod runs as root (`RunAsUser == 0` or unset), no init container is created. Kubelet handles directory creation automatically
- If the working directory matches a volume mount path exactly, no init container is needed. `FSGroupChangePolicy` handles permissions
- An init container is only created when the working directory is nested within a volume mount path
- The init container uses `busybox:stable-musl` with minimal resource limits (5m CPU, 5Mi memory) and drops all capabilities.

### Related issues and PRs
- Solves the error mentioned in #5346 (comment) without requiring a previous step.
- In addition to #6307 and #6310, this will make it easier to run woodpecker ci workloads in a namespace that enforces [Pod Security Standards](https://kubernetes.io/docs/concepts/security/pod-security-standards/)
@woodpecker-bot woodpecker-bot mentioned this pull request Apr 28, 2026
1 task
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

backend/kubernetes enhancement improve existing features

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants