Skip to main content
One namespace. This page is the whole ask, with the verbs written out.

What gets created

Applying the install kit creates six objects, all namespaced:
  • one ServiceAccount (mixpeek-submitter)
  • two Roles and their RoleBindings
  • one ResourceQuota
You can read every object in about five minutes.

The short answer, for a security review

There is exactly one cluster-scoped prerequisite and it is not ours to install.

The one cluster-scoped prerequisite

KubeRay is cluster-scoped, and there is no namespace-only way to install it. Measured on kuberay-operator 1.5.1: 3 CustomResourceDefinitions (rayclusters, rayjobs, rayservices) and 5 ClusterRoles with 1 ClusterRoleBinding. CRDs and ClusterRoles are cluster-scoped by definition. The distinction that matters to a security review is lifetime: Most customers reading this page already run KubeRay, in which case there is nothing to grant. Where you do not, your platform team installs it once with a published Helm command, and the steady-state ask is unchanged. You can also grant it to us, and some customers prefer to. The permissions are customresourcedefinitions, clusterroles and clusterrolebindings, all create. The trade is straightforward: holding it yourself means a Mixpeek release that requires a newer KubeRay waits for your change window.
On GKE these permissions are separable, which is worth knowing if you are scoping a custom role. An identity can hold container.customResourceDefinitions.create and not container.clusterRoles.create, so a check that reads only the CRD verb reports the grant as held on a cluster where the install will fail halfway. The qualification suite checks all three.

The two Roles, in full

rayjob-manager: submitting batch work

resourcequotas is read so batches can be sized to fit under your quota rather than discovering it by rejection. services is listed to resolve the Ray head.

ray-autoscaler-generation-stable: letting Ray scale its own workers

This is Ray’s own autoscaler, not Mixpeek code. pods/resize is in-place vertical scaling, available from Kubernetes 1.33; on older clusters the rule is inert and Ray falls back to replacing pods.
The binding is named for a generation-stable subject on purpose. KubeRay creates a new ServiceAccount per cluster generation, so a name-bound Role breaks on the first RayService swap and the symptom is that worker scale-up silently stops. If you intend to share this namespace with your own workloads, tell us and we will pin the generation instead.

What Mixpeek does not ask for

No ClusterRole. No cluster-scoped read of any kind. No ability to create namespaces, read other namespaces, or touch nodes. Verify it rather than believing it:
The qualification suite’s rbac-minimal-sa row asserts five verbs we need and five we must not have, including create clusterroles, create namespaces, delete nodes, and creating RayJobs in a namespace other than ours. It fails if any of the five forbidden answers yes.
kubectl auth can-i --as requires impersonation rights. If you run it as an identity that cannot impersonate, every answer comes back no and the output reads like a clean bill of health. Check that you got a mix of answers.

A disclosure we would rather you heard from us

get/list on rayjobs currently also reads Mixpeek credentials. Our batch RayJob CRs carry credential-shaped environment variables as inline values on their container specs, so anyone holding rayjob-manager can read them out of the CR. The verbs are genuinely required for batch to work. The problem is what the CR contains, and it is ours. It is tracked, being fixed in two phases (deliver via envFrom from a Secret, then remove the inline values), and the qualification suite fails on Security/rayjob-cr-secrets until it is done. How long the exposure lasts. Batch RayJob CRs are submitted with ttlSecondsAfterFinished: 120, so a finished job’s CR self-deletes two minutes after it completes. What is readable is in-flight and just-finished jobs, rather than an accumulating pile of credential-bearing objects.

Network policy

networkpolicy.yaml ships as a template with the endpoints blank, and is deliberately not applied by default. An incomplete egress policy does not fail at apply time; it fails hours later, in the middle of a batch, as a timeout that looks like something else. That leaves a third outcome, where you apply the kit, it works, and the policy is never revisited. So the qualification suite reports whether any NetworkPolicy governs the namespace. It is a warning rather than a failure, since running without one is a legitimate choice on a flat internal cluster. The point is that deciding against a policy and forgetting about it stop looking identical. The suite also distinguishes a policy that exists from a policy that governs our pods. One carrying a podSelector that matches something else leaves our workloads exactly as open as none at all, while still counting as one.

Using a namespace that is not mixpeek

Two edits before your first apply: the namespace: line in kustomization.yaml, and the Group subject system:serviceaccounts:mixpeek in role-ray-autoscaler.yaml, which kustomize does not rewrite. Then kubectl apply -k . with no -n. Passing -n instead does not work: kustomize stamps every object with the pinned namespace and kubectl refuses the mismatch object by object.