kyverno / website

User docs and sample policies: https://kyverno.io
Apache License 2.0
35 stars 149 forks source link

[Bug] The policy shown as an example skips validation of init containers with non-mesh images #1251

Closed cybra-northco closed 4 months ago

cybra-northco commented 5 months ago

Page link

https://kyverno.io/blog/2024/02/04/securing-services-meshes-easier-with-kyverno/#policies-in-kyverno

Description

The policy description implies that:

  1. Any capability added beyond the allowed list is disallowed
  2. Service mesh containers may only add NET_ADMIN and NET_RAW to the list

However the policy definition iterates only on istio and linkerd init containers. If there was another init container defined like this:

  initContainers:
  - name: hacktainer
    image: hack/hack:v1
    securityContext:
      capabilities:
        add:
          - ROOT
          - ACCESS_ALL

then the policy will skip it and will succeed the validation.

Expected behavior

The policy must fail.

Slack discussion

No response

welcome[bot] commented 5 months ago

Thanks for opening your first issue here! Be sure to follow the issue template!

chipzoller commented 5 months ago

Thank you for catching this. This is my fault for not testing enough scenarios. I have enhanced this policy and think I now cover all the scenarios. Would you please run this policy through its paces and provide your feedback?

apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: disallow-capabilities
spec:
  validationFailureAction: Enforce
  background: true
  rules:
    - name: adding-capabilities-service-mesh
      match:
        any:
        - resources:
            kinds:
              - Pod
      preconditions:
        all:
        - key: "{{ request.operation || 'BACKGROUND' }}"
          operator: NotEquals
          value: DELETE
      context:
        - name: capabilities
          variable:
            value: ["AUDIT_WRITE","CHOWN","DAC_OVERRIDE","FOWNER","FSETID","KILL","MKNOD","NET_BIND_SERVICE","SETFCAP","SETGID","SETPCAP","SETUID","SYS_CHROOT"]
      validate:
        message: >-
          Any capabilities added beyond the allowed list (AUDIT_WRITE, CHOWN, DAC_OVERRIDE, FOWNER,
          FSETID, KILL, MKNOD, NET_BIND_SERVICE, SETFCAP, SETGID, SETPCAP, SETUID, SYS_CHROOT)
          are disallowed. Service mesh initContainers may additionally add NET_ADMIN and NET_RAW.
        foreach:
          - list: request.object.spec.initContainers[]
            preconditions:
              all:
              - key: "{{ element.image }}"
                operator: AnyIn
                value:
                - "*/istio/proxyv2*"
                - "*/linkerd/proxy-init*"
              - key: "{{ element.securityContext.capabilities.add[] || `[]` }}"
                operator: AnyNotIn
                value:
                  - NET_ADMIN
                  - NET_RAW
                  - "{{ capabilities }}"
            deny:
              conditions:
                all:
                - key: "{{ element.securityContext.capabilities.add[] || `[]` }}"
                  operator: AnyNotIn
                  value: "{{ capabilities }}"
                  message: The service mesh initContainer {{ element.name }} is attempting to add forbidden capabilities.
          - list: request.object.spec.initContainers[]
            preconditions:
              all:
              - key: "{{ element.image }}"
                operator: AnyNotIn
                value:
                - "*/istio/proxyv2*"
                - "*/linkerd/proxy-init*"
            deny:
              conditions:
                all:
                - key: "{{ element.securityContext.capabilities.add[] || `[]` }}"
                  operator: AnyNotIn
                  value: "{{ capabilities }}"
                  message: The initContainer {{ element.name }} is attempting to add forbidden capabilities.
          - list: request.object.spec.[ephemeralContainers, containers][]
            deny:
              conditions:
                all:
                - key: "{{ element.securityContext.capabilities.add[] || `[]` }}"
                  operator: AnyNotIn
                  value: "{{ capabilities }}"
                  message: The container {{ element.name }} is attempting to add forbidden capabilities.
cybra-northco commented 4 months ago

@chipzoller thank you, works as expected!

chipzoller commented 4 months ago

Fix sent in #1254