apiVersion: admissionregistration.k8s.io/v1 kind: ValidatingAdmissionPolicy metadata: {name: short-election} spec: failurePolicy: Fail matchConstraints: resourceRules: - apiGroups: [""] apiVersions: [v1] operations: [UPDATE] resources: [pods] matchConditions: - name: tunnel-account expression: request.userInfo.username == 'system:serviceaccount:short:tunnel' variables: - name: labels expression: "has(object.metadata.labels) ? object.metadata.labels : {}" - name: oldLabels expression: "has(oldObject.metadata.labels) ? oldObject.metadata.labels : {}" validations: - expression: >- oldObject.metadata.namespace == 'short' && oldObject.spec.serviceAccountName == 'tunnel' && 'app.kubernetes.io/name' in variables.oldLabels && variables.oldLabels['app.kubernetes.io/name'] == 'tunnel' message: The tunnel may only update tunnel pods. - expression: object.spec == oldObject.spec message: The tunnel may not change pod specifications. - expression: >- variables.labels.all(k, k == 'role' || (k in variables.oldLabels && variables.labels[k] == variables.oldLabels[k])) && variables.oldLabels.all(k, k == 'role' || k in variables.labels) && (!('role' in variables.labels) || variables.labels['role'] == 'active') message: The tunnel may only set or remove the active role label. - expression: >- (has(object.metadata.annotations) ? object.metadata.annotations : {}) == (has(oldObject.metadata.annotations) ? oldObject.metadata.annotations : {}) && (has(object.metadata.ownerReferences) ? object.metadata.ownerReferences : []) == (has(oldObject.metadata.ownerReferences) ? oldObject.metadata.ownerReferences : []) && (has(object.metadata.finalizers) ? object.metadata.finalizers : []) == (has(oldObject.metadata.finalizers) ? oldObject.metadata.finalizers : []) message: The tunnel may not change annotations, owners, or finalizers. --- apiVersion: admissionregistration.k8s.io/v1 kind: ValidatingAdmissionPolicyBinding metadata: {name: short-election} spec: policyName: short-election validationActions: [Deny]