Skip to content
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

KEP-3488: Implement Enforcement Actions and Audit Annotations #115973

Merged
merged 3 commits into from
Mar 7, 2023

Conversation

jpbetz
Copy link
Contributor

@jpbetz jpbetz commented Feb 22, 2023

What type of PR is this?

/kind feature

What this PR does / why we need it:

Implements the Enforcement Actions and Audit Annotations sections of CEL for Admission Control.

Special notes for your reviewer:

Adding validationActions as a required field is a intentional (alpha stability) breaking change. We want developers setting this explicitly going forward.

Something we missed when writing the KEP: If multiple bindings for a policy match the same resource, I'd decided to have all the unique audit annotation values produced by the auditAnnotations concatenated into a comma-separated value. For simple cases where all the bindings produce the same audit annotation value, this results in that single value being published to the audit event. For cases where bindings produce different values, the values are concatenated into a comma-separated list so no information is lost. Better ideas on how to best combine the values into a single audit annotation value are welcome.

Deviations from the KEP:

  • Switched from {policyName}/validation_failure to the validation.policy.admission.k8s.io/validation_failure to adhere better to the conventions of audit annotations.
  • Custom audit annotations remain in the form {ValidatingPolicyDefinition name}/{auditAnnotation key}. We had wanted to offer a way to prevent a validating or mutating webhook from producing the exact same audit annotation as a ValidatingPolicyDefinition, but the structure of audit annotation keys makes this awkward because only one / is allowed and there is a length restriction on audit annotation keys.

Does this PR introduce a user-facing change?

Adds auditAnnotations to ValidatingAdmissionPolicy, enabling CEL to be used to add audit annotations to request audit events.
Adds validationActions to ValidatingAdmissionPolicyBinding, enabling validation failures to be handled by any combination of the warn, audit and deny enforcement actions.

Additional documentation e.g., KEPs (Kubernetes Enhancement Proposals), usage docs, etc.:


@k8s-ci-robot k8s-ci-robot added release-note Denotes a PR that will be considered when it comes time to generate release notes. size/XXL Denotes a PR that changes 1000+ lines, ignoring generated files. kind/feature Categorizes issue or PR as related to a new feature. do-not-merge/needs-sig Indicates an issue or PR lacks a `sig/foo` label and requires one. needs-triage Indicates an issue or PR lacks a `triage/foo` label and requires one. needs-priority Indicates a PR lacks a `priority/foo` label and requires one. labels Feb 22, 2023
@jpbetz jpbetz changed the title Enforcement actions KEP-3488: Implement Enforcement Actions and Audit Annotations Feb 22, 2023
@jpbetz
Copy link
Contributor Author

jpbetz commented Feb 22, 2023

/sig api-machinery
/priority important-soon
/api-review

@k8s-ci-robot k8s-ci-robot added sig/api-machinery Categorizes an issue or PR as relevant to SIG API Machinery. priority/important-soon Must be staffed and worked on either currently, or very soon, ideally in time for the next release. labels Feb 22, 2023
@jpbetz
Copy link
Contributor Author

jpbetz commented Feb 22, 2023

/triage accepted

@k8s-ci-robot k8s-ci-robot added triage/accepted Indicates an issue or PR is ready to be actively worked on. cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. area/apiserver and removed do-not-merge/needs-sig Indicates an issue or PR lacks a `sig/foo` label and requires one. needs-priority Indicates a PR lacks a `priority/foo` label and requires one. needs-triage Indicates an issue or PR lacks a `triage/foo` label and requires one. labels Feb 22, 2023
@k8s-ci-robot k8s-ci-robot added area/code-generation area/test kind/api-change Categorizes issue or PR as related to adding, removing, or otherwise changing an API sig/testing Categorizes an issue or PR as relevant to SIG Testing. labels Feb 22, 2023
@k8s-triage-robot
Copy link

This PR may require API review.

If so, when the changes are ready, complete the pre-review checklist and request an API review.

Status of requested reviews is tracked in the API Review project.

@jpbetz
Copy link
Contributor Author

jpbetz commented Feb 22, 2023

@cici37 Feedback applied, thanks!

@jpbetz
Copy link
Contributor Author

jpbetz commented Feb 23, 2023

/retest

@sftim
Copy link
Contributor

sftim commented Feb 23, 2023

We had wanted to offer a way to prevent a validating or mutating webhook from producing the exact same audit annotation as a ValidatingPolicyDefinition, but the structure of audit annotation keys makes this awkward because only one / is allowed and there is a length restriction on audit annotation keys.

Does anything stop me from abusing this to write a well-known annotation key, or to try to fool someone into thinking I did?

@liggitt liggitt moved this from In progress to Changes requested in API Reviews Mar 2, 2023
@k8s-ci-robot k8s-ci-robot added the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Mar 2, 2023
@k8s-ci-robot k8s-ci-robot removed the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Mar 3, 2023
@jpbetz
Copy link
Contributor Author

jpbetz commented Mar 3, 2023

Rebased and API review feedback applied!

@liggitt liggitt moved this from Changes requested to In progress in API Reviews Mar 3, 2023
pkg/apis/admissionregistration/validation/validation.go Outdated Show resolved Hide resolved
pkg/apis/admissionregistration/validation/validation.go Outdated Show resolved Hide resolved
@@ -70,9 +70,6 @@ func (a *evaluationActivation) Parent() interpreter.Activation {

// Compile compiles the cel expressions defined in the ExpressionAccessors into a Filter
func (c *filterCompiler) Compile(expressionAccessors []ExpressionAccessor, hasParam bool) Filter {
if len(expressionAccessors) == 0 {
return nil
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Why to remove this nil check?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Now that we have both validations and auditAnnotations, it is possible for one of the calls to Compile to have an empty slice. We could write special case cost to avoid the compile call, but it is less error prone to make the compile calls safe by not returning an error here.

Copy link
Contributor

Choose a reason for hiding this comment

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

Here is not really a err handling but rather a short circus. I am ok with either since it is nit and not a blocker any way :)

@@ -165,6 +170,8 @@ func (c *celAdmissionController) Run(stopCh <-chan struct{}) {
wg.Wait()
}

const maxAuditAnnotationValueLength = 10 * 1024
Copy link
Contributor

Choose a reason for hiding this comment

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

Why this is different than the number in validation?
Also, maybe have a comment to remind keeping it same as it is in validation if it should be the same.
A following up PR might be add this to celconfig file we used in #115747

Copy link
Contributor Author

Choose a reason for hiding this comment

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

An expressions that concatenate strings will often produce a longer value than the expression, so the expression limit is set at 5kb and the annotation value limits is set at 10k.

type validationFailureValue struct {
Message string `json:"message"`
Policy string `json:"policy"`
Binding string `json:"binding"`
Copy link
Contributor

Choose a reason for hiding this comment

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

Maybe use PolicyName and BindingName here since we only assign name not the entire policy/binding?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I was trying to save space since I'm already concerned with the data volume produced by these audit annotation values. It should be clear enough? Let me know if you feel strongly about it.

Copy link
Contributor

Choose a reason for hiding this comment

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

Just thought we have Policy/Binding all over and it's easily confused in terms of code maintenance.
It is not a merging blocker though :)

for i, evalResult := range auditAnnotationEvalResults {
var auditAnnotationResult = &auditAnnotationResults[i]
// TODO: move this to generics
validation, ok := evalResult.ExpressionAccessor.(*AuditAnnotationCondition)
Copy link
Contributor

Choose a reason for hiding this comment

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

Is that possible that evalResult.ExpressionAccessor is nil and evalResult.Error saved the err?
Looks at the code path checks evalResult.ExpressionAccessor.(*AuditAnnotationCondition) before evalResult.Error and the error might be ignored?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is the same order as for validations above. This !ok check is a failure that should never be reached if the code is working as expected (and will go away when we switch to using generics here).

@liggitt liggitt moved this from In progress to API review completed, 1.27 in API Reviews Mar 6, 2023
Copy link
Member

@liggitt liggitt left a comment

Choose a reason for hiding this comment

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

A couple nits/suggestions, but API types, validation, and docs lgtm.

Once the compile/admission/impl bits are reviewed/approved, tag me back in and I can approve.

pkg/apis/admissionregistration/validation/validation.go Outdated Show resolved Hide resolved
pkg/apis/admissionregistration/validation/validation.go Outdated Show resolved Hide resolved
pkg/apis/admissionregistration/validation/validation.go Outdated Show resolved Hide resolved
@cici37
Copy link
Contributor

cici37 commented Mar 6, 2023

Looks like the tests messages need to be updated with the code updates. Couple nits. Overall LGTM :)

@jpbetz
Copy link
Contributor Author

jpbetz commented Mar 6, 2023

Feedback applied and commits squashed to minimal set (with codegen separated out)

@cici37
Copy link
Contributor

cici37 commented Mar 7, 2023

/lgtm
/approve

/test pull-kubernetes-e2e-kind-ipv6

@k8s-ci-robot k8s-ci-robot added the lgtm "Looks good to me", indicates that a PR is ready to be merged. label Mar 7, 2023
@k8s-ci-robot
Copy link
Contributor

LGTM label has been added.

Git tree hash: fbbfb21bd33f40a55ccdbfc530ec543351172d47

@liggitt
Copy link
Member

liggitt commented Mar 7, 2023

/approve
for API changes

@k8s-ci-robot
Copy link
Contributor

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: cici37, jpbetz, liggitt

The full list of commands accepted by this bot can be found here.

The pull request process is described here

Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@k8s-ci-robot k8s-ci-robot added the approved Indicates a PR has been approved by an approver from all required OWNERS files. label Mar 7, 2023
@k8s-ci-robot k8s-ci-robot merged commit 0467542 into kubernetes:master Mar 7, 2023
@k8s-ci-robot k8s-ci-robot added this to the v1.27 milestone Mar 7, 2023
@jpbetz jpbetz mentioned this pull request Mar 9, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
api-review Categorizes an issue or PR as actively needing an API review. approved Indicates a PR has been approved by an approver from all required OWNERS files. area/apiserver area/code-generation area/test cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. kind/api-change Categorizes issue or PR as related to adding, removing, or otherwise changing an API kind/feature Categorizes issue or PR as related to a new feature. lgtm "Looks good to me", indicates that a PR is ready to be merged. priority/important-soon Must be staffed and worked on either currently, or very soon, ideally in time for the next release. release-note Denotes a PR that will be considered when it comes time to generate release notes. sig/api-machinery Categorizes an issue or PR as relevant to SIG API Machinery. sig/testing Categorizes an issue or PR as relevant to SIG Testing. size/XXL Denotes a PR that changes 1000+ lines, ignoring generated files. triage/accepted Indicates an issue or PR is ready to be actively worked on.
Projects
Status: API review completed, 1.27
Development

Successfully merging this pull request may close these issues.

None yet

6 participants