Skip to content

Commit ed71967

Browse files
benluddyjpbetz
authored andcommitted
wip: secondary authz for cel admission control
1 parent 7f1eec4 commit ed71967

File tree

1 file changed

+66
-11
lines changed
  • keps/sig-api-machinery/3488-cel-admission-control

1 file changed

+66
-11
lines changed

keps/sig-api-machinery/3488-cel-admission-control/README.md

Lines changed: 66 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1094,23 +1094,78 @@ repeated evaluations if they are shared across validations.
10941094

10951095
#### Secondary Authz
10961096

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
11021098

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
11041101
field.
1105-
- Validate that only a controller responsible for a finalizer can remove it from
1106-
the finalizers field.
11071102

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:
11111147

11121148
- PodSecurityPolicy (kube)
11131149
- 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+
11141169
- CertificateSigning (kube)
11151170
- OwnerReferencesPermissionEnforcement (kube)
11161171
- network.openshift.io/ExternalIPRanger

0 commit comments

Comments
 (0)