aws-cdk icon indicating copy to clipboard operation
aws-cdk copied to clipboard

aws-eks: support setting KubernetesGroups in AccessEntry

Open Xfel opened this issue 1 year ago • 9 comments

Describe the feature

AccessEntry is the new mechanism to specify EKS API access, avoiding the previous cyclic nature of having to edit the aws-auth configmap.

There are two ways to grant permissions via AccessEntry.

  1. AccessPolicies, pre-defined roles that need not exist inside the cluster
  2. Specifying group names that can then be used in regular RoleBindings and ClusterRoleBindings.

The L2 AccessEntry construct added in #30016 only supports the first versions.

While the AccessPolicies are an easy way to add permissions without having to be able to access the cluster API to do so, it is not possible to define custom ones for a more fine-grained permission control. For that, we need to be able to set the group names and use those in the regular Kubernetes role system.

Use Case

To grant custom roles in kubernetes to a User or Role from IAM.

Proposed Solution

Add a "kubernetesGroups" parameter to the AccessEntry construct. Also, the "accessPolicies" parameter should be optional to allow specifying an AccessEntry that only uses the group mapping.

A variant of the "grantAccess" method on the cluster that accepts group names would also be useful.

Other Information

No response

Acknowledgements

  • [ ] I may be able to implement this feature request
  • [ ] This feature might incur a breaking change

CDK version used

2.146.0

Environment details (OS name and version, etc.)

all

Xfel avatar Jun 20 '24 20:06 Xfel

Thank you @Xfel .

Are you proposing to support custom group names used in RoleBindings and ClusterRoleBindingsthat and map the custom groups to IAM roles without using pre-defined access entries?

I will need some investigation but could you share some real use cases where you need to define a custom group like that and why access entries would not be sufficient?

Thanks.

pahud avatar Jun 21 '24 13:06 pahud

Add a "kubernetesGroups" parameter to the AccessEntry construct. Also, the "accessPolicies" parameter should be optional to allow specifying an AccessEntry that only uses the group mapping.

Yes, we havn't implemented KubernetesGroups yet and AccessPolicies should be optional.

I guess the experience would be like

new AccessEntry(scope, id, {
  cluster, 
  principal, 
  kubernetesGroups: ['group1', 'group2'],
});

Is this something you expect?

pahud avatar Jun 21 '24 14:06 pahud

Exactly.

One real use case is that we have a buildserver role for restarting services in kubernetes as part of a nightly deployment. This role should operate under least privileges, so the access policy would be too broad. Additionally, it should also only have access to a limited set of namespaces, but that set of namespaces may change independently. Such a thing is easy by deploying a properly configured RoleBinding in each affected namespace, but when using AccessPolicies the list of namespaces must be specified eagerly in the AccessEntry.

Xfel avatar Jun 21 '24 16:06 Xfel

@Xfel

Thank you for your case sharing.

Can you share some sample manifests for the custom group so I can test it when I work on a pull request?

pahud avatar Jun 21 '24 20:06 pahud

This issue has not received a response in a while. If you want to keep this issue open, please leave a comment below and auto-close will be canceled.

github-actions[bot] avatar Jun 24 '24 00:06 github-actions[bot]

OK I guess we can test it this way

  1. This creates a ClusterRoleBinding that binds the "edit" ClusterRole to the "my-group" group:
kubectl create clusterrolebinding my-group --clusterrole=edit --group=my-group
  1. Use the group in a RoleBinding: Once the group is created, use it in a RoleBinding to grant permissions to the group within a specific Namespace.Here's an example RoleBinding that grants the "edit" Role to the "my-group" group in the "my-namespace" Namespace:
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: my-group-edit
  namespace: my-namespace
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: Role
  name: edit

This RoleBinding binds the "edit" Role to the "my-group" group within the "my-namespace" Namespace.

  1. Similarly, use the group in a ClusterRoleBinding to grant cluster-wide permissions to the group.Here's an example ClusterRoleBinding that grants the "cluster-admin" ClusterRole to the "my-group" group:
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: my-group-cluster-admin
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: cluster-admin

Now, create an AccessEntry that maps my-group to a specific IAM principal:

new AccessEntry(scope, id, {
  cluster, 
  principal, 
  kubernetesGroups: ['my-group'],
});

Is this correct?

pahud avatar Jun 24 '24 14:06 pahud

You are missing the subjects entry in your YAML to bind to the group:

subjects:
- apiGroup: rbac.authorization.k8s.io
  kind: Group
  name: my-group

And 1 and 3 are both ClusterRoleBinding for the purpose of tests.


As a workaround currently can be used:

cluster.grantAccess('id', principalArn, []);
Aspects.of(cluster).add({ visit: node => {
  if (node instanceof CfnAccessEntry && node.principalArn === principalArn) node.kubernetesGroups = [ 'my-group' ];
} });

Hazzard17h avatar Jul 22 '24 16:07 Hazzard17h

Is this not being worked on anymore? We would also love to see this feature being available in the AccessEntry construct

ariksidney avatar Feb 28 '25 15:02 ariksidney

Me too, maybe I start a new try to get this merged

markussiebert avatar Mar 27 '25 11:03 markussiebert