@@ -1094,23 +1094,78 @@ repeated evaluations if they are shared across validations.
1094
1094
1095
1095
# ### Secondary Authz
1096
1096
1097
- We have general agreement to include this as a feature, but need to provide
1098
- a concrete design.
1099
-
1100
- kube-apiserver authorizer checks (aka Secondary-authz checks) have been proposed
1101
- as a way of doing things like :
1097
+ TODO : background and motivation
1102
1098
1103
- - Validate that only a user with a specific permission can set a particular
1099
+ - Validate that only a user with a specific permission can set a particular field.
1100
+ - Validate that only a controller responsible for a finalizer can remove it from the finalizers
1104
1101
field.
1105
- - Validate that only a controller responsible for a finalizer can remove it from
1106
- the finalizers field.
1107
1102
1108
- This could be supported by matching criteria, or via CEL expression access, or both.
1109
-
1110
- Use cases :
1103
+ To depend on an authz decision, validation expressions can reference the identifier `authorizer`,
1104
+ which will be bound at evaluation time to an Authorizer object supporting receiver-style function
1105
+ overloads :
1106
+
1107
+ | Symbol | Type | Description |
1108
+ |-------------|------------------------------------------------------|-------------|
1109
+ | path | Authorizer.(string) -> PathCheck | todo |
1110
+ | check | PathCheck.(string) -> Decision | todo |
1111
+ | resource | Authorizer.(string, string, string) -> ResourceCheck | todo |
1112
+ | subresource | ResourceCheck.(string) -> ResourceCheck | todo |
1113
+ | namespace | ResourceCheck.(string) -> ResourceCheck | todo |
1114
+ | name | ResourceCheck.(string) -> ResourceCheck | todo |
1115
+ | check | ResourceCheck.(string) -> Decision | todo |
1116
+ | allowed | Decision.() -> bool | todo |
1117
+ | denied | Decision.() -> bool | todo |
1118
+
1119
+ Example expressions using `authorizer` :
1120
+
1121
+ - ` authorizer.resource('signers', 'certificates.k8s.io', '*').name(oldObject.spec.signerName).check('approve').allowed()`
1122
+ - ` authorizer.path('/metrics').check('get').denied()`
1123
+
1124
+ Note that this API :
1125
+
1126
+ - Produces errors at compilation time when parameters are missing or improperly combined
1127
+ (e.g. subresource with non-resource path, missing path or resource).
1128
+ - Is open to the addition of future knobs (e.g. impersonation).
1129
+
1130
+ Other considerations :
1131
+
1132
+ - Does there need to be a special limit on the number of authz checks generated during expression
1133
+ evaluation, or is it sufficient to assign an appropriate fixed cost?
1134
+ - Since authorization decisions depend on an apiserver's authorizer, and the
1135
+ ValidatingAdmissionPolicy plugin is supported on [aggregated API
1136
+ servers](#aggregated-api-servers), the evaluation result of any validation expression involving
1137
+ secondary authz inherently depends on which apiserver evalutes it.
1138
+ - A validation expression could be written such that it allows malicious clients to probe
1139
+ permissions. Policy authors are responsible for careful use of client-provided inputs when
1140
+ constructing authz checks.
1141
+ - Decisions can be stored either as a [variable](#variables) or as part of the implementation of the
1142
+ object bound to the exposed `authorizer` object (i.e. caching decisions for identical checks
1143
+ within a single policy evaluation) in order to prevent duplicate checks across multiple validation
1144
+ expressions.
1145
+
1146
+ Use cases in existing admission plugins :
1111
1147
1112
1148
- PodSecurityPolicy (kube)
1113
1149
- CertificateApproval (kube)
1150
+
1151
+ ` ` ` yaml
1152
+ apiVersion: admissionregistration.k8s.io/v1alpha1
1153
+ kind: ValidatingAdmissionPolicy
1154
+ metadata:
1155
+ name: "certificate-approval-policy.example.com"
1156
+ spec:
1157
+ matchConstraints:
1158
+ resourceRules:
1159
+ - apiGroups: ["certificates.k8s.io"]
1160
+ apiVersions: ["*"]
1161
+ operations: ["UPDATE"]
1162
+ resources: ["certificatesigningrequests/approval"]
1163
+ validations:
1164
+ - expression: "authorizer.resource('signers', 'certificates.k8s.io', '*').name(oldObject.spec.signerName).check('approve').allowed() || authorizer.resource('signers', 'certificates.k8s.io', '*').name([oldObject.spec.signerName.split('/')[0], '*'].join('/')).check('approve').allowed()"
1165
+ reason: Forbidden
1166
+ messageExpression: "user not permitted to approve requests with signerName %q".format([oldObject.spec.signerName])"
1167
+ ` ` `
1168
+
1114
1169
- CertificateSigning (kube)
1115
1170
- OwnerReferencesPermissionEnforcement (kube)
1116
1171
- network.openshift.io/ExternalIPRanger
0 commit comments