| Version | Supported |
|---|---|
| 1.5.x | ✅ |
| 1.4.x | ✅ |
| 1.3.x | ✅ |
| < 1.3 | ❌ |
If you discover a security vulnerability in the Kubernaut Operator, please report it responsibly.
Do NOT open a public GitHub issue for security vulnerabilities.
Instead, please email jgil@redhat.com with:
- A description of the vulnerability
- Steps to reproduce
- Potential impact
- Any suggested fix (optional)
- Acknowledgment within 48 hours of your report
- Assessment within 5 business days
- Fix timeline communicated after assessment, typically within 30 days for critical issues
- Credit in the release notes (unless you prefer to remain anonymous)
The Kubernaut Operator runs with elevated Kubernetes RBAC permissions to manage cluster-scoped resources (ClusterRoles, ClusterRoleBindings, CRDs, webhook configurations) and namespace-scoped workloads. When deploying:
- Follow the principle of least privilege for the operator's ServiceAccount
- TLS for the AuthWebhook is managed by OCP service-CA; the operator annotates the Service and webhook configurations for automatic certificate injection
- Restrict who can create/modify the singleton
KubernautCR - BYO secrets (PostgreSQL, Valkey, LLM credentials) should use short-lived credentials where possible and be rotated regularly
- The operator requires
escalateandbindRBAC verbs to provision ClusterRoles for managed workloads; see RBAC documentation below
The operator creates MutatingWebhookConfiguration and ValidatingWebhookConfiguration resources for the AuthWebhook service. Key security properties:
- FailurePolicy: Fail -- webhook requests are rejected if the AuthWebhook
service is unavailable. This prevents unauthenticated mutations from bypassing
policy enforcement. In HA deployments, ensure the AuthWebhook Deployment has
replicas >= 2and an appropriate PodDisruptionBudget to avoid blocking API server operations during rolling updates. - TimeoutSeconds: 10 -- explicit timeout to prevent slow webhook backends from causing API server request pile-up.
- TLS is managed by OCP service-CA: the
authwebhook-serviceannotation requests automatic certificate injection.
The operator requires these elevated permissions:
escalate/bindon ClusterRoles/ClusterRoleBindings: Required to create RBAC bindings for managed workloads (Kubernaut Agent investigator, signal processing, monitoring) without granting itself the permissions those roles carry.get/list/watchon Secrets cluster-wide: The Kubernaut Agent investigator role requires read access to secrets for root-cause analysis across namespaces. This is a deliberate design choice documented in thekubernaut-agent-investigatorClusterRole.
| ClusterRole | Purpose | Scoped Resources |
|---|---|---|
<ns>-kubernaut-agent-investigator |
Cluster-wide read-only access for root-cause analysis | Core K8s (pods, deployments, secrets, events, RBAC, etc.), OCP platform (routes, SCCs, DeploymentConfigs, ImageStreams, Builds), OCP machine management (Machines, MachineSets, MachineConfigs, MCPs), OLM (CSVs, Subscriptions, InstallPlans, CatalogSources), admission webhooks, CRDs, PriorityClasses, Istio/Linkerd/cert-manager/ArgoCD/Prometheus. See internal/resources/rbac.go for the full rule set. |
<ns>-kubernaut-agent-client |
AIAnalysis service calls the KA service | Services (get/create on kubernaut-agent-service) |
<ns>-gateway-role |
Signal fingerprinting and owner-chain resolution | Core K8s read-only (nodes, pods, services, PVs, PVCs), apps (deployments, replicasets, statefulsets, daemonsets), autoscaling (HPAs), batch (jobs), networking (ingresses) |
<ns>-signalprocessing-controller |
Process signals and manage remediation lifecycle | Full CRUD on kubernaut.ai CRs (signalprocessings, remediationrequests), status/finalizer updates, read-only core K8s (pods, services, namespaces, nodes, deployments, replicasets, statefulsets, daemonsets, HPAs, PDBs, NetworkPolicies), event creation, leader election leases |
<ns>-aianalysis-controller |
Manage AI analysis lifecycle | Full CRUD on kubernaut.ai CRs (aianalyses), status/finalizer updates, read-only core K8s, event creation, leader election leases |
<ns>-remediationorchestrator-controller |
Orchestrate end-to-end remediation | Full CRUD on kubernaut.ai CRs (remediationrequests, remediationexecutions, workflowruns), status/finalizer updates, read-only core K8s, event creation, leader election leases |
<ns>-workflowexecution-controller |
Execute remediation workflows | Full CRUD on kubernaut.ai CRs (workflowruns), Argo Workflows (workflows), status/finalizer updates, read-only core K8s, event creation, leader election leases |
<ns>-workflow-runner |
Run remediation actions inside workflows | Broad read-write on core K8s (pods, deployments, statefulsets, daemonsets, services, configmaps, secrets, etc.), Istio/Linkerd/cert-manager/ArgoCD resources |
<ns>-effectivenessmonitor-controller |
Monitor remediation effectiveness | Full CRUD on kubernaut.ai CRs (effectivenessassessments), read-only core K8s, event creation, leader election leases |
<ns>-notification-controller |
Deliver notifications | Full CRUD on kubernaut.ai CRs (notifications), status/finalizer updates, event creation, leader election leases |
<ns>-data-storage-auth-middleware |
Auth webhook token review | TokenReview create, SubjectAccessReview create |
<ns>-data-storage-client |
Service-to-DataStorage API access | Full CRUD on kubernaut.ai CRs (datastorageapis). Bound per-service via RoleBindings |
<ns>-authwebhook-role |
AuthWebhook admission control | TokenReview create, SubjectAccessReview create, webhook configuration read |
<ns>-alertmanager-view |
EffectivenessMonitor reads Prometheus/AlertManager metrics | Created only when monitoring.enabled=true |
<ns>-gateway-signal-source |
AlertManager pushes signals to Gateway | Created only when monitoring.enabled=true. Bound to OCP alertmanager SA |
<ns>-workflowexecution-awx |
WorkflowExecution talks to AWX/AAP | AWX Jobs (CRUD). Created only when ansible.enabled=true |
The kubernaut-agent-investigator ClusterRole grants read-only access to a
broad set of resources across 30+ API groups. Key security considerations:
- Cluster-wide secret read (pre-existing): The agent can read all secrets in all namespaces. This is required for cross-namespace root-cause analysis.
- RBAC topology read: The agent can enumerate all Roles, ClusterRoles, and their bindings. An attacker who compromises the agent pod could map the entire cluster's principal-to-privilege chains.
- SCC read (OCP): Exposes which SecurityContextConstraints exist and which SAs are bound to privileged SCCs.
- MachineConfig read (OCP): Exposes node-level configuration (ignition snippets, kubelet config).
- OCP networking read: Includes EgressNetworkPolicies, HostSubnets, and NetNamespaces, exposing network topology details.
- Ecosystem CRD read: Istio/Linkerd security policies, cert-manager certificates, and ArgoCD application state are readable, potentially exposing service mesh mTLS configuration and GitOps deployment details.
These capabilities are equivalent to a cluster auditor tier — high-sensitivity read access with no write or escalation capability. The accepted risk boundary is: "compromise of the agent SA = full cluster read reconnaissance, but no mutation or data exfiltration beyond secret content."
The operator's own ClusterRole (config/rbac/role.yaml, manager-role) grants the following API access:
| API Group | Resources | Verbs | Justification |
|---|---|---|---|
"" (core) |
configmaps, namespaces, secrets, serviceaccounts, services | create, delete, get, list, patch, update, watch | Manage all namespace-scoped resources for the 10 kubernaut services |
"" (core) |
events | create, patch | Emit Kubernetes events for reconciliation status |
admissionregistration.k8s.io |
mutatingwebhookconfigurations, validatingwebhookconfigurations | create, delete, get, list, patch, update, watch | Manage AuthWebhook admission configurations |
apiextensions.k8s.io |
customresourcedefinitions | create, get, list, patch, update, watch | Install and update kubernaut workload CRDs |
apps |
deployments | create, delete, get, list, patch, update, watch | Manage Deployments for all 10 services |
batch |
jobs | create, delete, get, list, patch, update, watch | Manage database migration Jobs |
config.openshift.io |
apiservers | get, list, watch | Read OCP APIServer CR to derive TLS profile |
kubernaut.ai |
kubernauts, kubernauts/finalizers, kubernauts/status | full CRUD | Reconcile the Kubernaut CR |
networking.k8s.io |
networkpolicies | create, delete, get, list, patch, update, watch | Manage NetworkPolicies when enabled |
policy |
poddisruptionbudgets | create, delete, get, list, patch, update, watch | Manage PDBs for service availability |
rbac.authorization.k8s.io |
clusterroles, clusterrolebindings, roles, rolebindings | bind, create, delete, escalate, get, list, patch, update, watch | Provision RBAC for managed workloads (requires escalate/bind) |
route.openshift.io |
routes | create, delete, get, list, patch, update, watch | Manage OCP Routes for Gateway |
- Kubernaut Agent uses projected SA tokens (not automounted).
AutomountServiceAccountToken: falseon thekubernaut-agent-saServiceAccount.- Projected token: audience
https://kubernetes.default.svc, expiration 3600s (1 hour), mount path/var/run/secrets/kubernetes.io/serviceaccount/token. - All other service SAs use standard automounted tokens.
- All containers run as non-root (
runAsNonRoot: true). - Privilege escalation disabled (
allowPrivilegeEscalation: false). - All Linux capabilities dropped (
capabilities.drop: ["ALL"]). - Seccomp profile:
RuntimeDefault. - Read-only root filesystem on the operator container.
- Init containers follow the same security context as application containers.
- Operator images signed with Cosign (keyless, GitHub Actions OIDC).
- SBOM (CycloneDX JSON) generated via Syft, attached to GitHub Releases.
- SBOM attested to images via Cosign (
cosign attest --type cyclonedx). - Image vulnerability scanning via Trivy (CRITICAL/HIGH gate in CI).
- Build provenance: SLSA 1–2 via
actions/attest-build-provenance. - Init container images pinned by digest and configurable via
RELATED_IMAGE_*env vars. - Consumer verification:
cosign verify \
--certificate-oidc-issuer=https://token.actions.githubusercontent.com \
--certificate-identity-regexp="^https://github.com/jordigilh/kubernaut-operator/.github/workflows/release.yml@refs/tags/" \
quay.io/kubernaut-ai/kubernaut-operator:<version>We follow coordinated disclosure. We ask that you give us reasonable time to address the vulnerability before public disclosure.