Skip to content

Commit

Permalink
fix: add priv user check for machine config & master toleration polic…
Browse files Browse the repository at this point in the history
…ies (#3169)

* user check for machine config & master taint

* lint fix

* lint fix
  • Loading branch information
ArrisLee authored Sep 14, 2023
1 parent 825a70b commit 331b08e
Show file tree
Hide file tree
Showing 7 changed files with 174 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,6 @@ spec:
- target: admission.k8s.gatekeeper.sh
rego: |
{{ file.Read "gktemplates-src/aro-deny-machine-config/src.rego" | strings.Indent 8 | strings.TrimSuffix "\n" }}
libs:
- |
{{ file.Read "gktemplates-src/library/common.rego" | strings.Indent 10 | strings.TrimSuffix "\n" }}
Original file line number Diff line number Diff line change
@@ -1,8 +1,14 @@
package arodenymachineconfig
import future.keywords.in
import data.lib.common.is_exempted_account

violation[{"msg": msg}] {
input.review.operation in ["CREATE", "UPDATE", "DELETE"]

# Check if it is a regular user
not is_exempted_account(input.review)

# Check if the object name matches the regex for generated machine configs
name := input.review.object.metadata.name
regex.match("^.+(-master|-worker|-master-.+|-worker-.+|-kubelet|-container-runtime|-aro-.+|-ssh|-generated-.+)$", name)
msg := "Modify cluster machine config is not allowed"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,9 @@ fake_machine_config_input_review(name, operation) = review {
"metadata": {
"name": name
}
},
"userInfo":{
"username":"testuser"
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package arodenymastertolerationtaints
import future.keywords.in
import future.keywords.contains
import data.lib.common.is_priv_namespace
import data.lib.common.is_exempted_account

violation[{"msg": msg}] {
# Check if the input namespace is a non-privileged namespace
Expand All @@ -12,6 +13,9 @@ violation[{"msg": msg}] {
# Check if the input operation is CREATE or UPDATE
input.review.operation in ["CREATE", "UPDATE"]

# Check if it is a regular user
not is_exempted_account(input.review)

# Check if pod object has master toleration taints
tolerations := input.review.object.spec.tolerations
some toleration in tolerations
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,9 @@ fake_input_review(namespace, operation, taint_key_one, taint_key_two) = review {
}
]
}
}

},
"userInfo":{
"username":"testuser"
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,160 @@ spec:
rego: |
package arodenymachineconfig
import future.keywords.in
import data.lib.common.is_exempted_account
violation[{"msg": msg}] {
input.review.operation in ["CREATE", "UPDATE", "DELETE"]
# Check if it is a regular user
not is_exempted_account(input.review)
# Check if the object name matches the regex for generated machine configs
name := input.review.object.metadata.name
regex.match("^.+(-master|-worker|-master-.+|-worker-.+|-kubelet|-container-runtime|-aro-.+|-ssh|-generated-.+)$", name)
msg := "Modify cluster machine config is not allowed"
}
libs:
- |
package lib.common
import future.keywords.in
# shared structures, functions, etc.
is_exempted_account(review) = true {
has_field(review, "userInfo")
has_field(review.userInfo, "username")
username := get_username(review)
groups := get_user_group(review)
is_exempted_user_or_groups(username, groups)
} {
not has_field(review, "userInfo")
} {
has_field(review, "userInfo")
not has_field(review.userInfo, "username")
}
get_username(review) = name {
not has_field(review.userInfo, "username")
name = "notfound"
} {
has_field(review.userInfo, "username")
name = review.userInfo.username
print(name)
}
get_user_group(review) = group {
not review.userInfo
group = []
} {
not review.userInfo.groups
group = []
} {
group = review.userInfo.groups
}
is_exempted_user_or_groups(user, groups) = true {
exempted_user[user]
print("exempted user:", user)
} {
group := [ g | g := groups[_]; (g in cast_set(exempted_groups)) ]
count(group) > 0
print("exempted group:", group)
}
has_field(object, field) = true {
object[field]
}
is_exempted_user(user) = true {
exempted_user[user]
}
is_priv_namespace(ns) = true {
privileged_ns[ns]
}
exempted_user = {
"system:kube-controller-manager",
"system:admin" # comment out temporarily for testing in console
}
exempted_groups = {
# "system:cluster-admins", # dont allow kube:admin
"system:nodes", # eg, "username": "system:node:jeff-test-cluster-pcnp4-master-2"
"system:serviceaccounts", # to allow all system service account?
# "system:serviceaccounts:openshift-monitoring", # monitoring operator
# "system:serviceaccounts:openshift-network-operator", # network operator
# "system:serviceaccounts:openshift-machine-config-operator", # machine-config-operator, however the request provide correct sa name
"system:masters" # system:admin
}
privileged_ns = {
# Kubernetes specific namespaces
"kube-node-lease",
"kube-public",
"kube-system",
# ARO specific namespaces
"openshift-azure-logging",
"openshift-azure-operator",
"openshift-managed-upgrade-operator",
"openshift-azure-guardrails",
# OCP namespaces
"openshift",
"openshift-apiserver",
"openshift-apiserver-operator",
"openshift-authentication-operator",
"openshift-cloud-controller-manager",
"openshift-cloud-controller-manager-operator",
"openshift-cloud-credential-operator",
"openshift-cluster-csi-drivers",
"openshift-cluster-machine-approver",
"openshift-cluster-node-tuning-operator",
"openshift-cluster-samples-operator",
"openshift-cluster-storage-operator",
"openshift-cluster-version",
"openshift-config",
"openshift-config-managed",
"openshift-config-operator",
"openshift-console",
"openshift-console-operator",
"openshift-console-user-settings",
"openshift-controller-manager",
"openshift-controller-manager-operator",
"openshift-dns",
"openshift-dns-operator",
"openshift-etcd",
"openshift-etcd-operator",
"openshift-host-network",
"openshift-image-registry",
"openshift-ingress",
"openshift-ingress-canary",
"openshift-ingress-operator",
"openshift-insights",
"openshift-kni-infra",
"openshift-kube-apiserver",
"openshift-kube-apiserver-operator",
"openshift-kube-controller-manager",
"openshift-kube-controller-manager-operator",
"openshift-kube-scheduler",
"openshift-kube-scheduler-operator",
"openshift-kube-storage-version-migrator",
"openshift-kube-storage-version-migrator-operator",
"openshift-machine-api",
"openshift-machine-config-operator",
"openshift-marketplace",
"openshift-monitoring",
"openshift-multus",
"openshift-network-diagnostics",
"openshift-network-operator",
"openshift-oauth-apiserver",
"openshift-openstack-infra",
"openshift-operators",
"openshift-operator-lifecycle-manager",
"openshift-ovirt-infra",
"openshift-sdn",
"openshift-service-ca",
"openshift-service-ca-operator"
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ spec:
import future.keywords.in
import future.keywords.contains
import data.lib.common.is_priv_namespace
import data.lib.common.is_exempted_account
violation[{"msg": msg}] {
# Check if the input namespace is a non-privileged namespace
Expand All @@ -28,6 +29,9 @@ spec:
# Check if the input operation is CREATE or UPDATE
input.review.operation in ["CREATE", "UPDATE"]
# Check if it is a regular user
not is_exempted_account(input.review)
# Check if pod object has master toleration taints
tolerations := input.review.object.spec.tolerations
some toleration in tolerations
Expand Down

0 comments on commit 331b08e

Please sign in to comment.