Isolate workspace content
Enable the Omnia admission policy so that a pod in a workspace namespace can mount only its own workspace-<namespace>-content PVC.
The policy sits on top of the storage layout described in Workspace content layout. It rejects a pod that names a foreign workspace’s content PVC or the shared-root PVC. For the paths on the volume and the mount modes, see the layout reference.
Prerequisites
Section titled “Prerequisites”- Kubernetes 1.30 or later with the
ValidatingAdmissionPolicyfeature. On an older cluster, use a policy controller instead (see Clusters without ValidatingAdmissionPolicy). - An Omnia release installed with Helm, with workspace content storage configured.
Enable the policy
Section titled “Enable the policy”-
Set the chart values.
failurePolicyisFailby default, so a policy error rejects the pod. The policy is off by default.workspaceContent:admissionPolicy:enabled: truefailurePolicy: Fail -
Optional: also reject any PersistentVolume that points at the share root. Set
shareRootPathto the NFS export path of your install, andprovisionerUsernameto the identity that creates the per-workspace volumes so that it stays exempt. Both values below are illustrative.workspaceContent:admissionPolicy:shareRootPath: /data/omniaprovisionerUsername: system:serviceaccount:kube-system:nfs-provisionerThe PV policy is rendered only when
shareRootPathis set. It rejects creation of a PersistentVolume whosespec.nfs.pathequalsshareRootPath. -
Apply the values.
--reuse-valuesdoes not read the values from steps 1 and 2, so pass them in a file.Terminal window helm upgrade omnia oci://ghcr.io/altairalabs/charts/omnia --devel \--namespace omnia-system --reuse-values -f values.yaml
The policy applies to pod creates and updates in every namespace except the release namespace, where the operator mounts the share root.
Verify
Section titled “Verify”-
Confirm the policy and its binding exist.
Terminal window kubectl get validatingadmissionpolicy,validatingadmissionpolicybinding | grep workspace-content-mount -
Try a pod in a workspace namespace that mounts another namespace’s claim.
otheris a placeholder.apiVersion: v1kind: Podmetadata:name: mount-probespec:containers:- name: probeimage: busyboxcommand: ["sleep", "60"]volumeMounts:- name: contentmountPath: /contentvolumes:- name: contentpersistentVolumeClaim:claimName: workspace-other-contentTerminal window kubectl apply -n <workspace-namespace> --dry-run=server -f mount-probe.yamlThe request is denied, and the error contains
pod may only mount its own namespace's workspace-content PVC. ChangeclaimNametoworkspace-<workspace-namespace>-contentand the same dry run is admitted.
Clusters without ValidatingAdmissionPolicy
Section titled “Clusters without ValidatingAdmissionPolicy”Enforce the same rule with a policy controller. Exclude the Omnia release namespace from either policy, because the operator mounts the share root there.
The rule: reject a pod volume whose PVC claim name contains workspace, ends in -content, and is not workspace-<namespace>-content.
Gatekeeper
Section titled “Gatekeeper”Create a ConstraintTemplate whose Rego runs over input.review.object, then a Constraint of that kind that matches Pod and lists the release namespace in excludedNamespaces. The Rego below is the rule in Gatekeeper’s syntax; Omnia does not ship or test it.
package workspacecontentviolation[{"msg": msg}] { vol := input.review.object.spec.volumes[_] claim := vol.persistentVolumeClaim.claimName contains(claim, "workspace") endswith(claim, "-content") claim != sprintf("workspace-%s-content", [input.review.namespace]) msg := sprintf("pod may only mount workspace-%s-content", [input.review.namespace])}Kyverno
Section titled “Kyverno”Create a ClusterPolicy with a validate.deny rule that applies the same condition to request.object.spec.volumes[].persistentVolumeClaim.claimName, matching Pod and excluding the release namespace.
Troubleshooting
Section titled “Troubleshooting”A pod in a workspace namespace is rejected after enabling the policy
Section titled “A pod in a workspace namespace is rejected after enabling the policy”The pod names a content PVC other than workspace-<namespace>-content. Any claim name that contains workspace and ends in -content is checked, so rename an unrelated claim that matches that pattern.
Related pages
Section titled “Related pages”- Workspace content layout: why the volume is shaped this way, and how the dashboard reaches it through the operator
- Workspace content layout reference: paths, mount modes and the content API
- Manage workspaces