Skip to content

Commit

Permalink
KEP-3488 ValidatingAdmissionPolicy: Enforcement actions, audit annota…
Browse files Browse the repository at this point in the history
…tions, and secondary authz (#40098)

* Document auditAnnotations, validationActions and authorizer

* Apply suggestions from code review

Co-authored-by: Qiming Teng <tengqm@outlook.com>

* Apply suggestions from code review

Co-authored-by: Tim Allclair <timallclair@gmail.com>

* Apply feedback

---------

Co-authored-by: Qiming Teng <tengqm@outlook.com>
Co-authored-by: Tim Allclair <timallclair@gmail.com>
  • Loading branch information
3 people committed Apr 3, 2023
1 parent 40a6ff8 commit cf37b59
Show file tree
Hide file tree
Showing 4 changed files with 110 additions and 0 deletions.
Expand Up @@ -92,6 +92,7 @@ metadata:
name: "demo-binding-test.example.com"
spec:
policyName: "demo-policy.example.com"
validationActions: [Deny]
matchResources:
namespaceSelector:
matchLabels:
Expand All @@ -107,6 +108,37 @@ ValidatingAdmissionPolicy 'demo-policy.example.com' with binding 'demo-binding-t

The above provides a simple example of using ValidatingAdmissionPolicy without a parameter configured.

#### Validation actions

Each `ValidatingAdmissionPolicyBinding` must specify one or more
`validationActions` to declare how `validations` of a policy are enforced.

The supported `validationActions` are:

- `Deny`: Validation failure results in a denied request.
- `Warn`: Validation failure is reported to the request client
as a [warning](/blog/2020/09/03/warnings/).
- `Audit`: Validation failure is included in the audit event for the API request.

For example, to both warn clients about a validation failure and to audit the
validation failures, use:

```yaml
validationActions: [Warn, Audit]
```

`Deny` and `Warn` may not be used together since this combination
needlessly duplicates the validation failure both in the
API response body and the HTTP warning headers.

A `validation` that evaluates to false is always enforced according to these
actions. Failures defined by the `failurePolicy` are enforced
according to these actions only if the `failurePolicy` is set to `Fail` (or unset),
otherwise the failures are ignored.

See [Audit Annotations: validation falures](/docs/reference/labels-annotations-taints/audit-annotations/#validation-policy-admission-k8s-io-validation_failure)
for more details about the validation failure audit annotation.

#### Parameter resources

Parameter resources allow a policy configuration to be separate from its definition.
Expand Down Expand Up @@ -159,6 +191,7 @@ metadata:
name: "replicalimit-binding-test.example.com"
spec:
policyName: "replicalimit-policy.example.com"
validationActions: [Deny]
paramRef:
name: "replica-limit-test.example.com"
matchResources:
Expand Down Expand Up @@ -188,6 +221,7 @@ metadata:
name: "replicalimit-binding-nontest"
spec:
policyName: "replicalimit-policy.example.com"
validationActions: [Deny]
paramRef:
name: "replica-limit-clusterwide.example.com"
matchResources:
Expand Down Expand Up @@ -219,6 +253,7 @@ metadata:
name: "replicalimit-binding-global"
spec:
policyName: "replicalimit-policy.example.com"
validationActions: [Deny]
params: "replica-limit-clusterwide.example.com"
matchResources:
namespaceSelector:
Expand Down Expand Up @@ -299,6 +334,12 @@ variables as well as some other useful variables:
- 'request' - Attributes of the [admission request](/docs/reference/config-api/apiserver-admission.v1/#admission-k8s-io-v1-AdmissionRequest).
- 'params' - Parameter resource referred to by the policy binding being evaluated. The value is
null if `ParamKind` is unset.
- `authorizer` - A CEL Authorizer. May be used to perform authorization checks for the principal
(authenticated user) of the request. See
[Authz](https://pkg.go.dev/k8s.io/apiserver/pkg/cel/library#Authz) in the Kubernetes CEL library
documentation for more details.
- `authorizer.requestResource` - A shortcut for an authorization check configured with the request
resource (group, resource, (subresource), namespace, name).

The `apiVersion`, `kind`, `metadata.name` and `metadata.generateName` are always accessible from
the root of the object. No other metadata properties are accessible.
Expand Down Expand Up @@ -386,3 +427,23 @@ the request is determined as follows:
2. Otherwise:
- for [`failurePolicy: Fail`](#failure-policy), reject the request (without evaluating the policy).
- for [`failurePolicy: Ignore`](#failure-policy), proceed with the request but skip the policy.

### Audit annotations

`auditAnnotations` may be used to include audit annotations in the audit event of the API request.

For example, here is an admission policy with an audit annotation:

{{< codenew file="access/validating-admission-policy-audit-annotation.yaml" >}}

When an API request is validated with this admission policy, the resulting audit event will look like:

{{< codenew file="access/audit-event-with-audit-annotation.yaml" >}}

In this example the annotation will only be included if the `spec.replicas` of the Deployment is more than
50, otherwise the CEL expression evalutes to null and the annotation will not be included.

Note that audit annotation keys are prefixed by the name of the `ValidatingAdmissionWebhook` and a `/`. If
another admission controller, such as an admission webhook, uses the exact same audit annotation key, the
value of the first admission controller to include the audit annotation will be included in the audit
event and all other values will be ignored.
Expand Up @@ -108,3 +108,25 @@ to ensure connections are secured properly and to avoid disruption in future rel

There's more information about this in the Go documentation:
[Rejecting SHA-1 certificates](https://go.dev/doc/go1.18#sha1).

## validation.policy.admission.k8s.io/validation_failure

Example: `validation.policy.admission.k8s.io/validation_failure: '[{"message": "Invalid value", {"policy": "policy.example.com", {"binding": "policybinding.example.com", {"expressionIndex": "1", {"validationActions": ["Audit"]}]'`

Used by Kubernetes version v1.27 and later.

This annotation indicates that a admission policy validation evaluted to false
for an API request, or that the validation resulted in an error while the policy
was configured with `failurePolicy: Fail`.

The value of the annotation is a JSON object. The `message` in the JSON
provides the message about the validation failure.

The `policy`, `binding` and `expressionIndex` in the JSON identifies the
name of the `ValidatingAdmissionPolicy`, the name of the
`ValidatingAdmissionPolicyBinding` and the index in the policy `validations` of
the CEL expressions that failed, respectively.

The `validationActions` shows what actions were taken for this validation failure.
See [Validating Admission Policy](/docs/reference/access-authn-authz/validating-admission-policy/)
for more details about `validationActions`.
12 changes: 12 additions & 0 deletions content/en/examples/access/audit-event-with-audit-annotation.yaml
@@ -0,0 +1,12 @@
# the audit event recorded
{
"kind": "Event",
"apiVersion": "audit.k8s.io/v1",
"annotations": {
"demo-policy.example.com/high-replica-count": "Deployment spec.replicas set to 128"
# other annotations
...
}
# other fields
...
}
@@ -0,0 +1,15 @@
apiVersion: admissionregistration.k8s.io/v1alpha1
kind: ValidatingAdmissionPolicy
metadata:
name: "demo-policy.example.com"
spec:
failurePolicy: Fail
matchConstraints:
resourceRules:
- apiGroups: ["apps"]
apiVersions: ["v1"]
operations: ["CREATE", "UPDATE"]
resources: ["deployments"]
validations:
- key: "high-replica-count"
valueExpression: "object.spec.replicas > 50 ? 'Deployment spec.replicas set to ' + string(object.spec.replicas) : null"

0 comments on commit cf37b59

Please sign in to comment.