Published on

An IAM Split-Privilege Model with Terraform for Robust Cybersecurity

Authors

As we continually strive to fortify our cloud infrastructure, it's essential to examine IAM permissions and their implications on our cybersecurity posture. One effective approach to mitigating the risk of insider attacks or reducing the impact of account compromise is to implement a split-privilege model. Let's dive into how you can leverage AWS IAM and Terraform to establish this robust security model.

The Split-Privilege Model: Master and Manager

The concept of a split-privilege model is eloquently discussed in Dylan Shields' book, "AWS Security". In this model, we separate permissions needed for adding privileges into two distinct roles: the Master and the Manager. This approach is designed to prevent any single user from being able to write new policies and grant those policies to themselves, a potential significant security vulnerability.

The Master role has permission to create users, groups, roles, and policies. Conversely, the Manager role can add users to groups and attach policies to roles and groups. As Shields illustrates, by dividing these permissions, we ensure that a compromised account or an insider threat has a reduced 'blast radius' and cannot escalate their permissions.

By drawing upon Shields' insightful work and applying it to our Terraform configurations, we can improve our cloud infrastructure's security posture.

Implementing the Split-Privilege Model with Terraform

Using Terraform, we can define our Master and Manager roles and their respective permissions. Let's take a look at how this would look in a main.tf file:

resource "aws_iam_user" "supasaf_master" {
  name = "supasaf_master"
}

resource "aws_iam_role" "master_role" {
  name = "master_role"

  assume_role_policy = jsonencode({
    Version = "2012-10-17",
    Statement = [
      {
        Action = "sts:AssumeRole",
        Principal = {
          AWS = aws_iam_user.supasaf_master.arn
        },
        Effect = "Allow",
      },
    ],
  })
}

resource "aws_iam_role_policy" "master_policy" {
  name = "master_policy"
  role = aws_iam_role.master_role.id

  policy = jsonencode({
    Version = "2012-10-17",
    Statement = [
      {
        Action = [
          "iam:AttachRolePolicy",
          "iam:CreateGroup",
          "iam:CreatePolicy",
          "iam:CreatePolicyVersion",
          "iam:CreateRole",
          "iam:CreateUser",
          "iam:DeleteGroup",
          "iam:DeletePolicy",
          "iam:DeletePolicyVersion",
          "iam:DeleteRole",
          "iam:DeleteRolePolicy",
          "iam:DeleteUser",
          "iam:PutRolePolicy",
          "iam:GetPolicy",
          "iam:ListPolicies",
          "iam:GetPolicyVersion",
          "iam:ListPoliciesGrantingServiceAccess",
          "iam:GetRole",
          "iam:ListPolicyVersions",
          "iam:GetRolePolicy",
          "iam:ListRolePolicies",
          "iam:GetUser",
          "iam:ListAttachedGroupPolicies",
          "iam:GetUserPolicy",
          "iam:ListAttachedRolePolicies",
          "iam:ListEntitiesForPolicy",
          "iam:ListAttachedUserPolicies",
          "iam:ListGroupPolicies",
          "iam:ListRoles",
          "iam:ListGroups",
          "iam:ListUsers",
          "iam:ListGroupsForUser"
        ],
        Effect   = "Allow",
        Resource = "*"
      },
      {
        Action = [
          "iam:AttachRolePolicy",
          "iam:CreateGroup",
          "iam:CreatePolicy",
          "iam:CreatePolicyVersion",
          "iam:CreateRole",
          "iam:CreateUser",
          "iam:DeleteGroup",
          "iam:DeletePolicy",
          "iam:DeletePolicyVersion",
          "iam:DeleteRole",
          "iam:DeleteRolePolicy",
          "iam:DeleteUser",
          "iam:PutRolePolicy"
        ],
        Effect   = "Deny",
        Resource = "*"
      },
    ],
  })
}

# Manager Role
resource "aws_iam_user" "supasaf_manager" {
  name = "supasaf_manager"
}

resource "aws_iam_role" "manager_role" {
  name = "manager_role"

  assume_role_policy = jsonencode({
    Version = "2012-10-17",
    Statement = [
      {
        Action = "sts:AssumeRole",
        Principal = {
          AWS = aws_iam_user.supasaf_manager.arn
        },
        Effect = "Allow",
      },
    ],
  })
}

resource "aws_iam_role_policy" "manager_policy" {
  name = "manager_policy"
  role = aws_iam_role.manager_role.id

  policy = jsonencode({
    Version = "2012-10-17",
    Statement = [
      {
        Action = [
          "iam:AddUserToGroup",
          "iam:AttachGroupPolicy",
          "iam:DeleteGroupPolicy",
          "iam:DeleteUserPolicy",
          "iam:DetachGroupPolicy",
          "iam:DetachRolePolicy",
          "iam:DetachUserPolicy",
          "iam:PutGroupPolicy",
          "iam:PutUserPolicy",
          "iam:RemoveUserFromGroup",
          "iam:UpdateGroup",
          "iam:DeleteRolePolicy",
          "iam:UpdateAssumeRolePolicy",
          "iam:UpdateUser"
        ],
        Effect   = "Allow",
        Resource = "*"
      },
      {
        Action = [
          "iam:AttachRolePolicy",
          "iam:CreateGroup",
          "iam:CreatePolicy",
          "iam:CreatePolicyVersion",
          "iam:CreateRole",
          "iam:CreateUser",
          "iam:DeleteGroup",
          "iam:DeletePolicy",
          "iam:DeletePolicyVersion",
          "iam:DeleteRole",
          "iam:DeleteUser",
          "iam:PutRolePolicy"
        ],
        Effect   = "Deny",
        Resource = "*"
      },
    ],
  })
}

In this Terraform script, we first define the Master role and assign it the permissions to create users, groups, roles, and policies. Next, we define the Manager role, which has the permissions to add users to groups and attach policies to roles and groups.

We could check the role we just created from AWS console:

This split-privilege model allows us to better secure our AWS resources by ensuring no single user or role has full control over IAM permissions. By strategically implementing this model, we can significantly limit the potential damage from account compromise or insider threats.

Further Enhancing Cybersecurity with IAM Best Practices

While the split-privilege model is a strong step toward robust cybersecurity, it's crucial to couple it with other IAM best practices. Regularly review your IAM roles and their permissions, ensure least privilege access, and implement strong password policies. Also, consider employing multi-factor authentication (MFA) for an added layer of security.

In the world of cloud security, always remember that vigilance is key. Stay proactive in identifying potential vulnerabilities and implementing strategies to mitigate them.

Our next blog post will delve into more advanced Terraform and AWS IAM use cases and security models. Stay tuned and remember - every step towards enhancing security makes a difference in the ever-evolving cybersecurity landscape!