All Policies
Record Creation Details
Kubernetes by default does not make a record of who or what created a resource in that resource itself. It must be retrieved from an audit log, if enabled, which can make it difficult for cluster operators to know who was responsible for an object's creation. This policy writes an annotation with the key `kyverno.io/created-by` having all the userInfo fields present in the AdmissionReview request for any object being created. It then protects this annotation from tampering or removal making it immutable. Although this policy matches on all kinds ("*") it is highly recommend to more narrowly scope it to only the resources which should be labeled.
Policy Definition
/other/record-creation-details/record-creation-details.yaml
1apiVersion: kyverno.io/v1
2kind: ClusterPolicy
3metadata:
4 name: record-creation-details
5 annotations:
6 policies.kyverno.io/title: Record Creation Details
7 policies.kyverno.io/category: other
8 policies.kyverno.io/severity: medium
9 kyverno.io/kyverno-version: 1.6.2
10 policies.kyverno.io/minversion: 1.6.0
11 kyverno.io/kubernetes-version: "1.23"
12 policies.kyverno.io/subject: Annotation
13 policies.kyverno.io/description: >-
14 Kubernetes by default does not make a record of who or what
15 created a resource in that resource itself. It must be retrieved from
16 an audit log, if enabled, which can make it difficult for cluster
17 operators to know who was responsible for an object's creation.
18 This policy writes an annotation with the key `kyverno.io/created-by`
19 having all the userInfo fields present in the AdmissionReview request
20 for any object being created. It then protects this annotation from
21 tampering or removal making it immutable. Although this policy matches on
22 all kinds ("*") it is highly recommend to more narrowly scope it to only
23 the resources which should be labeled.
24spec:
25 validationFailureAction: enforce
26 background: false
27 rules:
28 - name: add-userinfo
29 match:
30 any:
31 - resources:
32 kinds:
33 - '*'
34 preconditions:
35 any:
36 - key: "{{request.operation || 'BACKGROUND'}}"
37 operator: Equals
38 value: CREATE
39 mutate:
40 patchStrategicMerge:
41 metadata:
42 annotations:
43 kyverno.io/created-by: "{{ request.userInfo | to_string(@) }}"
44 - name: prevent-updates-userinfo
45 match:
46 any:
47 - resources:
48 kinds:
49 - '*'
50 annotations:
51 kyverno.io/created-by: "?*"
52 preconditions:
53 any:
54 - key: "{{request.operation || 'BACKGROUND'}}"
55 operator: Equals
56 value: UPDATE
57 validate:
58 message: The annotation kyverno.io/created-by is protected and may not be altered.
59 deny:
60 conditions:
61 all:
62 - key: "{{ request.object.metadata.annotations.\"kyverno.io/created-by\" || '' }}"
63 operator: NotEquals
64 value: ""
65 - key: "{{ request.object.metadata.annotations.\"kyverno.io/created-by\" || '' }}"
66 operator: NotEquals
67 value: "{{ request.oldObject.metadata.annotations.\"kyverno.io/created-by\" }}"
68 - name: prevent-removals-userinfo
69 match:
70 any:
71 - resources:
72 kinds:
73 - '*'
74 annotations:
75 kyverno.io/created-by: "?*"
76 preconditions:
77 all:
78 - key: "{{request.operation || 'BACKGROUND'}}"
79 operator: Equals
80 value: UPDATE
81 - key: "{{ request.oldObject.metadata.annotations.\"kyverno.io/created-by\" || '' }}"
82 operator: Equals
83 value: "?*"
84 validate:
85 message: The annotation kyverno.io/created-by is protected and may not removed.
86 pattern:
87 metadata:
88 annotations:
89 kyverno.io/created-by: "?*"