-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Introduce new SecurePodDefaults options #16042
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
Conversation
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #16042 +/- ##
==========================================
- Coverage 80.07% 80.02% -0.05%
==========================================
Files 214 214
Lines 16907 16932 +25
==========================================
+ Hits 13538 13550 +12
- Misses 3013 3021 +8
- Partials 356 361 +5 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
|
/test upgrade-tests |
fee5725 to
e1d20df
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the release notes in the PR body.
One expected side-effect of this change is that certain images will break with the new default.
eg. nginx will no longer run since it tries to do a chown syscall on startup
nginx: [emerg] chown("/var/cache/nginx/client_temp", 101) failed (1: Operation not permitted)
caddy (which runs as root) runs on on the default profile now. It fails on the restricted one which is expected.
As a follow up (separate PR) I notice the caddy image error doesn't propagate up properly to the Revision properly. The Pod has
state:
waiting:
message: 'container has runAsNonRoot and image will run as root (pod: "hello-00001-deployment-5c77b7fb5b-w7r74_default(271b9aaa-340d-4073-914c-2144c8560273)",
container: user-container)'
reason: CreateContainerConfigError
|
/assign @evankanderson for a security WG review |
601132f to
a7734b7
Compare
evankanderson
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should also plan to flag changing any defaults here as a breaking change if we decide to do so, along with clear instructions about what the breakage looks like, and how to switch back to the current behavior.
In particular, I think nginx is probably a great example to show / test with, since many people may use it to serve static content.
From a security point of view, I think getting towards safer defaults without breaking too many things for users is a net win, so I think it makes sense from a security perspective.
|
|
||
| if psc.RunAsNonRoot == nil { | ||
| if cfg.Features.SecurePodDefaults == config.Restricted { | ||
| updatedSC.RunAsNonRoot = ptr.Bool(true) | ||
| } else { | ||
| updatedSC.RunAsNonRoot = ptr.Bool(false) | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This feels like it's doing something different, since RunAsNonRoot is a tri-state (*bool).
Before, if SecurePodDefaults was enabled, this would set a missing RunAsNonRoot to true . If RunAsNonRoot was set to false, it would leave it as false. The new flag will unconditionally set RunAsNonRoot, which feels like it might be a value which is always wrong.
What about adding an root-okay value between disabled and enabled, and then aiming to change the default to root-okay in an upcoming release (it could be 1.20 or 1.21)?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we make RootAllowed as the default and that would work the same as you described where it allows RunAsRoot to true if empty or false if the user set it to that.
and keep Restricted but not set it as a default until a later release?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it could also be called RootEnabled
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I think RootAllowed is probably a good name for this intermediate setting, and I think it's reasonable to make it the new default in the same release; upgrade instructions should flag that setting the config to disabled prior to upgrading will preserve existing behavior.
Since this is an admission webhook, I think it will only affect new Revisions, correct?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Everything else in the config is called enabled, should we use that for the meaning of root-allowed and mention it in the description? or do you actually want it to be called root-allowed and remove enabled
Since this is an admission webhook, I think it will only affect new Revisions, correct?
yes I tested with an existing cluster and the existing revisions were fine, only applied on create
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@evankanderson wdyt?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would like the enum values to clearly indicate where on the security continuum the value falls. We currently have:
disabled-- least secureenabled-- some security, low chance of incompatibilityrestricted-- highest security, medium chance of incompatibility
The problem is that on a quick read, it's not clear to me if enabled > restricted or restricted > enabled in terms of security. I'd sort of expect that enabled means as much security as possible, so I'd like things to look like:
disabled-- least secure$BETTER-- some security, low chance of incompatibilityenabled-- highest security, medium chance of incompatibility
We could call $BETTER something like transition or root-allowed, but it seems odd for enabled to be an intermediate step, and for users who've already turned on enabled in 1.19 (where it means "highest security") to have a security backslide until they change to restricted in 1.20 (which would not be allowed in 1.19). On the other hand, if we add $BETTER in the middle as a default, users already on enabled don't need to change anything, users who want disabled can set it explicitly before upgrade, and users who don't care can simply accept the upgrade (and possibly set the value afterwards).
Sorry for the late reply -- hope this makes sense.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes, makes perfect sense, thank you for the clarification. Will make the necessary updates and let you know
afc0a85 to
0601251
Compare
|
here is a summary of the changes:
|
Sorry to be going around on this, but what's the user benefit to setting The previous purpose of
The "correct" solution is to rebuild the container and/or set My suggestion would be to change // RunAsNonRoot breaks more containers than other settings, see discussion in #16042
if cfg.Features.SecurePodDefaults == config.Enabled {
if psc.RunAsNonRoot == nil {
updatedSC.RunAsNonRoot = ptr.Bool(true)
}
}In either case, it feels like the enforcement of Of course, it's also possible that I'm missing a use-case here, but this was mostly intended to be a "better defaults than Kubernetes" feature in the same way that we do for probes and network setup. |
apologies for maybe not understand, but if securePodDefaults is set |
Interesting - I didn't realize there was an K8s admission controller that was already doing defaulting on the pods. I was under the impression there was a validation controller that would prevent pods from running. @evankanderson I guess what do we want to do here? Do we want to remove this feature entirely (and the warnings) and just provide docs about 'securing workloads' and linking to the K8s Pod Security Admission ? |
|
For some historical context the original PR (#13398) was done in Oct 2022 which is roughly a month or so after K8s 1.25 was released with security pod admission going stable - https://kubernetes.io/docs/concepts/security/pod-security-admission/ Given we trail K8s releases by some time we probably introduced the secure defaulting because it wasn't available at the time. |
|
Kubernetes does not have secure defaulting; it does have policies to enforce (block) pods which don't set the fields to approved values. My concern is the behavior of a pod which uses a user container which only functions when running as the root user (for example, the binary or shared libraries are in a If a user submits the pod with I'm fine with setting a default if the value was previously unset (the Kubernetes behavior here values backwards compatibility too highly in my opinion), but forcibly overriding user intent seems hostile. |
|
@evankanderson @dprotaso what do you think about this: My understanding is that the concern is the current code changes in this PR would override the user the way I implemented the feature in this PR is:
here are some suggestions for how we can move forward:
|
|
My thoughts about this (though I'm happy to be overruled):
What I would like to see here is:
|
|
would this match what we want to see and provide better secure defaults?
|
|
I was wrong about k8s defaulting settings. Given the naming issue of the setting - I'm wondering if we should use the profile names of Then Knative's obligation is to 'default' settings appropriate to satisfy the profile. I'm also wondering if we shouldn't enable this by default in this release (sorry) - or maybe we introduce that as a new feature and deprecate this one |
- default is still disabled - when AllowRootBounded, defaults SeccompProfile and Capabilities if nil - when enabled sets RunAsNonRoot to true if not already specified
0601251 to
40f26e7
Compare
evankanderson
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
/lgtm
/approve
/hold if you want to make the other slices.Contains changes (I don't care strongly)
thanks for all the reviews and help @evankanderson I added the rest of the slice.Contains, looks and read much better than the long if |
|
/lgtm |
|
/approve |
|
/assign @dprotaso |
|
/lgtm 🎉 thanks for the improvements @evankanderson @nader-ziada Are we ok with flipping the default in 1.21 release? Assuming in 1.20 we notify people about the upcoming change |
|
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: dprotaso, evankanderson, nader-ziada The full list of commands accepted by this bot can be found here. The pull request process is described here DetailsNeeds approval from an approver in each of these files:
Approvers can indicate their approval by writing |
Yes, I think flipping the default to |
|
@nader-ziada can you add docs to the website around this secure-pod-defaults? |
|
Fixes #14029
Proposed Changes
Release Note