Skip to main content

Policy Practice: Only Allow Specific Accounts to Create Public Ingress

Creating Policy

Use kubectl apply for the following two YAMLs:

constraint-template.yaml
apiVersion: templates.gatekeeper.sh/v1
kind: ConstraintTemplate
metadata:
name: blockpublicingress
spec:
crd:
spec:
names:
kind: BlockPublicIngress
validation:
openAPIV3Schema:
type: object
properties:
allowedUins:
type: array
items:
type: string
targets:
- target: admission.k8s.gatekeeper.sh
rego: |
package blockpublicingress

is_qcloud_ingress(ingress) = true {
not ingress.spec.ingressClassName
}
is_qcloud_ingress(ingress) = true {
ingress.spec.ingressClassName == ""
}
is_qcloud_ingress(ingress) = true {
ingress.spec.ingressClassName == "qcloud"
}
is_qcloud_ingress(ingress) = true {
not ingress.metadata.annotations["kubernetes.io/ingress.class"]
}
is_qcloud_ingress(ingress) = true {
ingress.metadata.annotations["kubernetes.io/ingress.class"] == ""
}
is_public_ingress(ingress) = true {
not ingress.metadata.annotations["kubernetes.io/ingress.subnetId"]
}
is_public_ingress(ingress) = true {
ingress.metadata.annotations["kubernetes.io/ingress.subnetId"] == ""
}
is_qcloud_ingress(ingress) = true {
ingress.metadata.annotations["kubernetes.io/ingress.class"] == "qcloud"
}
is_tke_user(userinfo) = true {
userinfo.groups[_] == "tke:users"
regex.match("^\\d+-\\d+$", userinfo.username)
}
get_uin(userinfo) = uin {
split(userinfo.username, "-", parts)
uin := parts[0]
}
is_uin_allowed(uin, allowed_uins) {
allowed_uins[_] == uin
}

violation[{"msg": msg}] {
input.review.kind.kind == "Ingress"
regex.match("^(extensions|networking.k8s.io)$", input.review.kind.group)
regex.match("^(CREATE|UPDATE)$", input.review.operation)
ingress := input.review.object
is_qcloud_ingress(ingress)
is_public_ingress(ingress)
userinfo := input.review.userInfo
is_tke_user(userinfo)
uin := get_uin(userinfo)
not is_uin_allowed(uin, input.parameters.allowedUins)
msg := sprintf("User '%v' is not allowed to create Ingress resources", [uin])
}

Creating Ingress Notes

  1. If creating Ingress through console, and cluster created by current sub-account, will use admin permissions, not restricted by this policy.
  2. If creating via kubectl, need sub-account's kubeconfig when obtaining kubeconfig.

Effect

If used sub-account not in allowedUins list, creating public Ingress will report error.

Console error:

kubectl apply error:

Error from server (Forbidden): error when creating "STDIN": admission webhook "validation.gatekeeper.sh" denied the request: [block-public-ingress] User '100009022548' is not allowed to create Ingress resources