Securing EKS Deployments with IAM and RBAC Manager

2024-06-25

·

Nick

eks

aws

security

We are a 24/7 globally distributed team

In the dynamic world of DevOps, the convenience of automated deployments can sometimes lead to compromises in security. A common scenario involves using a single IAM user with extensive permissions for deploying code across multiple namespaces in an Amazon EKS cluster. While this setup simplifies the deployment process, it poses significant security risks, especially in a shared cluster environment. In this blog, we'll explore how to enhance security by restricting deployment permissions using AWS IAM and RBAC Manager.

The Problem

Engineers often use a GitHub Actions pipeline with wide permissions to deploy code to Kubernetes. This is quick way to get your deployment working but it allows the pipeline unrestricted access to perform tasks across any namespace within the cluster. In a shared cluster, where services are managed by different teams, such broad permissions can lead to potential breaches and issues.

The Solution: IAM and RBAC Manager

To address these security concerns, we can adopt a more granular permission model using AWS IAM and Kubernetes RBAC. Here’s how you can implement it.

Step 1: Restrict IAM User Permissions Instead of granting broad permissions, create an IAM user specifically for your CI/CD pipelines with only the necessary permissions. Initially, attach a policy that only allows the IAM user to describe the EKS cluster.

resource "aws_iam_user" "ui_user" {
  name = "eks-ui-user"
}

resource "aws_iam_policy" "ui_policy" {
  name = "eks-ui-policy"
  policy = jsonencode({
    Version = "2012-10-17"
    Statement = [
      {
        Action = [
          "eks:DescribeCluster"
        ]
        Effect   = "Allow"
        Resource = ["arn:aws:eks:us-east-1:${local.aws_account_id}:cluster/prod-cluster"]
      },
      {
        Action = [
          "ecr:BatchGetImage",
          "ecr:BatchCheckLayerAvailability",
          "ecr:CompleteLayerUpload",
          "ecr:GetDownloadUrlForLayer",
          "ecr:InitiateLayerUpload",
          "ecr:PutImage",
          "ecr:UploadLayerPart"
        ]
        Effect   = "Allow"
        Resource = [
          "arn:aws:ecr:us-east-1:${local.aws_account_id}:repository/ui"
        ]
      },
      {
        Action = [
          "ecr:GetAuthorizationToken"
        ]
        Effect   = "Allow"
        Resource = "*"
      }
    ]
  })
}

resource "aws_iam_user_policy_attachment" "ui_user_policy_attachment" {
  user       = aws_iam_user.ui_user.name
  policy_arn = aws_iam_policy.ui_policy.arn
}

This policy restricts the IAM user to only fetching details about the EKS cluster and only allowing to push into a specific ECR.

Step 2: Use RBAC Manager to Create Roles

With RBAC Manager, you can create roles within your Kubernetes cluster that allow you to deploy into a specific namespace.

First, you need to install rbac-manager by using Helm:

helm repo add fairwinds-stable https://charts.fairwinds.com/stable
helm install rbac-manager fairwinds-stable/rbac-manager --namespace rbac-manager

And then you'll be able to deploy the role:

resource "kubernetes_manifest" "rbac_definition" {
  manifest = {
    apiVersion = "rbacmanager.reactiveops.io/v1beta1"
    kind       = "RBACDefinition"
    metadata = {
      name      = "ui"
    }
    rbacBindings = [
      {
        name = "ui-binding"
        subjects = [
          {
            kind = "Group"
            name = "ui:edit"
          }
        ]
        roleBindings = [
          {
            clusterRole        = "edit"
            namespaceSelector = {
              ui = "edit"
            }
          }
        ]
      }
    ]
  }
}

Step 3: Bind IAM Users to Kubernetes Roles

Finally, bind the IAM user to the Kubernetes role using the AWS-auth ConfigMap. This binding ensures that the IAM user's permissions are aligned with the Kubernetes role, enforcing namespace-specific deployment permissions.

    {
      userarn  = data.terraform_remote_state.prod.outputs.ui_user_arn
      username = data.terraform_remote_state.prod.outputs.ui_user_name
      groups   = ["ui:edit"]
    }

You can now deploy into the specific namespace you chose, and no others. If you try to deploy into a namespace for which you don't have permission, you'll get an error like the following:

Error from server (Forbidden): pods is forbidden: User "ui-user" cannot create resource "pods" in API group "" in the namespace "default"
Error: Process completed with exit code 1.

Conclusion

By integrating IAM and RBAC Manager, you can effectively segregate deployment permissions within a shared EKS cluster. This approach not only enhances security but also ensures that each team has the autonomy to manage their services independently, without interfering with each other. Implementing such granular controls helps maintain a robust and secure infrastructure in multi-team environments.

Subscribe to get
the latest updates

Our HQ Locations

Copenhagen Denmark

Melbourne Australia

Tallinn Estonia

Privacy policy||

Copyright © 2024. All rights reserved