All Policies

Restrict Secrets by Name in CEL expressions

Secrets often contain sensitive information and their access should be carefully controlled. Although Kubernetes RBAC can be effective at restricting them in several ways, it lacks the ability to use wildcards in resource names. This policy ensures that only Secrets beginning with the name `safe-` can be consumed by Pods. In order to work effectively, this policy needs to be paired with a separate policy or rule to require `automountServiceAccountToken=false` since this would otherwise result in a Secret being mounted.

Policy Definition

/other-cel/restrict-secrets-by-name/restrict-secrets-by-name.yaml

 1apiVersion: kyverno.io/v1
 2kind: ClusterPolicy
 3metadata:
 4  name: restrict-secrets-by-name
 5  annotations:
 6    policies.kyverno.io/title: Restrict Secrets by Name in CEL expressions
 7    policies.kyverno.io/category: Other in CEL 
 8    policies.kyverno.io/subject: Pod, Secret
 9    kyverno.io/kyverno-version: 1.11.0
10    kyverno.io/kubernetes-version: "1.26-1.27"
11    policies.kyverno.io/description: >-
12      Secrets often contain sensitive information and their access should be carefully controlled.
13      Although Kubernetes RBAC can be effective at restricting them in several ways,
14      it lacks the ability to use wildcards in resource names. This policy ensures
15      that only Secrets beginning with the name `safe-` can be consumed by Pods.
16      In order to work effectively, this policy needs to be paired with a separate policy
17      or rule to require `automountServiceAccountToken=false` since this would otherwise
18      result in a Secret being mounted.
19spec:
20  background: false
21  validationFailureAction: Audit
22  rules:
23  - name: safe-secrets-from-env
24    match:
25      any:
26      - resources:
27          kinds:
28          - Pod
29          operations:
30          - CREATE
31          - UPDATE
32    validate:
33      cel:
34        variables:
35          - name: allContainers
36            expression: "object.spec.containers + object.spec.?initContainers.orValue([]) + object.spec.?ephemeralContainers.orValue([])"
37        expressions: 
38          - expression: >-
39              variables.allContainers.all(container, 
40              container.?env.orValue([]).all(env,
41              env.?valueFrom.?secretKeyRef.?name.orValue('safe-').startsWith("safe-")))
42            message: "Only Secrets beginning with `safe-` may be consumed in env statements."
43  - name: safe-secrets-from-envfrom
44    match:
45      any:
46      - resources:
47          kinds:
48          - Pod
49          operations:
50          - CREATE
51          - UPDATE
52    validate:
53      cel:
54        variables:
55          - name: allContainers
56            expression: "object.spec.containers + object.spec.?initContainers.orValue([]) + object.spec.?ephemeralContainers.orValue([])"
57        expressions: 
58          - expression: >-
59              variables.allContainers.all(container, 
60              container.?envFrom.orValue([]).all(env,
61              env.?secretRef.?name.orValue('safe-').startsWith("safe-")))
62            message: "Only Secrets beginning with `safe-` may be consumed in envFrom statements."
63  - name: safe-secrets-from-volumes
64    match:
65      any:
66      - resources:
67          kinds:
68          - Pod
69          operations:
70          - CREATE
71          - UPDATE
72    validate:
73      cel:
74        expressions:
75          - expression: >-
76              object.spec.?volumes.orValue([]).all(volume,
77              volume.?secret.?secretName.orValue('safe-').startsWith("safe-"))
78            message: "Only Secrets beginning with `safe-` may be consumed in volumes."