Policy: organization-namespaces
Ensure that all namespaces created by users have a label appuio.io/organization
which isn’t empty.
Category |
Namespace Ownership |
Minimum Kyverno version |
v1 |
Subject |
APPUiO Organizations |
Policy types |
|
Implementation |
This policy will:
-
Check that each namespace created by a user without cluster-admin permissions has a label appuio.io/organization which isn’t empty.
-
Check that the creating user is in the organization it tries to create a namespace for.
The user’s organization membership is checked by:
-
Fetching all OpenShift groups
-
Reading the
appuio.io/organization
label of the request and finding a group with the same name
If a group matching the label value exists, the policy checks that the user which issued the request is a member of that group.
If the label appuio.io/organization
is missing or empty or the user isn’t a member of the group, the request is denied.
Users which match an entry of component parameter bypassNamespaceRestrictions
are allowed to bypass the policy.
Policy Definition
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
annotations:
policies.kyverno.io/category: Namespace Ownership
policies.kyverno.io/description: |
This policy will:
- Check that each namespace created by a user without cluster-admin permissions has a label appuio.io/organization which isn't empty.
- Check that the creating user is in the organization it tries to create a namespace for.
The user's organization membership is checked by:
- Fetching all OpenShift groups
- Reading the `appuio.io/organization` label of the request and finding a group with the same name
If a group matching the label value exists, the policy checks that the user which issued the request is a member of that group.
If the label `appuio.io/organization` is missing or empty or the user isn't a member of the group, the request is denied.
Users which match an entry of xref:references/parameters#_bypassnamespacerestrictions[component parameter `bypassNamespaceRestrictions`] are allowed to bypass the policy.
policies.kyverno.io/jsonnet: component/namespace-policies.jsonnet
policies.kyverno.io/minversion: v1
policies.kyverno.io/subject: APPUiO Organizations
policies.kyverno.io/title: Ensure that all namespaces created by users have a
label `appuio.io/organization` which isn't empty.
labels:
app.kubernetes.io/component: appuio-cloud
app.kubernetes.io/managed-by: commodore
app.kubernetes.io/name: appuio-cloud
name: organization-namespaces
name: organization-namespaces
spec:
background: false
rules:
- context:
- apiCall:
jmesPath: '@'
urlPath: /apis/user.openshift.io/v1/users/{{request.userInfo.username}}
name: ocpuser
exclude:
any:
- clusterRoles:
- cluster-admin
- cluster-image-registry-operator
- cluster-node-tuning-operator
- kyverno:generatecontroller
- kyverno:policycontroller
- multus-admission-controller-webhook
- openshift-dns-operator
- openshift-ingress-operator
- syn-admin
- syn-argocd-application-controller
- syn-argocd-server
- system:controller:generic-garbage-collector
- system:controller:operator-lifecycle-manager
- system:master
- system:openshift:controller:namespace-security-allocation-controller
- system:openshift:controller:podsecurity-admission-label-syncer-controller
- subjects:
- kind: ServiceAccount
name: argocd-application-controller
namespace: argocd
- kind: ServiceAccount
name: cluster-logging-operator
namespace: openshift-logging
- kind: ServiceAccount
name: olm-operator-serviceaccount
namespace: openshift-operator-lifecycle-manager
- kind: ServiceAccount
name: namespace-openshift-config-2c8343f13594d63-manager
namespace: syn-resource-locker
- kind: ServiceAccount
name: namespace-default-d6a0af6dd07e8a3-manager
namespace: syn-resource-locker
- kind: ServiceAccount
name: namespace-openshift-monitoring-c4273dc15ddfdf7-manager
namespace: syn-resource-locker
match:
all:
- resources:
kinds:
- Namespace
mutate:
patchStrategicMerge:
metadata:
labels:
+(appuio.io/organization): '{{ocpuser.metadata.annotations."appuio.io/default-organization"
|| ""}}'
name: set-default-organization
preconditions:
all:
- key: '{{serviceAccountName}}'
operator: Equals
value: ''
- exclude:
any:
- clusterRoles:
- cluster-admin
- cluster-image-registry-operator
- cluster-node-tuning-operator
- kyverno:generatecontroller
- kyverno:policycontroller
- multus-admission-controller-webhook
- openshift-dns-operator
- openshift-ingress-operator
- syn-admin
- syn-argocd-application-controller
- syn-argocd-server
- system:controller:generic-garbage-collector
- system:controller:operator-lifecycle-manager
- system:master
- system:openshift:controller:namespace-security-allocation-controller
- system:openshift:controller:podsecurity-admission-label-syncer-controller
- subjects:
- kind: ServiceAccount
name: argocd-application-controller
namespace: argocd
- kind: ServiceAccount
name: cluster-logging-operator
namespace: openshift-logging
- kind: ServiceAccount
name: olm-operator-serviceaccount
namespace: openshift-operator-lifecycle-manager
- kind: ServiceAccount
name: namespace-openshift-config-2c8343f13594d63-manager
namespace: syn-resource-locker
- kind: ServiceAccount
name: namespace-default-d6a0af6dd07e8a3-manager
namespace: syn-resource-locker
- kind: ServiceAccount
name: namespace-openshift-monitoring-c4273dc15ddfdf7-manager
namespace: syn-resource-locker
match:
all:
- resources:
kinds:
- Namespace
name: has-organization
preconditions:
all:
- key: '{{serviceAccountName}}'
operator: Equals
value: ''
validate:
message: Namespace must have organization
pattern:
metadata:
labels:
appuio.io/organization: ?*
- exclude:
any:
- clusterRoles:
- cluster-admin
- cluster-image-registry-operator
- cluster-node-tuning-operator
- kyverno:generatecontroller
- kyverno:policycontroller
- multus-admission-controller-webhook
- openshift-dns-operator
- openshift-ingress-operator
- syn-admin
- syn-argocd-application-controller
- syn-argocd-server
- system:controller:generic-garbage-collector
- system:controller:operator-lifecycle-manager
- system:master
- system:openshift:controller:namespace-security-allocation-controller
- system:openshift:controller:podsecurity-admission-label-syncer-controller
- subjects:
- kind: ServiceAccount
name: argocd-application-controller
namespace: argocd
- kind: ServiceAccount
name: cluster-logging-operator
namespace: openshift-logging
- kind: ServiceAccount
name: olm-operator-serviceaccount
namespace: openshift-operator-lifecycle-manager
- kind: ServiceAccount
name: namespace-openshift-config-2c8343f13594d63-manager
namespace: syn-resource-locker
- kind: ServiceAccount
name: namespace-default-d6a0af6dd07e8a3-manager
namespace: syn-resource-locker
- kind: ServiceAccount
name: namespace-openshift-monitoring-c4273dc15ddfdf7-manager
namespace: syn-resource-locker
match:
all:
- resources:
kinds:
- Namespace
name: is-in-organization
preconditions:
all:
- key: '{{serviceAccountName}}'
operator: Equals
value: ''
- key: '{{request.object.metadata.labels."appuio.io/organization" || ""}}'
operator: NotEquals
value: ''
validate:
deny:
conditions:
any:
- key: '{{request.object.metadata.labels."appuio.io/organization" ||
""}}'
operator: AnyNotIn
value: '{{request.userInfo.groups}}'
message: Creating namespace for {{request.object.metadata.labels."appuio.io/organization"}}
but {{request.userInfo.username}} is not in organization
validationFailureAction: enforce