Skip to content

Commit

Permalink
Gatekeeper policy to replace deprecated IAMPolicy Controller
Browse files Browse the repository at this point in the history
Signed-off-by: Brian Jarvis <[email protected]>
  • Loading branch information
brian-jarvis authored and openshift-merge-bot[bot] committed Feb 15, 2024
1 parent 658537f commit 89fe5a3
Show file tree
Hide file tree
Showing 2 changed files with 254 additions and 1 deletion.
253 changes: 253 additions & 0 deletions community/AC-Access-Control/policy-gatekeeper-limitclusteradmin.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,253 @@

# ## Introduction
# This Gatekeeper Policy is intended to match the behavior of the deprecated ACM IAMPolicy Controller. It will allow an administrator to monitor and alert if `ClusterRoleBindings` with the specified `ClusterRole` exceed the maximum number of users. In the case where a Group is specified in the `ClusterRoleBinding` the number of users in the group are counted. ServiceAccounts are ignored.
#
# ## Prerequisites
# The Policy makes use of sync data from the cluster to have knowledge of the existing `ClusterRoleBindings` and `Groups`. To make this data available create a `Config` in the Gatekeeper Operator namespace, this is `openshift-gatekeeper-system` by default.
#
# The config needs to be named "config", there can only be one. Below is an example of the sync config required for this Policy. Note you should also enable the `auditFromCache` in the gatekeeper instance.
#
# ```
# apiVersion: config.gatekeeper.sh/v1alpha1
# kind: Config
# metadata:
# name: config
# namespace: "openshift-gatekeeper-system"
# spec:
# sync:
# syncOnly:
# - group: "rbac.authorization.k8s.io"
# version: "v1"
# kind: "ClusterRoleBinding"
# - group: "user.openshift.io"
# version: "v1"
# kind: "Group"
#```

apiVersion: policy.open-cluster-management.io/v1
kind: Policy
metadata:
annotations:
policy.open-cluster-management.io/standards: NIST SP 800-53
policy.open-cluster-management.io/categories: AC Access Control
policy.open-cluster-management.io/controls: AC-2 Account Management
name: gatekeeper-limitclusteradmin
spec:
disabled: false
policy-templates:
- objectDefinition:
apiVersion: templates.gatekeeper.sh/v1
kind: ConstraintTemplate
metadata:
name: maxiamclusterbindings
annotations:
metadata.gatekeeper.sh/title: "Prevent number of users assigned to all ClusterRoleBindings from exceeding limit for the specified role"
metadata.gatekeeper.sh/version: 1.0.0
metadata.gatekeeper.sh/requires-sync-data: |
"[
[
{
"groups": ["rbac.authorization.k8s.io"],
"versions": ["v1"],
"kinds": ["ClusterRoleBinding"]
},
{
"groups": ["user.openshift.io"],
"versions": ["v1"],
"kinds": ["Group"]
}
]
]"
description: |
validates the number of users and users in groups assigned the specified cluster role does not exceed the specified count
spec:
crd:
spec:
names:
kind: MaxIAMClusterBindings
validation:
openAPIV3Schema:
type: object
properties:
maxClusterRoleBindingUsers:
type: number
description: Maximum number of users and users within groups allowed to be bound to the specified role
example: 5
clusterRole:
type: string
description: Name of the ClusterRole to validate
example: "cluster-admin"
ignoreClusterRoleBindings:
type: array
items:
type: string
description: List of ClusterRoleBindings to exclude from the validation count
example: '["myclusteradmins-crb", "system-admins"]'


targets:
- target: admission.k8s.gatekeeper.sh
libs:
- |
package lib.helpers
# Types of subjects to count
count_kinds := {"User", "Group"}
validate_subject(kind, roleRef) {
kind == count_kinds[_]
is_clusterrole_ref(roleRef)
}
is_clusterrole_ref(role) {
role.kind == "ClusterRole"
role.name == input.parameters.clusterRole
}
get_user_names("User", s_name) := names {
names := {nm | nm := s_name}
}
get_user_names("Group", s_name) := names {
names := {nm | nm := data.inventory.cluster["user.openshift.io/v1"].Group[s_name].users[_]}
}
is_excluded(exclusion_list, crd_name) {
exclusions := {e | e := exclusion_list[_]}
crd_name == exclusions[_]
}
rego: |
package maxiamclusterbindings
import data.lib.helpers.validate_subject
import data.lib.helpers.is_clusterrole_ref
import data.lib.helpers.get_user_names
import data.lib.helpers.is_excluded
max_admins := input.parameters.maxClusterRoleBindingUsers
violation[{"msg": msg}] {
is_number(max_admins)
max_admins < 1
msg = sprintf("maxClusterRoleBindingUsers parameter must be greater than 0(zero) maxClusterRoleBindingUsers: %v", [max_admins] )
}
# Make a list of all ClusterRoleBindings that should be excluded from the count
# Exclude the binding under review so if the number of subjects decreases we don't have an incorrect count.
# The updated subjects will be added back in to the count below.
bindings_to_exclude[crd_name] {
crd_name := input.review.object.metadata.name
}
bindings_to_exclude[crd_name] {
crd_name := input.parameters.ignoreClusterRoleBindings[_]
}
violation[{"msg": msg}] {
# check if the requested role references clusterRole parameter
is_clusterrole_ref(input.review.object.roleRef)
# check if the requested binding should be excluded
not is_excluded(input.parameters.ignoreClusterRoleBindings, input.review.object.metadata.name)
# Get all ClusterRoleBinding that are not excluded
crb_list := {crb | not is_excluded(bindings_to_exclude, data.inventory.cluster["rbac.authorization.k8s.io/v1"].ClusterRoleBinding[i].metadata.name);
crb := data.inventory.cluster["rbac.authorization.k8s.io/v1"].ClusterRoleBinding[i]}
# Get the list of all users in the list
current_subjects := {sub | validate_subject(crb_list[i].subjects[s].kind, crb_list[i].roleRef);
sub := get_user_names(crb_list[i].subjects[s].kind, crb_list[i].subjects[s].name)[_]}
new_subjects := {sub | validate_subject(input.review.object.subjects[s].kind, input.review.object.roleRef);
sub := get_user_names(input.review.object.subjects[s].kind, input.review.object.subjects[s].name)[_]}
total_admins := count(current_subjects | new_subjects)
total_admins > max_admins
msg := sprintf("Total number of bindings to role '%v' exceeded. max-admins allowed: %v - current total: %v", [input.parameters.clusterRole, max_admins, total_admins] )
}
- objectDefinition:
apiVersion: constraints.gatekeeper.sh/v1beta1
kind: MaxIAMClusterBindings
metadata:
name: max-cluster-admins
spec:
match:
kinds:
- apiGroups:
- rbac.authorization.k8s.io
kinds:
- ClusterRoleBinding
parameters:
clusterRole: cluster-admin
ignoreClusterRoleBindings:
- iam-max-groups
maxClusterRoleBindingUsers: 5

- objectDefinition:
apiVersion: policy.open-cluster-management.io/v1
kind: ConfigurationPolicy
metadata:
name: inform-gatekeeper-audit-max-cluster-admins
spec:
namespaceSelector:
exclude:
- kube-*
include:
- '*'
object-templates:
- complianceType: musthave
objectDefinition:
apiVersion: constraints.gatekeeper.sh/v1beta1
kind: MaxIAMClusterBindings
metadata:
name: max-cluster-admins
status:
totalViolations: 0
remediationAction: inform
severity: low
- objectDefinition:
apiVersion: policy.open-cluster-management.io/v1
kind: ConfigurationPolicy
metadata:
name: inform-gatekeeper-admission-max-cluster-admins
spec:
namespaceSelector:
exclude:
- kube-*
include:
- '*'
object-templates:
- complianceType: mustnothave
objectDefinition:
annotations:
constraint_action: deny
constraint_kind: MaxIAMClusterBindings
constraint_name: max-cluster-admins
event_type: violation
apiVersion: v1
kind: Event
remediationAction: inform
severity: low
---
apiVersion: cluster.open-cluster-management.io/v1beta1
kind: Placement
metadata:
name: placement-gatekeeper-limitclusteradmin
spec:
predicates:
- requiredClusterSelector:
labelSelector:
matchExpressions: []
---
apiVersion: policy.open-cluster-management.io/v1
kind: PlacementBinding
metadata:
name: binding-gatekeeper-limitclusteradmin
placementRef:
apiGroup: cluster.open-cluster-management.io
kind: Placement
name: placement-gatekeeper-limitclusteradmin
subjects:
- apiGroup: policy.open-cluster-management.io
kind: Policy
name: gatekeeper-limitclusteradmin
2 changes: 1 addition & 1 deletion community/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ Policies in this folder are organized by [NIST Special Publication 800-53](https
- [System and Information Integrity](#system-and-information-integrity)
- [Templatized Policies](#templatized-policies)
- [Deploying community policies to your cluster](#deploying-community-policies-to-your-cluster)
- [Custom policy controllers](#custom-policy-controllers)
- [Policy consumers on operator hub](#policy-consumers-on-operator-hub)
- [Other custom policy consumers](#other-custom-policy-consumers)

Expand All @@ -42,6 +41,7 @@ Policy | Description
------- |------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -------------
[Disallowed roles policy](./AC-Access-Control/policy-roles-no-wildcards.yaml) | Use the disallowed roles policy to make sure no pods are being granted full access in violation of least privilege. | Check [Using RBAC Authorization](https://kubernetes.io/docs/reference/access-authn-authz/rbac/) to learn more about Kubernetes RBAC authorization.
[Disallowed anonymous authentication](./AC-Access-Control/policy-gatekeeper-disallow-anonymous.yaml) | Use the disallowed anonymous authentication policy to make sure that the system:anonymous user and system:unauthenticated group are not associated with any ClusterRole / Role in the environment | See the [Gatekeeper documentation](https://github.com/open-policy-agent/gatekeeper). **Note**: Gatekeeper controllers must be installed to use the gatekeeper policy.
[Limit user bindings to ClusterRole](./AC-Access-Control/policy-gatekeeper-limitclusteradmin.yaml) | This Gatekeeper Policy is intended to match the behavior of the deprecated ACM IAMPolicy Controller. It will allow an administrator to monitor and alert if `ClusterRoleBindings` with the specified `ClusterRole` exceed the maximum number of users. In the case where a Group is specified in the `ClusterRoleBinding` the number of users in the group are counted. ServiceAccounts are ignored. | See the [Gatekeeper documentation](https://github.com/open-policy-agent/gatekeeper). **Note**: The Policy makes use of sync data from the cluster to have knowledge of the existing `ClusterRoleBindings` and `Groups`.
[Configure RBAC for Application workloads ](./AC-Access-Control/policy-configure-appworkloads-rbac-sample.yaml) | Use this policy to configure a role based access control model for application workloads running on managed-clusters. This is a sample policy. | This sample policy must be modified for your environment. Check [Using RBAC Authorization](https://kubernetes.io/docs/reference/access-authn-authz/rbac/) to learn more about Kubernetes RBAC authorization.
[Configure RBAC for Administering policies ](./AC-Access-Control/policy-rbac-adminiterpolicies-sample.yaml) | Use this policy to configure a role based access control model on the hub for administering policies in a multi team environment. | Check [Using RBAC Authorization](https://kubernetes.io/docs/reference/access-authn-authz/rbac/) to learn more about Kubernetes RBAC authorization.
[Configure RBAC using groups in openshift for hub and managed clusters using admin and view-only roles ](./AC-Access-Control/policy-configure-clusterlevel-rbac.yaml) | Use this policy to configure a role based access control model on the hub to have a view-only access to desired managed clusters along with admin access to hub cluster based on groups to which the users belongs to. | This sample policy must be modified for your environment, Check [Using RBAC Authorization](https://kubernetes.io/docs/reference/access-authn-authz/rbac/) to learn more about Kubernetes RBAC authorization.
Expand Down

0 comments on commit 89fe5a3

Please sign in to comment.