Repository: kubernetes-sigs/security-profiles-operator
Pull request #499 (2021-06-23 15:07:18)

Make log enricher work with containerd
#### What type of PR is this?

/kind feature

#### What this PR does / why we need it:
This should make the CRI-O requirement obsolete and also work on containerd.
#### Which issue(s) this PR fixes:

<!--
*Automatically closes linked issue when PR is merged.
Usage: `Fixes #<issue number>`, or `Fixes (paste link of issue)`.

Fixes #

or

None
-->
None
#### Does this PR have test?
None
<!--
If tests aren't applicable just write N/A.
-->

#### Special notes for your reviewer:
None
#### Does this PR introduce a user-facing change?

<!--
If no, just write "NONE" in the release-note block below.
If yes, a release note is required:
Enter your extended release note in the block below. If the PR requires additional action from users switching to the new release, include the string "action required".

For more information on release notes see: https://git.k8s.io/community/contributors/guide/release-notes.md
-->

```release-note
None
```


k8s-ci-robot: [APPROVALNOTIFIER] This PR is **APPROVED**

This pull-request has been approved by: *<a href="https://github.com/kubernetes-sigs/security-profiles-operator/pull/499#" title="Author self-approved">saschagrunert</a>*

The full list of commands accepted by this bot can be found [here](https://go.k8s.io/bot-commands?repo=kubernetes-sigs%2Fsecurity-profiles-operator).

The pull request process is described [here](https://git.k8s.io/community/contributors/guide/owners.md#the-code-review-process)

<details >
Needs approval from an approver in each of these files:

- ~~[OWNERS](https://github.com/kubernetes-sigs/security-profiles-operator/blob/master/OWNERS)~~ [saschagrunert]

Approvers can indicate their approval by writing `/approve` in a comment
Approvers can cancel approval by writing `/approve cancel` in a comment
</details>
<!-- META={"approvers":[]} -->
k8s-ci-robot: @saschagrunert: The following test **failed**, say `/retest` to rerun all failed tests:

Test name | Commit | Details | Rerun command
--- | --- | --- | ---
pull-security-profiles-operator-test-unit | eeb727f8848be84a46c9877dff972b61679f0ce5 | [link](https://prow.k8s.io/view/gs/kubernetes-jenkins/pr-logs/pull/kubernetes-sigs_security-profiles-operator/499/pull-security-profiles-operator-test-unit/1407716905476689920) | `/test pull-security-profiles-operator-test-unit`

[Full PR test history](https://prow.k8s.io/pr-history?org=kubernetes-sigs&repo=security-profiles-operator&pr=499). [Your PR dashboard](https://prow.k8s.io/pr?query=is%3Apr%20state%3Aopen%20author%3Asaschagrunert). Please help us cut down on flakes by [linking to](https://git.k8s.io/community/contributors/devel/sig-testing/flaky-tests.md#filing-issues-for-flaky-tests) an [open issue](https://github.com/kubernetes-sigs/security-profiles-operator/issues?q=is:issue+is:open) when you hit one in your PR.

<details>

Instructions for interacting with me using PR comments are available [here](https://git.k8s.io/community/contributors/guide/pull-requests.md).  If you have questions or suggestions related to my behavior, please file an issue against the [kubernetes/test-infra](https://github.com/kubernetes/test-infra/issues/new?title=Prow%20issue:) repository. I understand the commands that are listed [here](https://go.k8s.io/bot-commands).
</details>
<!-- test report -->
codecov-commenter: # [Codecov](https://codecov.io/gh/kubernetes-sigs/security-profiles-operator/pull/499?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None) Report
> Merging [#499](https://codecov.io/gh/kubernetes-sigs/security-profiles-operator/pull/499?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None) (adacc3a) into [master](https://codecov.io/gh/kubernetes-sigs/security-profiles-operator/commit/980a29ec6c9595ab2f46eb006ea436d0d19f437a?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None) (980a29e) will **decrease** coverage by `0.42%`.
> The diff coverage is `14.28%`.


```diff
@@            Coverage Diff             @@
##           master     #499      +/-   ##
==========================================
- Coverage   38.25%   37.82%   -0.43%     
==========================================
  Files          23       23              
  Lines        1200     1203       +3     
==========================================
- Hits          459      455       -4     
- Misses        726      733       +7     
  Partials       15       15              
```

k8s-ci-robot: @saschagrunert: The following test **failed**, say `/retest` to rerun all failed tests:

Test name | Commit | Details | Rerun command
--- | --- | --- | ---
pull-security-profiles-operator-verify | 2ede5486e96ac6639e6fd992cdea6e84b6b4f97a | [link](https://prow.k8s.io/view/gs/kubernetes-jenkins/pr-logs/pull/kubernetes-sigs_security-profiles-operator/499/pull-security-profiles-operator-verify/1407721818235604992) | `/test pull-security-profiles-operator-verify`

[Full PR test history](https://prow.k8s.io/pr-history?org=kubernetes-sigs&repo=security-profiles-operator&pr=499). [Your PR dashboard](https://prow.k8s.io/pr?query=is%3Apr%20state%3Aopen%20author%3Asaschagrunert). Please help us cut down on flakes by [linking to](https://git.k8s.io/community/contributors/devel/sig-testing/flaky-tests.md#filing-issues-for-flaky-tests) an [open issue](https://github.com/kubernetes-sigs/security-profiles-operator/issues?q=is:issue+is:open) when you hit one in your PR.

<details>

Instructions for interacting with me using PR comments are available [here](https://git.k8s.io/community/contributors/guide/pull-requests.md).  If you have questions or suggestions related to my behavior, please file an issue against the [kubernetes/test-infra](https://github.com/kubernetes/test-infra/issues/new?title=Prow%20issue:) repository. I understand the commands that are listed [here](https://go.k8s.io/bot-commands).
</details>
<!-- test report -->
saschagrunert: Have to verify that it actually works. 
saschagrunert: Tested in ubuntu, microk8s and installed auditd:
```
I0624 08:16:33.540285   39923 enricher.go:111] log-enricher "msg"="audit"  "container"="log-container" "executable"="/usr/sbin/nginx" "namespace"="security-profiles-operator" "node"="ubuntu-hirsute" "pid"=43313 "pod"="log-pod" "syscallID"=16 "syscallName"="ioctl" "timestamp"="1624522556.801:3021" "type"="seccomp"
I0624 08:16:33.551466   39923 enricher.go:111] log-enricher "msg"="audit"  "container"="log-container" "executable"="/usr/sbin/nginx" "namespace"="security-profiles-operator" "node"="ubuntu-hirsute" "pid"=43311 "pod"="log-pod" "syscallID"=3 "syscallName"="close" "timestamp"="1624522556.801:3022" "type"="seccomp"
I0624 08:16:33.560159   39923 enricher.go:111] log-enricher "msg"="audit"  "container"="log-container" "executable"="/usr/sbin/nginx" "namespace"="security-profiles-operator" "node"="ubuntu-hirsute" "pid"=43313 "pod"="log-pod" "syscallID"=206 "syscallName"="io_setup" "timestamp"="1624522556.801:3023" "type"="seccomp"
I0624 08:16:33.638312   39923 enricher.go:111] log-enricher "msg"="audit"  "container"="log-container" "executable"="/usr/sbin/nginx" "namespace"="security-profiles-operator" "node"="ubuntu-hirsute" "pid"=43311 "pod"="log-pod" "syscallID"=233 "syscallName"="epoll_ctl" "timestamp"="1624522556.801:3024" "type"="seccomp"
I0624 08:16:33.656041   39923 enricher.go:111] log-enricher "msg"="audit"  "container"="log-container" "executable"="/usr/sbin/nginx" "namespace"="security-profiles-operator" "node"="ubuntu-hirsute" "pid"=43311 "pod"="log-pod" "syscallID"=232 "syscallName"="epoll_wait" "timestamp"="1624522556.801:3025" "type"="seccomp"
I0624 08:16:33.665089   39923 enricher.go:111] log-enricher "msg"="audit"  "container"="log-container" "executable"="/usr/sbin/nginx" "namespace"="security-profiles-operator" "node"="ubuntu-hirsute" "pid"=43313 "pod"="log-pod" "syscallID"=233 "syscallName"="epoll_ctl" "timestamp"="1624522556.801:3026" "type"="seccomp"
```
k8s-ci-robot: @saschagrunert: The following test **failed**, say `/retest` to rerun all failed tests:

Test name | Commit | Details | Rerun command
--- | --- | --- | ---
pull-security-profiles-operator-test-e2e | 5b02a88c34d376ecc8da8da739f7528d4db19abd | [link](https://prow.k8s.io/view/gs/kubernetes-jenkins/pr-logs/pull/kubernetes-sigs_security-profiles-operator/499/pull-security-profiles-operator-test-e2e/1407976401851650048) | `/test pull-security-profiles-operator-test-e2e`

[Full PR test history](https://prow.k8s.io/pr-history?org=kubernetes-sigs&repo=security-profiles-operator&pr=499). [Your PR dashboard](https://prow.k8s.io/pr?query=is%3Apr%20state%3Aopen%20author%3Asaschagrunert). Please help us cut down on flakes by [linking to](https://git.k8s.io/community/contributors/devel/sig-testing/flaky-tests.md#filing-issues-for-flaky-tests) an [open issue](https://github.com/kubernetes-sigs/security-profiles-operator/issues?q=is:issue+is:open) when you hit one in your PR.

<details>

Instructions for interacting with me using PR comments are available [here](https://git.k8s.io/community/contributors/guide/pull-requests.md).  If you have questions or suggestions related to my behavior, please file an issue against the [kubernetes/test-infra](https://github.com/kubernetes/test-infra/issues/new?title=Prow%20issue:) repository. I understand the commands that are listed [here](https://go.k8s.io/bot-commands).
</details>
<!-- test report -->
saschagrunert: /test pull-security-profiles-operator-test-e2e
k8s-ci-robot: @saschagrunert: The following test **failed**, say `/retest` to rerun all failed tests:

Test name | Commit | Details | Rerun command
--- | --- | --- | ---
pull-security-profiles-operator-test-e2e | 5b02a88c34d376ecc8da8da739f7528d4db19abd | [link](https://prow.k8s.io/view/gs/kubernetes-jenkins/pr-logs/pull/kubernetes-sigs_security-profiles-operator/499/pull-security-profiles-operator-test-e2e/1407980893905096704) | `/test pull-security-profiles-operator-test-e2e`

[Full PR test history](https://prow.k8s.io/pr-history?org=kubernetes-sigs&repo=security-profiles-operator&pr=499). [Your PR dashboard](https://prow.k8s.io/pr?query=is%3Apr%20state%3Aopen%20author%3Asaschagrunert). Please help us cut down on flakes by [linking to](https://git.k8s.io/community/contributors/devel/sig-testing/flaky-tests.md#filing-issues-for-flaky-tests) an [open issue](https://github.com/kubernetes-sigs/security-profiles-operator/issues?q=is:issue+is:open) when you hit one in your PR.

<details>

Instructions for interacting with me using PR comments are available [here](https://git.k8s.io/community/contributors/guide/pull-requests.md).  If you have questions or suggestions related to my behavior, please file an issue against the [kubernetes/test-infra](https://github.com/kubernetes/test-infra/issues/new?title=Prow%20issue:) repository. I understand the commands that are listed [here](https://go.k8s.io/bot-commands).
</details>
<!-- test report -->
saschagrunert: /retest
k8s-ci-robot: @saschagrunert: The following test **failed**, say `/retest` to rerun all failed tests:

Test name | Commit | Details | Rerun command
--- | --- | --- | ---
pull-security-profiles-operator-test-e2e | 5b02a88c34d376ecc8da8da739f7528d4db19abd | [link](https://prow.k8s.io/view/gs/kubernetes-jenkins/pr-logs/pull/kubernetes-sigs_security-profiles-operator/499/pull-security-profiles-operator-test-e2e/1407984928259313664) | `/test pull-security-profiles-operator-test-e2e`

[Full PR test history](https://prow.k8s.io/pr-history?org=kubernetes-sigs&repo=security-profiles-operator&pr=499). [Your PR dashboard](https://prow.k8s.io/pr?query=is%3Apr%20state%3Aopen%20author%3Asaschagrunert). Please help us cut down on flakes by [linking to](https://git.k8s.io/community/contributors/devel/sig-testing/flaky-tests.md#filing-issues-for-flaky-tests) an [open issue](https://github.com/kubernetes-sigs/security-profiles-operator/issues?q=is:issue+is:open) when you hit one in your PR.

<details>

Instructions for interacting with me using PR comments are available [here](https://git.k8s.io/community/contributors/guide/pull-requests.md).  If you have questions or suggestions related to my behavior, please file an issue against the [kubernetes/test-infra](https://github.com/kubernetes/test-infra/issues/new?title=Prow%20issue:) repository. I understand the commands that are listed [here](https://go.k8s.io/bot-commands).
</details>
<!-- test report -->
saschagrunert: /test pull-security-profiles-operator-test-e2e

Patch:
diff --git a/api/profilebinding/v1alpha1/profilebinding_types.go b/api/profilebinding/v1alpha1/profilebinding_types.go
index 62ef8db75..1c1a98cdc 100644
--- a/api/profilebinding/v1alpha1/profilebinding_types.go
+++ b/api/profilebinding/v1alpha1/profilebinding_types.go
@@ -20,6 +20,12 @@ import (
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 )
 
+type ProfileBindingKind string
+
+const (
+	ProfileBindingKindSeccompProfile ProfileBindingKind = "SeccompProfile"
+)
+
 // ProfileBindingSpec defines the desired state of ProfileBinding.
 type ProfileBindingSpec struct {
 	// ProfileRef references a SeccompProfile or other profile type in the current namespace.
@@ -32,7 +38,7 @@ type ProfileBindingSpec struct {
 type ProfileRef struct {
 	// Kind of object to be bound.
 	// +kubebuilder:validation:Enum=SeccompProfile
-	Kind string `json:"kind"` // TODO(cmurphy) add SelinuxProfile
+	Kind ProfileBindingKind `json:"kind"` // TODO(cmurphy) add SelinuxProfile
 	// Name of the profile within the current namespace to which to bind the selected pods.
 	Name string `json:"name"`
 }
diff --git a/api/profilerecording/v1alpha1/profilerecording_types.go b/api/profilerecording/v1alpha1/profilerecording_types.go
index 9e9cd4abd..f908b4100 100644
--- a/api/profilerecording/v1alpha1/profilerecording_types.go
+++ b/api/profilerecording/v1alpha1/profilerecording_types.go
@@ -20,11 +20,17 @@ import (
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 )
 
+type ProfileRecordingKind string
+
+const (
+	ProfileRecordingKindSeccompProfile ProfileRecordingKind = "SeccompProfile"
+)
+
 // ProfileRecordingSpec defines the desired state of ProfileRecording.
 type ProfileRecordingSpec struct {
 	// Kind of object to be recorded.
 	// +kubebuilder:validation:Enum=SeccompProfile
-	Kind string `json:"kind"`
+	Kind ProfileRecordingKind `json:"kind"`
 
 	// PodSelector selects the pods to record. This field follows standard
 	// label selector semantics. An empty podSelector matches all pods in this
diff --git a/go.mod b/go.mod
index 6fd75f112..a659fe6a5 100644
--- a/go.mod
+++ b/go.mod
@@ -16,7 +16,7 @@ require (
 	github.com/urfave/cli/v2 v2.3.0
 	google.golang.org/grpc v1.38.0
 	google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0
-	google.golang.org/protobuf v1.26.0
+	google.golang.org/protobuf v1.27.0
 	k8s.io/api v0.20.6
 	k8s.io/apimachinery v0.21.2
 	k8s.io/client-go v0.20.6
diff --git a/go.sum b/go.sum
index edc1ab747..5c5ca4f5a 100644
--- a/go.sum
+++ b/go.sum
@@ -1367,8 +1367,9 @@ google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpAD
 google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4=
 google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
 google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
-google.golang.org/protobuf v1.26.0 h1:bxAC2xTBsZGibn2RTntX0oH50xLsqy1OxA9tTL3p/lk=
 google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
+google.golang.org/protobuf v1.27.0 h1:KhgSLlr/moiqjv0qUsSnLvdUL7NH7PHW8aZGn7Jpjko=
+google.golang.org/protobuf v1.27.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
 gopkg.in/airbrake/gobrake.v2 v2.0.9/go.mod h1:/h5ZAUhDkGaJfjzjKLSjv6zCL6O0LLBxU4K+aSYdM/U=
 gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
 gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
diff --git a/installation-usage.md b/installation-usage.md
index f1d5ebea5..fd2bd5c98 100644
--- a/installation-usage.md
+++ b/installation-usage.md
@@ -558,7 +558,6 @@ within host PID namespace (`hostPID`).
 Further requirements to the Kubernetes node have to be fulfilled to use the log
 enrichment feature:
 
-- [CRI-O][cri-o] has to be the container runtime
 - [auditd][auditd] needs to run and has to be configured to log into
   `/var/log/audit/audit.log`
 
diff --git a/internal/pkg/daemon/enricher/container.go b/internal/pkg/daemon/enricher/container.go
index 8a96f2ce3..681eb64bb 100644
--- a/internal/pkg/daemon/enricher/container.go
+++ b/internal/pkg/daemon/enricher/container.go
@@ -23,7 +23,6 @@ import (
 	"os"
 	"path/filepath"
 	"regexp"
-	"strings"
 
 	"github.com/go-logr/logr"
 	"github.com/pkg/errors"
@@ -34,11 +33,6 @@ import (
 	"sigs.k8s.io/security-profiles-operator/internal/pkg/util"
 )
 
-const (
-	crioCgroupRegex = `\/.+-([a-f0-9]+)`
-	crioPrefix      = "cri-o://"
-)
-
 // NOTE(jaosorior): Should this actually be namespace-scoped?
 //
 // Cluster scoped
@@ -81,8 +75,8 @@ func getNodeContainers(logger logr.Logger, nodeName string) (map[string]containe
 						return errContainerIDEmpty
 					}
 
-					rawContainerID, err := containerIDRaw(containerID)
-					if err != nil {
+					rawContainerID := regexID.FindString(containerID)
+					if rawContainerID == "" {
 						logger.Error(
 							err, "unable to get container ID",
 							"containerName", pod.Name,
@@ -107,14 +101,6 @@ func getNodeContainers(logger logr.Logger, nodeName string) (map[string]containe
 	return containers, err
 }
 
-func containerIDRaw(containerID string) (string, error) {
-	if strings.Contains(containerID, crioPrefix) {
-		return strings.TrimPrefix(containerID, crioPrefix), nil
-	}
-
-	return "", errors.Wrap(errUnsupportedContainerRuntime, containerID)
-}
-
 func getContainerID(processID int) (string, error) {
 	cgroupFile := fmt.Sprintf("/proc/%d/cgroup", processID)
 	file, err := os.Open(filepath.Clean(cgroupFile))
@@ -139,12 +125,9 @@ func getContainerID(processID int) (string, error) {
 	return "", errors.New("unable to find container ID from cgroup path")
 }
 
-func extractID(cgroup string) string {
-	containerIDRegex := regexp.MustCompile(crioCgroupRegex)
-	capture := containerIDRegex.FindStringSubmatch(cgroup)
-	if len(capture) > 1 {
-		return capture[1]
-	}
+// We assume that a container ID has a length of 64.
+var regexID = regexp.MustCompile(`[0-9a-f]{64}`)
 
-	return ""
+func extractID(cgroup string) string {
+	return regexID.FindString(cgroup)
 }
diff --git a/internal/pkg/daemon/enricher/enricher.go b/internal/pkg/daemon/enricher/enricher.go
index 22dbb4ee0..c9862699a 100644
--- a/internal/pkg/daemon/enricher/enricher.go
+++ b/internal/pkg/daemon/enricher/enricher.go
@@ -85,11 +85,6 @@ func Run(logger logr.Logger) error {
 			continue
 		}
 
-		if auditLine.SystemCallID == 0 {
-			logger.Info("Audit line SystemCallID is 0, skipping")
-			continue
-		}
-
 		cID, err := getContainerID(auditLine.ProcessID)
 		if err != nil {
 			logger.Error(err, "unable to get container ID", "processID", auditLine.ProcessID)
diff --git a/internal/pkg/daemon/enricher/types.go b/internal/pkg/daemon/enricher/types.go
index c7dc88b14..aa1f4ee9d 100644
--- a/internal/pkg/daemon/enricher/types.go
+++ b/internal/pkg/daemon/enricher/types.go
@@ -19,9 +19,8 @@ package enricher
 import "errors"
 
 var (
-	errUnsupportedContainerRuntime = errors.New("unsupported container runtime")
-	errUnsupportedLogLine          = errors.New("unsupported log line")
-	errContainerIDEmpty            = errors.New("container ID is empty")
+	errUnsupportedLogLine = errors.New("unsupported log line")
+	errContainerIDEmpty   = errors.New("container ID is empty")
 )
 
 const (
diff --git a/internal/pkg/webhooks/binding/binding.go b/internal/pkg/webhooks/binding/binding.go
index 6f3db0477..49093e8f2 100644
--- a/internal/pkg/webhooks/binding/binding.go
+++ b/internal/pkg/webhooks/binding/binding.go
@@ -118,7 +118,7 @@ func (p *podSeccompBinder) Handle(ctx context.Context, req admission.Request) ad
 
 	for i := range profilebindings {
 		// TODO(cmurphy): handle profiles kinds other than SeccompProfile
-		if profilebindings[i].Spec.ProfileRef.Kind != "SeccompProfile" {
+		if profilebindings[i].Spec.ProfileRef.Kind != profilebindingv1alpha1.ProfileBindingKindSeccompProfile {
 			p.log.Info(fmt.Sprintf("profile kind %s not yet supported", profilebindings[i].Spec.ProfileRef.Kind))
 			continue
 		}
diff --git a/internal/pkg/webhooks/recording/recording.go b/internal/pkg/webhooks/recording/recording.go
index fc54b4bae..60de139f3 100644
--- a/internal/pkg/webhooks/recording/recording.go
+++ b/internal/pkg/webhooks/recording/recording.go
@@ -111,7 +111,7 @@ func (p *podSeccompRecorder) Handle(
 
 	for i := range items {
 		item := items[i]
-		if item.Spec.Kind != "SeccompProfile" {
+		if item.Spec.Kind != profilerecordingv1alpha1.ProfileRecordingKindSeccompProfile {
 			p.log.Info(fmt.Sprintf(
 				"recording kind %s not supported", item.Spec.Kind,
 			))
diff --git a/vendor/google.golang.org/protobuf/cmd/protoc-gen-go/internal_gengo/main.go b/vendor/google.golang.org/protobuf/cmd/protoc-gen-go/internal_gengo/main.go
index 6338c44dc..6372ad4e1 100644
--- a/vendor/google.golang.org/protobuf/cmd/protoc-gen-go/internal_gengo/main.go
+++ b/vendor/google.golang.org/protobuf/cmd/protoc-gen-go/internal_gengo/main.go
@@ -128,6 +128,9 @@ func genGeneratedHeader(gen *protogen.Plugin, g *protogen.GeneratedFile, f *file
 		protocVersion := "(unknown)"
 		if v := gen.Request.GetCompilerVersion(); v != nil {
 			protocVersion = fmt.Sprintf("v%v.%v.%v", v.GetMajor(), v.GetMinor(), v.GetPatch())
+			if s := v.GetSuffix(); s != "" {
+				protocVersion += "-" + s
+			}
 		}
 		g.P("// \tprotoc-gen-go ", protocGenGoVersion)
 		g.P("// \tprotoc        ", protocVersion)
@@ -444,7 +447,15 @@ func genMessageDefaultDecls(g *protogen.GeneratedFile, f *fileInfo, m *messageIn
 		case protoreflect.EnumKind:
 			idx := field.Desc.DefaultEnumValue().Index()
 			val := field.Enum.Values[idx]
-			consts = append(consts, fmt.Sprintf("%s = %s", name, g.QualifiedGoIdent(val.GoIdent)))
+			if val.GoIdent.GoImportPath == f.GoImportPath {
+				consts = append(consts, fmt.Sprintf("%s = %s", name, g.QualifiedGoIdent(val.GoIdent)))
+			} else {
+				// If the enum value is declared in a different Go package,
+				// reference it by number since the name may not be correct.
+				// See https://github.com/golang/protobuf/issues/513.
+				consts = append(consts, fmt.Sprintf("%s = %s(%d) // %s",
+					name, g.QualifiedGoIdent(field.Enum.GoIdent), val.Desc.Number(), g.QualifiedGoIdent(val.GoIdent)))
+			}
 		case protoreflect.FloatKind, protoreflect.DoubleKind:
 			if f := defVal.Float(); math.IsNaN(f) || math.IsInf(f, 0) {
 				var fn, arg string
@@ -527,25 +538,6 @@ func genMessageBaseMethods(g *protogen.GeneratedFile, f *fileInfo, m *messageInf
 		g.P()
 		f.needRawDesc = true
 	}
-
-	// ExtensionRangeArray method.
-	extRanges := m.Desc.ExtensionRanges()
-	if m.genExtRangeMethod && extRanges.Len() > 0 {
-		protoExtRange := protoifacePackage.Ident("ExtensionRangeV1")
-		extRangeVar := "extRange_" + m.GoIdent.GoName
-		g.P("var ", extRangeVar, " = []", protoExtRange, " {")
-		for i := 0; i < extRanges.Len(); i++ {
-			r := extRanges.Get(i)
-			g.P("{Start:", r[0], ", End:", r[1]-1 /* inclusive */, "},")
-		}
-		g.P("}")
-		g.P()
-		g.P("// Deprecated: Use ", m.GoIdent, ".ProtoReflect.Descriptor.ExtensionRanges instead.")
-		g.P("func (*", m.GoIdent, ") ExtensionRangeArray() []", protoExtRange, " {")
-		g.P("return ", extRangeVar)
-		g.P("}")
-		g.P()
-	}
 }
 
 func genMessageGetterMethods(g *protogen.GeneratedFile, f *fileInfo, m *messageInfo) {
@@ -566,7 +558,7 @@ func genMessageGetterMethods(g *protogen.GeneratedFile, f *fileInfo, m *messageI
 
 		// Getter for message field.
 		goType, pointer := fieldGoType(g, f, field)
-		defaultValue := fieldDefaultValue(g, m, field)
+		defaultValue := fieldDefaultValue(g, f, m, field)
 		g.Annotate(m.GoIdent.GoName+".Get"+field.GoName, field.Location)
 		leadingComments := appendDeprecationSuffix("",
 			field.Desc.Options().(*descriptorpb.FieldOptions).GetDeprecated())
@@ -688,7 +680,7 @@ func fieldProtobufTagValue(field *protogen.Field) string {
 	return tag.Marshal(field.Desc, enumName)
 }
 
-func fieldDefaultValue(g *protogen.GeneratedFile, m *messageInfo, field *protogen.Field) string {
+func fieldDefaultValue(g *protogen.GeneratedFile, f *fileInfo, m *messageInfo, field *protogen.Field) string {
 	if field.Desc.IsList() {
 		return "nil"
 	}
@@ -707,7 +699,15 @@ func fieldDefaultValue(g *protogen.GeneratedFile, m *messageInfo, field *protoge
 	case protoreflect.MessageKind, protoreflect.GroupKind, protoreflect.BytesKind:
 		return "nil"
 	case protoreflect.EnumKind:
-		return g.QualifiedGoIdent(field.Enum.Values[0].GoIdent)
+		val := field.Enum.Values[0]
+		if val.GoIdent.GoImportPath == f.GoImportPath {
+			return g.QualifiedGoIdent(val.GoIdent)
+		} else {
+			// If the enum value is declared in a different Go package,
+			// reference it by number since the name may not be correct.
+			// See https://github.com/golang/protobuf/issues/513.
+			return g.QualifiedGoIdent(field.Enum.GoIdent) + "(" + strconv.FormatInt(int64(val.Desc.Number()), 32) + ")"
+		}
 	default:
 		return "0"
 	}
diff --git a/vendor/google.golang.org/protobuf/compiler/protogen/protogen.go b/vendor/google.golang.org/protobuf/compiler/protogen/protogen.go
index 17cbe1a39..2ee676fbb 100644
--- a/vendor/google.golang.org/protobuf/compiler/protogen/protogen.go
+++ b/vendor/google.golang.org/protobuf/compiler/protogen/protogen.go
@@ -251,12 +251,13 @@ func (opts Options) New(req *pluginpb.CodeGeneratorRequest) (*Plugin, error) {
 					"\t• a \"M\" argument on the command line.\n\n"+
 					"See %v for more information.\n",
 				fdesc.GetName(), goPackageDocURL)
-		case !strings.Contains(string(importPaths[filename]), "/"):
-			// Check that import paths contain at least one slash to avoid a
-			// common mistake where import path is confused with package name.
+		case !strings.Contains(string(importPaths[filename]), ".") &&
+			!strings.Contains(string(importPaths[filename]), "/"):
+			// Check that import paths contain at least a dot or slash to avoid
+			// a common mistake where import path is confused with package name.
 			return nil, fmt.Errorf(
 				"invalid Go import path %q for %q\n\n"+
-					"The import path must contain at least one forward slash ('/') character.\n\n"+
+					"The import path must contain at least one period ('.') or forward slash ('/') character.\n\n"+
 					"See %v for more information.\n",
 				string(importPaths[filename]), fdesc.GetName(), goPackageDocURL)
 		case packageNames[filename] == "":
diff --git a/vendor/google.golang.org/protobuf/encoding/prototext/decode.go b/vendor/google.golang.org/protobuf/encoding/prototext/decode.go
index 8fb1d9e08..179d6e8fc 100644
--- a/vendor/google.golang.org/protobuf/encoding/prototext/decode.go
+++ b/vendor/google.golang.org/protobuf/encoding/prototext/decode.go
@@ -744,9 +744,6 @@ func (d decoder) skipValue() error {
 				// Skip items. This will not validate whether skipped values are
 				// of the same type or not, same behavior as C++
 				// TextFormat::Parser::AllowUnknownField(true) version 3.8.0.
-				if err := d.skipValue(); err != nil {
-					return err
-				}
 			}
 		}
 	}
diff --git a/vendor/google.golang.org/protobuf/internal/encoding/text/encode.go b/vendor/google.golang.org/protobuf/internal/encoding/text/encode.go
index aa66bdd06..da289ccce 100644
--- a/vendor/google.golang.org/protobuf/internal/encoding/text/encode.go
+++ b/vendor/google.golang.org/protobuf/internal/encoding/text/encode.go
@@ -263,3 +263,8 @@ func (e *Encoder) Snapshot() encoderState {
 func (e *Encoder) Reset(es encoderState) {
 	e.encoderState = es
 }
+
+// AppendString appends the escaped form of the input string to b.
+func AppendString(b []byte, s string) []byte {
+	return appendString(b, s, false)
+}
diff --git a/vendor/google.golang.org/protobuf/internal/impl/legacy_message.go b/vendor/google.golang.org/protobuf/internal/impl/legacy_message.go
index 3759b010c..029feeefd 100644
--- a/vendor/google.golang.org/protobuf/internal/impl/legacy_message.go
+++ b/vendor/google.golang.org/protobuf/internal/impl/legacy_message.go
@@ -440,6 +440,13 @@ func legacyMerge(in piface.MergeInput) piface.MergeOutput {
 	if !ok {
 		return piface.MergeOutput{}
 	}
+	if !in.Source.IsValid() {
+		// Legacy Marshal methods may not function on nil messages.
+		// Check for a typed nil source only after we confirm that
+		// legacy Marshal/Unmarshal methods are present, for
+		// consistency.
+		return piface.MergeOutput{Flags: piface.MergeComplete}
+	}
 	b, err := marshaler.Marshal()
 	if err != nil {
 		return piface.MergeOutput{}
diff --git a/vendor/google.golang.org/protobuf/internal/version/version.go b/vendor/google.golang.org/protobuf/internal/version/version.go
index 5879131da..a91055769 100644
--- a/vendor/google.golang.org/protobuf/internal/version/version.go
+++ b/vendor/google.golang.org/protobuf/internal/version/version.go
@@ -52,7 +52,7 @@ import (
 //	10. Send out the CL for review and submit it.
 const (
 	Major      = 1
-	Minor      = 26
+	Minor      = 27
 	Patch      = 0
 	PreRelease = ""
 )
diff --git a/vendor/google.golang.org/protobuf/reflect/protoregistry/registry.go b/vendor/google.golang.org/protobuf/reflect/protoregistry/registry.go
index 66dcbcd0d..59f024c44 100644
--- a/vendor/google.golang.org/protobuf/reflect/protoregistry/registry.go
+++ b/vendor/google.golang.org/protobuf/reflect/protoregistry/registry.go
@@ -94,7 +94,8 @@ type Files struct {
 	// Note that enum values are in the top-level since that are in the same
 	// scope as the parent enum.
 	descsByName map[protoreflect.FullName]interface{}
-	filesByPath map[string]protoreflect.FileDescriptor
+	filesByPath map[string][]protoreflect.FileDescriptor
+	numFiles    int
 }
 
 type packageDescriptor struct {
@@ -117,17 +118,16 @@ func (r *Files) RegisterFile(file protoreflect.FileDescriptor) error {
 		r.descsByName = map[protoreflect.FullName]interface{}{
 			"": &packageDescriptor{},
 		}
-		r.filesByPath = make(map[string]protoreflect.FileDescriptor)
+		r.filesByPath = make(map[string][]protoreflect.FileDescriptor)
 	}
 	path := file.Path()
-	if prev := r.filesByPath[path]; prev != nil {
+	if prev := r.filesByPath[path]; len(prev) > 0 {
 		r.checkGenProtoConflict(path)
 		err := errors.New("file %q is already registered", file.Path())
-		err = amendErrorWithCaller(err, prev, file)
-		if r == GlobalFiles && ignoreConflict(file, err) {
-			err = nil
+		err = amendErrorWithCaller(err, prev[0], file)
+		if !(r == GlobalFiles && ignoreConflict(file, err)) {
+			return err
 		}
-		return err
 	}
 
 	for name := file.Package(); name != ""; name = name.Parent() {
@@ -168,7 +168,8 @@ func (r *Files) RegisterFile(file protoreflect.FileDescriptor) error {
 	rangeTopLevelDescriptors(file, func(d protoreflect.Descriptor) {
 		r.descsByName[d.FullName()] = d
 	})
-	r.filesByPath[path] = file
+	r.filesByPath[path] = append(r.filesByPath[path], file)
+	r.numFiles++
 	return nil
 }
 
@@ -308,6 +309,7 @@ func (s *nameSuffix) Pop() (name protoreflect.Name) {
 // FindFileByPath looks up a file by the path.
 //
 // This returns (nil, NotFound) if not found.
+// This returns an error if multiple files have the same path.
 func (r *Files) FindFileByPath(path string) (protoreflect.FileDescriptor, error) {
 	if r == nil {
 		return nil, NotFound
@@ -316,13 +318,19 @@ func (r *Files) FindFileByPath(path string) (protoreflect.FileDescriptor, error)
 		globalMutex.RLock()
 		defer globalMutex.RUnlock()
 	}
-	if fd, ok := r.filesByPath[path]; ok {
-		return fd, nil
+	fds := r.filesByPath[path]
+	switch len(fds) {
+	case 0:
+		return nil, NotFound
+	case 1:
+		return fds[0], nil
+	default:
+		return nil, errors.New("multiple files named %q", path)
 	}
-	return nil, NotFound
 }
 
-// NumFiles reports the number of registered files.
+// NumFiles reports the number of registered files,
+// including duplicate files with the same name.
 func (r *Files) NumFiles() int {
 	if r == nil {
 		return 0
@@ -331,10 +339,11 @@ func (r *Files) NumFiles() int {
 		globalMutex.RLock()
 		defer globalMutex.RUnlock()
 	}
-	return len(r.filesByPath)
+	return r.numFiles
 }
 
 // RangeFiles iterates over all registered files while f returns true.
+// If multiple files have the same name, RangeFiles iterates over all of them.
 // The iteration order is undefined.
 func (r *Files) RangeFiles(f func(protoreflect.FileDescriptor) bool) {
 	if r == nil {
@@ -344,9 +353,11 @@ func (r *Files) RangeFiles(f func(protoreflect.FileDescriptor) bool) {
 		globalMutex.RLock()
 		defer globalMutex.RUnlock()
 	}
-	for _, file := range r.filesByPath {
-		if !f(file) {
-			return
+	for _, files := range r.filesByPath {
+		for _, file := range files {
+			if !f(file) {
+				return
+			}
 		}
 	}
 }
diff --git a/vendor/google.golang.org/protobuf/types/descriptorpb/descriptor.pb.go b/vendor/google.golang.org/protobuf/types/descriptorpb/descriptor.pb.go
index f77239fc3..abe4ab511 100644
--- a/vendor/google.golang.org/protobuf/types/descriptorpb/descriptor.pb.go
+++ b/vendor/google.golang.org/protobuf/types/descriptorpb/descriptor.pb.go
@@ -43,7 +43,6 @@ package descriptorpb
 
 import (
 	protoreflect "google.golang.org/protobuf/reflect/protoreflect"
-	protoiface "google.golang.org/protobuf/runtime/protoiface"
 	protoimpl "google.golang.org/protobuf/runtime/protoimpl"
 	reflect "reflect"
 	sync "sync"
@@ -829,15 +828,6 @@ func (*ExtensionRangeOptions) Descriptor() ([]byte, []int) {
 	return file_google_protobuf_descriptor_proto_rawDescGZIP(), []int{3}
 }
 
-var extRange_ExtensionRangeOptions = []protoiface.ExtensionRangeV1{
-	{Start: 1000, End: 536870911},
-}
-
-// Deprecated: Use ExtensionRangeOptions.ProtoReflect.Descriptor.ExtensionRanges instead.
-func (*ExtensionRangeOptions) ExtensionRangeArray() []protoiface.ExtensionRangeV1 {
-	return extRange_ExtensionRangeOptions
-}
-
 func (x *ExtensionRangeOptions) GetUninterpretedOption() []*UninterpretedOption {
 	if x != nil {
 		return x.UninterpretedOption
@@ -1520,15 +1510,6 @@ func (*FileOptions) Descriptor() ([]byte, []int) {
 	return file_google_protobuf_descriptor_proto_rawDescGZIP(), []int{10}
 }
 
-var extRange_FileOptions = []protoiface.ExtensionRangeV1{
-	{Start: 1000, End: 536870911},
-}
-
-// Deprecated: Use FileOptions.ProtoReflect.Descriptor.ExtensionRanges instead.
-func (*FileOptions) ExtensionRangeArray() []protoiface.ExtensionRangeV1 {
-	return extRange_FileOptions
-}
-
 func (x *FileOptions) GetJavaPackage() string {
 	if x != nil && x.JavaPackage != nil {
 		return *x.JavaPackage
@@ -1776,15 +1757,6 @@ func (*MessageOptions) Descriptor() ([]byte, []int) {
 	return file_google_protobuf_descriptor_proto_rawDescGZIP(), []int{11}
 }
 
-var extRange_MessageOptions = []protoiface.ExtensionRangeV1{
-	{Start: 1000, End: 536870911},
-}
-
-// Deprecated: Use MessageOptions.ProtoReflect.Descriptor.ExtensionRanges instead.
-func (*MessageOptions) ExtensionRangeArray() []protoiface.ExtensionRangeV1 {
-	return extRange_MessageOptions
-}
-
 func (x *MessageOptions) GetMessageSetWireFormat() bool {
 	if x != nil && x.MessageSetWireFormat != nil {
 		return *x.MessageSetWireFormat
@@ -1930,15 +1902,6 @@ func (*FieldOptions) Descriptor() ([]byte, []int) {
 	return file_google_protobuf_descriptor_proto_rawDescGZIP(), []int{12}
 }
 
-var extRange_FieldOptions = []protoiface.ExtensionRangeV1{
-	{Start: 1000, End: 536870911},
-}
-
-// Deprecated: Use FieldOptions.ProtoReflect.Descriptor.ExtensionRanges instead.
-func (*FieldOptions) ExtensionRangeArray() []protoiface.ExtensionRangeV1 {
-	return extRange_FieldOptions
-}
-
 func (x *FieldOptions) GetCtype() FieldOptions_CType {
 	if x != nil && x.Ctype != nil {
 		return *x.Ctype
@@ -2030,15 +1993,6 @@ func (*OneofOptions) Descriptor() ([]byte, []int) {
 	return file_google_protobuf_descriptor_proto_rawDescGZIP(), []int{13}
 }
 
-var extRange_OneofOptions = []protoiface.ExtensionRangeV1{
-	{Start: 1000, End: 536870911},
-}
-
-// Deprecated: Use OneofOptions.ProtoReflect.Descriptor.ExtensionRanges instead.
-func (*OneofOptions) ExtensionRangeArray() []protoiface.ExtensionRangeV1 {
-	return extRange_OneofOptions
-}
-
 func (x *OneofOptions) GetUninterpretedOption() []*UninterpretedOption {
 	if x != nil {
 		return x.UninterpretedOption
@@ -2101,15 +2055,6 @@ func (*EnumOptions) Descriptor() ([]byte, []int) {
 	return file_google_protobuf_descriptor_proto_rawDescGZIP(), []int{14}
 }
 
-var extRange_EnumOptions = []protoiface.ExtensionRangeV1{
-	{Start: 1000, End: 536870911},
-}
-
-// Deprecated: Use EnumOptions.ProtoReflect.Descriptor.ExtensionRanges instead.
-func (*EnumOptions) ExtensionRangeArray() []protoiface.ExtensionRangeV1 {
-	return extRange_EnumOptions
-}
-
 func (x *EnumOptions) GetAllowAlias() bool {
 	if x != nil && x.AllowAlias != nil {
 		return *x.AllowAlias
@@ -2183,15 +2128,6 @@ func (*EnumValueOptions) Descriptor() ([]byte, []int) {
 	return file_google_protobuf_descriptor_proto_rawDescGZIP(), []int{15}
 }
 
-var extRange_EnumValueOptions = []protoiface.ExtensionRangeV1{
-	{Start: 1000, End: 536870911},
-}
-
-// Deprecated: Use EnumValueOptions.ProtoReflect.Descriptor.ExtensionRanges instead.
-func (*EnumValueOptions) ExtensionRangeArray() []protoiface.ExtensionRangeV1 {
-	return extRange_EnumValueOptions
-}
-
 func (x *EnumValueOptions) GetDeprecated() bool {
 	if x != nil && x.Deprecated != nil {
 		return *x.Deprecated
@@ -2258,15 +2194,6 @@ func (*ServiceOptions) Descriptor() ([]byte, []int) {
 	return file_google_protobuf_descriptor_proto_rawDescGZIP(), []int{16}
 }
 
-var extRange_ServiceOptions = []protoiface.ExtensionRangeV1{
-	{Start: 1000, End: 536870911},
-}
-
-// Deprecated: Use ServiceOptions.ProtoReflect.Descriptor.ExtensionRanges instead.
-func (*ServiceOptions) ExtensionRangeArray() []protoiface.ExtensionRangeV1 {
-	return extRange_ServiceOptions
-}
-
 func (x *ServiceOptions) GetDeprecated() bool {
 	if x != nil && x.Deprecated != nil {
 		return *x.Deprecated
@@ -2335,15 +2262,6 @@ func (*MethodOptions) Descriptor() ([]byte, []int) {
 	return file_google_protobuf_descriptor_proto_rawDescGZIP(), []int{17}
 }
 
-var extRange_MethodOptions = []protoiface.ExtensionRangeV1{
-	{Start: 1000, End: 536870911},
-}
-
-// Deprecated: Use MethodOptions.ProtoReflect.Descriptor.ExtensionRanges instead.
-func (*MethodOptions) ExtensionRangeArray() []protoiface.ExtensionRangeV1 {
-	return extRange_MethodOptions
-}
-
 func (x *MethodOptions) GetDeprecated() bool {
 	if x != nil && x.Deprecated != nil {
 		return *x.Deprecated
diff --git a/vendor/modules.txt b/vendor/modules.txt
index 9a15f06de..97379ec81 100644
--- a/vendor/modules.txt
+++ b/vendor/modules.txt
@@ -412,7 +412,7 @@ google.golang.org/grpc/tap
 # google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0
 ## explicit
 google.golang.org/grpc/cmd/protoc-gen-go-grpc
-# google.golang.org/protobuf v1.26.0
+# google.golang.org/protobuf v1.27.0
 ## explicit
 google.golang.org/protobuf/cmd/protoc-gen-go
 google.golang.org/protobuf/cmd/protoc-gen-go/internal_gengo


Test patch:
diff --git a/internal/pkg/webhooks/binding/binding_test.go b/internal/pkg/webhooks/binding/binding_test.go
index 6e37e303a..6f7ef7ef6 100644
--- a/internal/pkg/webhooks/binding/binding_test.go
+++ b/internal/pkg/webhooks/binding/binding_test.go
@@ -98,7 +98,7 @@ func TestHandle(t *testing.T) {
 						{
 							Spec: v1alpha1.ProfileBindingSpec{
 								ProfileRef: v1alpha1.ProfileRef{
-									Kind: "SeccompProfile",
+									Kind: v1alpha1.ProfileBindingKindSeccompProfile,
 								},
 							},
 						},
@@ -174,7 +174,7 @@ func TestHandle(t *testing.T) {
 						{
 							Spec: v1alpha1.ProfileBindingSpec{
 								ProfileRef: v1alpha1.ProfileRef{
-									Kind: "SeccompProfile",
+									Kind: v1alpha1.ProfileBindingKindSeccompProfile,
 								},
 							},
 						},
@@ -207,7 +207,7 @@ func TestHandle(t *testing.T) {
 						{
 							Spec: v1alpha1.ProfileBindingSpec{
 								ProfileRef: v1alpha1.ProfileRef{
-									Kind: "SeccompProfile",
+									Kind: v1alpha1.ProfileBindingKindSeccompProfile,
 								},
 							},
 						},
@@ -239,7 +239,7 @@ func TestHandle(t *testing.T) {
 						{
 							Spec: v1alpha1.ProfileBindingSpec{
 								ProfileRef: v1alpha1.ProfileRef{
-									Kind: "SeccompProfile",
+									Kind: v1alpha1.ProfileBindingKindSeccompProfile,
 								},
 							},
 						},
@@ -278,7 +278,7 @@ func TestHandle(t *testing.T) {
 						{
 							Spec: v1alpha1.ProfileBindingSpec{
 								ProfileRef: v1alpha1.ProfileRef{
-									Kind: "SeccompProfile",
+									Kind: v1alpha1.ProfileBindingKindSeccompProfile,
 								},
 							},
 						},
@@ -316,7 +316,7 @@ func TestHandle(t *testing.T) {
 						{
 							Spec: v1alpha1.ProfileBindingSpec{
 								ProfileRef: v1alpha1.ProfileRef{
-									Kind: "SeccompProfile",
+									Kind: v1alpha1.ProfileBindingKindSeccompProfile,
 								},
 							},
 							Status: v1alpha1.ProfileBindingStatus{
@@ -343,7 +343,7 @@ func TestHandle(t *testing.T) {
 						{
 							Spec: v1alpha1.ProfileBindingSpec{
 								ProfileRef: v1alpha1.ProfileRef{
-									Kind: "SeccompProfile",
+									Kind: v1alpha1.ProfileBindingKindSeccompProfile,
 								},
 							},
 							Status: v1alpha1.ProfileBindingStatus{
diff --git a/internal/pkg/webhooks/recording/recording_test.go b/internal/pkg/webhooks/recording/recording_test.go
index 42770e8d3..5ae5f2c91 100644
--- a/internal/pkg/webhooks/recording/recording_test.go
+++ b/internal/pkg/webhooks/recording/recording_test.go
@@ -94,7 +94,7 @@ func TestHandle(t *testing.T) {
 					Items: []v1alpha1.ProfileRecording{
 						{
 							Spec: v1alpha1.ProfileRecordingSpec{
-								Kind: "SeccompProfile",
+								Kind: v1alpha1.ProfileRecordingKindSeccompProfile,
 							},
 						},
 					},
@@ -142,7 +142,7 @@ func TestHandle(t *testing.T) {
 					Items: []v1alpha1.ProfileRecording{
 						{
 							Spec: v1alpha1.ProfileRecordingSpec{
-								Kind: "SeccompProfile",
+								Kind: v1alpha1.ProfileRecordingKindSeccompProfile,
 							},
 						},
 					},
@@ -160,7 +160,7 @@ func TestHandle(t *testing.T) {
 					Items: []v1alpha1.ProfileRecording{
 						{
 							Spec: v1alpha1.ProfileRecordingSpec{
-								Kind: "SeccompProfile",
+								Kind: v1alpha1.ProfileRecordingKindSeccompProfile,
 							},
 						},
 					},
@@ -190,7 +190,7 @@ func TestHandle(t *testing.T) {
 					Items: []v1alpha1.ProfileRecording{
 						{
 							Spec: v1alpha1.ProfileRecordingSpec{
-								Kind: "SeccompProfile",
+								Kind: v1alpha1.ProfileRecordingKindSeccompProfile,
 							},
 						},
 					},
@@ -224,7 +224,7 @@ func TestHandle(t *testing.T) {
 					Items: []v1alpha1.ProfileRecording{
 						{
 							Spec: v1alpha1.ProfileRecordingSpec{
-								Kind: "SeccompProfile",
+								Kind: v1alpha1.ProfileRecordingKindSeccompProfile,
 							},
 							Status: v1alpha1.ProfileRecordingStatus{
 								ActiveWorkloads: []string{"1", "2", "3"},
@@ -250,7 +250,7 @@ func TestHandle(t *testing.T) {
 					Items: []v1alpha1.ProfileRecording{
 						{
 							Spec: v1alpha1.ProfileRecordingSpec{
-								Kind: "SeccompProfile",
+								Kind: v1alpha1.ProfileRecordingKindSeccompProfile,
 							},
 							Status: v1alpha1.ProfileRecordingStatus{
 								ActiveWorkloads: []string{"1", "2", "3"},