-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Add validation to warn about insecure SecurityContext defaults #13399
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
Add validation to warn about insecure SecurityContext defaults #13399
Conversation
|
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: evankanderson 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 |
|
I need to add an |
…default SecurityContexts dozens of times
|
@mattmoor -- it looks like "warning level errors" are translating into |
|
Ah no, that's because this was never taught about warnings: |
|
tl;dr we added reactors to simulate validation webhooks in our table tests by calling |
|
Hah, I can do that, then. I didn't realize that this wasn't going through an actual apiserver in the test. |
|
I definitely didn't want to bring in an API server as a requirement for unit testing, that seems rough 😅 |
…ecure-defaults-for-3-years
…ecure-defaults-for-3-years
Codecov ReportBase: 86.43% // Head: 86.17% // Decreases project coverage by
Additional details and impacted files@@ Coverage Diff @@
## main #13399 +/- ##
==========================================
- Coverage 86.43% 86.17% -0.26%
==========================================
Files 196 197 +1
Lines 14600 14723 +123
==========================================
+ Hits 12619 12688 +69
- Misses 1680 1733 +53
- Partials 301 302 +1
Help us with your feedback. Take ten seconds to tell us how you rate us. Have a feature suggestion? Share it here. ☔ View full report at Codecov. |
…://github.com/evankanderson/serving into warning-warning-insecure-defaults-for-3-years
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.
|
/retest |
psschwei
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.
other than a nit on the comment, LGTM
pkg/apis/serving/k8s_validation.go
Outdated
| // warnDefaultContainerSecurityContext warns about Kubernetes default | ||
| // SecurityContext values which are insecure (i.e. the "restricted" profile | ||
| // forbids these values). Because securityContext values may also be set at | ||
| // the Pod level, the container-level settings need to be considered alongside | ||
| // the Pod-level settings. |
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.
nit: the release note is a little clearer in that the warning will sound when these values are unset. would be helpful to include that detail in the comment here, maybe something like:
| // warnDefaultContainerSecurityContext warns about Kubernetes default | |
| // SecurityContext values which are insecure (i.e. the "restricted" profile | |
| // forbids these values). Because securityContext values may also be set at | |
| // the Pod level, the container-level settings need to be considered alongside | |
| // the Pod-level settings. | |
| // warnDefaultContainerSecurityContext warns about Kubernetes default | |
| // SecurityContext values which are unset and thus insecure (i.e. the "restricted" profile | |
| // forbids these values). Because securityContext values may also be set at | |
| // the Pod level, the container-level settings need to be considered alongside | |
| // the Pod-level settings. |
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.
Done (and rewrapped, just 'cuz)
pkg/apis/serving/k8s_validation.go
Outdated
| for i := range ps.Containers { | ||
| errs = errs.Also( | ||
| warnDefaultContainerSecurityContext(ctx, ps.SecurityContext, ps.Containers[i].SecurityContext). | ||
| ViaFieldIndex("containers", 1).ViaField("securityContext")) |
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 1 should be i
| ViaFieldIndex("containers", 1).ViaField("securityContext")) | |
| ViaFieldIndex("containers", i).ViaField("securityContext")) |
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.
Ugh, I think I might have let AutoPilot write these... that's a crazy mistake.
Thanks!
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.
ViaField and ViaFieldIndex were backwards here, too, which I noticed in the test output when I was fixing the [1] in the tests.
pkg/apis/serving/k8s_validation.go
Outdated
| for i := range ps.InitContainers { | ||
| errs = errs.Also( | ||
| warnDefaultContainerSecurityContext(ctx, ps.SecurityContext, ps.InitContainers[i].SecurityContext). | ||
| ViaFieldIndex("initContainers", 1).ViaField("securityContext")) |
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.
Likewise 1 should be i
| ViaFieldIndex("initContainers", 1).ViaField("securityContext")) | |
| ViaFieldIndex("initContainers", i).ViaField("securityContext")) |
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.
Done
| ps corev1.PodSpec | ||
| cfgOpts []configOption | ||
| want *apis.FieldError | ||
| errLevel apis.DiagnosticLevel |
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.
question: is the default value (0) == apis.ErrorLevel
looks like it is - https://github.com/knative/pkg/blob/247510c00e9dbb7f5a23b76e8ab76654de173a04/apis/field_error.go#L38
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 it would be more clear in the tests that don't assert warnings to just filter in the t.Run instead of adding the additional option to the test case
got = got.Filter(apis.ErrorLevel)
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, the default value is error for compatibility with all the existing code.
I think I was trying to be consistent here, but I can roll all these back if you prefer.
| errs = errs.Also(insecureDefault("capabilities")) | ||
| } else { | ||
| if sc.Capabilities.Drop == nil { | ||
| errs = errs.Also(insecureDefault("capabilities.drop")) |
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.
You might want to add a warning that all needs to be ALL - or error out on this even
Knative made this mistake and it was only recently fixed - #13327
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.
Added a warning if arg 0 is "all", I think that should be sufficient for now.
|
(Still rolling back the validation_test changes, but wanted to get other bits pushed.) |
|
Okay, this should be ready for another review. |
|
/lgtm |
Fixes #13398
It would be nice if the Kubernetes defaults for SecurityContext and PodSecurityContext followed the
Pod Security Standards
restrictedprofile, whichis "following current Pod hardening best practices", but they do not, presumably for historical reasons.
Since all the SecurityContext values which have insecure defaults can distinguish between "default value" and "declared insecure"
(either via pointer or empty-string vs dangerous string), it seems reasonable to warn about these defaults in Knative, and
default them to "safe" values in the future, since we've knowingly restricted our set of workloads to those that should be safer.
Proposed Changes
Explicitly setting values to their (insecure) defaults will disable the warning. This is intentional, we only want to alert people who
may not know the default values have higher privilege than necessary.
Release Note