【With Step-by-Step Images】Setting Up Active Directory and IAM Identity Center Integration 2: Restricting VPCs Using Tags

Setting Up Active Directory and IAM Identity Center Integration 2: Restricting VPCs Using Tags
  • By integrating Active Directory with IAM Identity Center, we grant access to employees who need to use AWS. However, it is necessary to strictly control access permissions for each employee.
  • In this article, we explain how to restrict available VPCs using tags.
  • We will visually guide you through the process of customizing permission sets and assigning minimal permissions using images and screenshots.

This article is a continuation of the previous post:
For details on how to integrate Active Directory and IAM Identity Center, refer to the article below.

Background

Previously, we granted access permissions to employees who needed to use AWS for a specific project. Now, with AWS being considered for another project, it is expected that AWS usage will expand not only in the operational environment but also across various projects in the future.
Since Active Directory and IAM Identity Center are already integrated, we decided to grant permissions to employees who require access as we did previously.

Challenges

In the previous setup, no particular restrictions were applied, and the pre-defined PowerUserAccess policy in AWS was used. However, since PowerUserAccess grants extensive permissions, we took this opportunity to establish a more controlled approach to minimize permissions. Our goals include:

  • Preventing changes, deletions, or deployments of resources in VPCs used by other projects.
  • Enabling identification of which project a VPC is associated with.
  • Restricting the use of unnecessary AWS services.

Method

In the previous setup, access permissions to AWS accounts were defined using permission sets in IAM Identity Center and assigned to users.

This time, permission sets will be defined for each project and assigned to users belonging to those projects.
Each permission set will restrict available VPCs based on tags. This allows us to separate access permissions for each project.
Here’s a simplified illustration:

However, an important point to consider is that there are employees, such as User 2, who belong to multiple projects.
In IAM Identity Center, it is possible to assign multiple permission sets to a single user.
Therefore, for users participating in multiple projects, we will grant multiple access permissions.

Administrator’s Procedure

Groups are already created in Active Directory, and the current users and groups in IAM Identity Center are as follows:
We will delete the previously assigned permission set (PowerUserAccess) and proceed by creating new permission sets.

Image

Now, we’ll set up access permissions for users assigned to Project B.
The permissions will allow creation, updating, and deletion only for specific VPCs while granting read access to all resources.

Creating Permission Sets

We will assign a custom policy along with AWS-defined ReadOnlyAccess and AmazonEC2FullAccess.
While the previous permission set was created using the Management Console, this time we will use the AWS CLI.

Description: Provides read-only access to AWS services and resources.

https://docs.aws.amazon.com/aws-managed-policy/latest/reference/ReadOnlyAccess.html

Description: Provides full access to Amazon EC2 via the AWS Management Console.

https://docs.aws.amazon.com/aws-managed-policy/latest/reference/AmazonEC2FullAccess.html
  1. Execute the following AWS CLI command to create the permission set.
INSTNACE_ARN=$(aws sso-admin list-instances \
    --query "Instances[].InstanceArn" \
    --output text)

aws sso-admin create-permission-set \
    --instance-arn $INSTNACE_ARN \
    --name "ProjectB" \
    --session-duration "PT1H"
  1. Execute the following AWS CLI command to attach the AWS pre-defined ReadOnlyAccess policy and AmazonEC2FullAccess policy.
PERMISSIONSET_ARN=$(aws sso-admin list-permission-sets \
    --instance-arn $INSTNACE_ARN \
    --query "PermissionSets" \
    --output text | tr "\t" "\n" | 
    while read line
    do
       aws sso-admin describe-permission-set \
           --instance-arn $INSTNACE_ARN \
           --permission-set-arn ${line} \
           --query "PermissionSet.[Name,PermissionSetArn]" \
           --output text
    done | grep -w "ProjectB" | awk '{print $2}')

aws sso-admin attach-managed-policy-to-permission-set \
    --instance-arn $INSTNACE_ARN \
    --permission-set-arn $PERMISSIONSET_ARN \
    --managed-policy-arn "arn:aws:iam::aws:policy/ReadOnlyAccess"

aws sso-admin attach-managed-policy-to-permission-set \
    --instance-arn $INSTNACE_ARN \
    --permission-set-arn $PERMISSIONSET_ARN \
    --managed-policy-arn "arn:aws:iam::aws:policy/AmazonEC2FullAccess"
  1. Execute the following AWS CLI command to attach an inline policy.
cat << EOF > inline-policy.json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "DenyCreateVpc",
            "Effect": "Deny",
            "Action": [
                "ec2:CreateVpc"
            ],
            "Resource": "*",
            "Condition": {
                "StringNotEqualsIfExists": {
                    "aws:RequestTag/Project": "ProjectB"
                }
            }
        },
        {
            "Sid": "DenyChangeTag",
            "Effect": "Deny",
            "Action": [
                "ec2:CreateTags"
            ],
            "Resource": "*",
            "Condition": {
                "Null": {
                    "ec2:ResourceTag/Project": "false"
                },
                "StringNotEquals": {
                    "ec2:ResourceTag/Project": "ProjectB"
                }
            }
        },
        {
            "Sid": "DenyModifyAndDelete",
            "Effect": "Deny",
            "Action": [
                "ec2:Delete*",
                "ec2:ModifyVpcAttribute"
            ],
            "Resource": "*",
            "Condition": {
                "StringNotEquals": {
                    "ec2:ResourceTag/Project": "ProjectB"
                }
            }
        }
    ]
}
EOF

aws sso-admin put-inline-policy-to-permission-set \
    --instance-arn $INSTNACE_ARN \
    --permission-set-arn $PERMISSIONSET_ARN \
    --inline-policy file://inline-policy.json
  • DenyCreateVpc Statement
    The statement denies VPC creation if either of the following conditions is met:
    • The Project tag is not specified.
    • The specified Project tag value is anything other than ProjectB.
  • DenyChangeTag Statement
    The statement denies tag creation when all of the following conditions are met:
    • The resource’s Project tag is not null (the resource already has a Project tag).Note: Without this condition, creating VPCs with specified tags would also be denied.
    • The resource’s Project tag value is anything other than ProjectB.
  • DenyModifyAndDelete Statement
    The statement restricts operations on resources where the Project tag value is anything other than ProjectB. This includes:
    • Denying changes to VPC attributes.
    • Denying tag deletions, VPC deletions, etc.

Assign Groups

  1. Execute the following AWS CLI command to assign the permission set to a group.
IDENTITYSTORE_ID=$(aws sso-admin list-instances \
    --query "Instances[].IdentityStoreId" \
    --output text)
GROUP_ID=$(aws identitystore list-groups \
    --identity-store-id $IDENTITYSTORE_ID \
    --query "Groups[?DisplayName=='ProjectB@corp.awsexample.com'].GroupId" \
    --output text)
ACCOUNT_ID=$(aws sso-admin list-instances \
    --query "Instances[].OwnerAccountId" \
    --output text)

aws sso-admin create-account-assignment \
    --instance-arn $INSTNACE_ARN \
    --target-id $ACCOUNT_ID \
    --target-type AWS_ACCOUNT \
    --permission-set-arn $PERMISSIONSET_ARN \
    --principal-type GROUP \
    --principal-id $GROUP_ID

Additional Work

For other projects, proceed in a similar manner. Use the AWS CLI command shown earlier to create and assign permission sets for ProjectA.

AWS CLI Command
# Step1
INSTNACE_ARN=$(aws sso-admin list-instances \
    --query "Instances[].InstanceArn" \
    --output text)

aws sso-admin create-permission-set \
    --instance-arn $INSTNACE_ARN \
    --name "ProjectA" \
    --session-duration "PT1H"

# Step2
PERMISSIONSET_ARN=$(aws sso-admin list-permission-sets \
    --instance-arn $INSTNACE_ARN \
    --query "PermissionSets" \
    --output text | tr "\t" "\n" | 
    while read line
    do
       aws sso-admin describe-permission-set \
           --instance-arn $INSTNACE_ARN \
           --permission-set-arn ${line} \
           --query "PermissionSet.[Name,PermissionSetArn]" \
           --output text
    done | grep -w "ProjectA" | awk '{print $2}')

aws sso-admin attach-managed-policy-to-permission-set \
    --instance-arn $INSTNACE_ARN \
    --permission-set-arn $PERMISSIONSET_ARN \
    --managed-policy-arn "arn:aws:iam::aws:policy/ReadOnlyAccess"

aws sso-admin attach-managed-policy-to-permission-set \
    --instance-arn $INSTNACE_ARN \
    --permission-set-arn $PERMISSIONSET_ARN \
    --managed-policy-arn "arn:aws:iam::aws:policy/AmazonEC2FullAccess"

# Step3
cat << EOF > inline-policy.json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "DenyCreateVpc",
            "Effect": "Deny",
            "Action": [
                "ec2:CreateVpc"
            ],
            "Resource": "*",
            "Condition": {
                "StringNotEqualsIfExists": {
                    "aws:RequestTag/Project": "ProjectA"
                }
            }
        },
        {
            "Sid": "DenyChangeTag",
            "Effect": "Deny",
            "Action": [
                "ec2:CreateTags"
            ],
            "Resource": "*",
            "Condition": {
                "Null": {
                    "ec2:ResourceTag/Project": "false"
                },
                "StringNotEquals": {
                    "ec2:ResourceTag/Project": "ProjectA"
                }
            }
        },
        {
            "Sid": "DenyModifyAndDelete",
            "Effect": "Deny",
            "Action": [
                "ec2:Delete*",
                "ec2:ModifyVpcAttribute"
            ],
            "Resource": "*",
            "Condition": {
                "StringNotEquals": {
                    "ec2:ResourceTag/Project": "ProjectA"
                }
            }
        }
    ]
}
EOF

aws sso-admin put-inline-policy-to-permission-set \
    --instance-arn $INSTNACE_ARN \
    --permission-set-arn $PERMISSIONSET_ARN \
    --inline-policy file://inline-policy.json

# Step4
IDENTITYSTORE_ID=$(aws sso-admin list-instances \
    --query "Instances[].IdentityStoreId" \
    --output text)
GROUP_ID=$(aws identitystore list-groups \
    --identity-store-id $IDENTITYSTORE_ID \
    --query "Groups[?DisplayName=='ProjectA@corp.awsexample.com'].GroupId" \
    --output text)
ACCOUNT_ID=$(aws sso-admin list-instances \
    --query "Instances[].OwnerAccountId" \
    --output text)

aws sso-admin create-account-assignment \
    --instance-arn $INSTNACE_ARN \
    --target-id $ACCOUNT_ID \
    --target-type AWS_ACCOUNT \
    --permission-set-arn $PERMISSIONSET_ARN \
    --principal-type GROUP \
    --principal-id $GROUP_ID

Tag Policy Configuration

This step is not mandatory but is a beneficial configuration to consider.
By setting a tag policy, you can prevent the creation of duplicate tags that differ only in case (e.g., uppercase vs. lowercase).
Note that tag policies do not enforce tags; they are used as a guideline. While this could also be achieved by incorporating the aws:TagKeys condition into an inline policy, using a tag policy simplifies management and avoids overly complex inline policies.

To prevent duplicate tags with a key that varies only by case, use the aws:TagKeys condition to define the tag keys that your users can apply, or use tag policies, available with AWS Organizations. 

https://docs.aws.amazon.com/IAM/latest/UserGuide/access_tags.html
  1. Enable tag policies in your organization via the following URL:
    https://us-east-1.console.aws.amazon.com/organizations/v2/home/policies/tag-policy
Image
  1. Access the following URL to create a tag policy:
    https://us-east-1.console.aws.amazon.com/organizations/v2/home/policies/tag-policy/create
    • Policy name: Project
    • Tag key: Project
    • Compliance Options:
      • ☑ Use the capitalization that you’ve specified above for the tag key.
      • ☑ Specify allowed values for this tag key.
        • ProjectA
        • ProjectB
    • Resource types to enforce:
      • ☑ Prevent noncompliant operations for this tag.
        • Select all options.
Image
  1. Navigate to the [Target] tab and attach the policy to the required accounts.
Image

The tag policy ensures strict case sensitivity for both key and value and restricts values to specified options. Examples:

KeyValueAllowed?
ProjectProjectC❌ No
ProjecTProjectA❌ No
projectProjectA❌ No
Projectprojecta❌ No
ProjectProjectA✅ Yes
ProjectProjectB✅ Yes

User‘s Procedure

If MFA is already registered, you can skip steps 1 and 3.

  1. Install Google Authenticator (MFA app) on your smartphone.
    [Google Play / App Store]
  2. Access the following portal URL, enter your username and password.
    Replace <Directory ID> with your actual directory ID.
    https://<Directory ID>.awsapps.com/start
  3. Register MFA Device:
    • Select the authentication app.
    • Display the QR code.
    • Open Google Authenticator and scan the QR code.
    • Enter the six-digit authentication code displayed in the app.
  4. From the [Accounts] tab, select the permission set for the relevant project and log in.
Image

Employees are instructed to log in with the appropriate permission set for their current project. While switching between projects may seem cumbersome, using browser incognito or private windows allows simultaneous logins.

For now, we’ve restricted access to VPCs and granted user permissions. However, as the range of AWS services used expands, more restrictions will likely be needed. Although it seems challenging, inline policies will be updated as required.

Supplementary Information

ABAC (Attribute-Based Access Control) using IAM users or IAM Identity Center allows dynamic access restrictions based on user attributes, as described in the official documentation:

However, this approach does not seem to support assigning multiple access permissions to employees participating in multiple projects.
To address this limitation, we’ve opted for the more labor-intensive approach of creating multiple permission sets.

We will continue to explore better solutions moving forward.

タイトルとURLをコピーしました