Migration & Modernization

How to switch between Active Directory and External IdP (or vice versa) in AWS IAM Identity Center with Automation

In this blog post, we will explore a solution for organizations looking to switch between Microsoft Active Directory (AD) and an external Identity Provider (IdP) in AWS IAM Identity Center. Organizations may need to change the identity source in IAM Identity Center for various reasons, driven by business requirements or technological considerations. Some common motivations include mergers and acquisitions, cost efficiency, compliance requirements or scalability and performance. IAM Identity Center supports different types of IdPs such as AD, Google, Cyber Ark, Ping Identity, Entra ID, or the IAM Identity Center itself can act as an identity source.

Although you can change your identity source at any time in IAM Identity Center, there are some considerations for changing your identity source. For example, if you change your identity source from an external IdP to AD or from AD to an external IdP, consider the following.

  • Users, groups, and assignments are deleted – All users, groups, and assignments are deleted from IAM Identity Center. No user or group information is affected in either the external IdP or AD.
  • Provisioning users – If you change to an external IdP, you must configure IAM Identity Center to provision users. Alternatively, you must manually provision the users and groups for the external IdP before you can configure assignments.
  • Create assignments and groups – If you change to AD, you must create assignments with the users and groups that are in your AD.

Solution Overview

A high level overview of the solution presented in this blog is shown in Figure 1:

Diagram with Identity Provider options on the left side, AWS IAM Identity Center in the middle, a box representing multiple AWS Account on the right side. The python script provided interacts with IAM Identity Center via API Calls while either reading desired state from comma-separated value files to perform the API calls; or writing out API call result information to comma-separated value files.

Figure 1 – Solution overview

The script provided allows you to retrieve and set information on an Organization Identity Center instance. The script utilizes boto3 calls to organizations, sso-admin and identitystore to perform these actions.

There are 3 main actions available.

  1. List users and groups (principals) available in IAM Identity Center along with key identifying attributes.
  2. List entitlement assignments. An entitlement assignment is a combination of an AWS Account ID, a permission set and the principal (IAM Identity Center user or group) these are assigned to.
  3. Create new entitlement assignments provided in a CSV file that contains the account ID, permission set, and principal that form the assignment.

The main purpose of the Python script is to eliminate manual steps and to preserve a documented record of the configuration changes required to switch identity providers from AD to other IdPs. Having fewer manual steps reduces the probability of a system disruption.

Prerequisites

  1. IAM Identity Center is deployed in the organization with a connected external IdP or Active Directory.
  2. Before running the script, ensure that you have configured a break-glass access mechanism in your AWS environment. Break-glass access allows you to regain control of your AWS environment in case of emergency situations, such as when your primary identity source becomes unavailable. You can refer to, Setup emergency access to the AWS Management Console and the aws-break-glass-role project on GitHub for more information on setting up this access.
  3. IAM credentials with necessary permissions to create, manage, and deploy permissions sets to your AWS accounts.

Solution Deployment

The following are the IAM permissions required for the administrative user to perform assignment operations.

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "AWSorgAccess",
            "Effect": "Allow",
            "Action": [
                "organizations:ListAccounts",
                "sts:GetCallerIdentity"
            ],
            "Resource": "*"
        },
        {
            "Sid": "AWSIdentityCenterAccess",
            "Effect": "Allow",
            "Action": [
                "sso:ListInstances",
                "sso:ListPermissionSets",
                "sso:DescribePermissionSet",
                "sso:ListPermissionSetsProvisionedToAccount",
                "sso:ListAccountAssignments",
                "sso:CreateAccountAssignment",
                "sso:DescribeAccountAssignmentCreationStatus"
            ],
            "Resource": "arn:aws:sso:::*/*"
        },
        {
            "Sid": "IAMRoleAccess",
            "Effect": "Allow",
            "Action": [
                "iam:AttachRolePolicy",
                "iam:CreateRole",
                "iam:GetRole",
                "iam:ListAttachedRolePolicies",
                "iam:ListRolePolicies",
                "iam:PutRolePolicy"
            ],
            "Resource": "arn:aws:iam::*:role/aws-reserved/sso.amazonaws.com/*"
        },
        {
            "Sid": "SAMLproviderAccess",
            "Effect": "Allow",
            "Action": "iam:GetSAMLProvider",
            "Resource": "arn:aws:iam::*:saml-provider/AWSSSO_*_DO_NOT_DELETE"
        },
        {
            "Sid": "IdentityStoreRead",
            "Effect": "Allow",
            "Action": [
                "identitystore:ListGroups",
                "identitystore:ListUsers"
            ],
            "Resource": "arn:aws:identitystore::*:identitystore/*"
        },
        {
            "Sid": "IdentityStoreGroupRead",
            "Effect": "Allow",
            "Action": "identitystore:ListGroups",
            "Resource": "arn:aws:identitystore:::group/*"
        },
        {
            "Sid": "IdentityStoreUserRead",
            "Effect": "Allow",
            "Action": "identitystore:ListUsers",
            "Resource": "arn:aws:identitystore:::user/*"
        }
    ]
}

Deploy the script from the GitHub repository

  1. Install the AWS CLI or execute from AWS CloudShell.
  2. Download or clone the GitHub repository using the following commands (Table 1).
    Table 1 – Clone the git repository
    $ git clone https://github.com/aws-samples/how-to-switch-between-active-directory-and-external-idp-or-vice-versa-in-aws-iam-identity-center.git
    $ cd how-to-switch-between-active-directory-and-external-idp-or-vice-versa-in-aws-iam-identity-center
    
  3. Running python main.py -h displays all the different options available in the script (Table 2). Note that Python3.11 or later is required.
    Table 2 – Script options
    usage: main.py [-h] [-v] [-l] [-p] [-s] [-c] [-o OUTPUT] [-i INPUT] [-d DEBUG] [--profile PROFILE]
    
    options:
    -h, --help            show this help message and exit
    -v, --verbose         Verbose output
    -l, --list            Returns all permission set to account assignment information.
    -p, --principals      Returns all user and group principals found in AWS IAM Identity Center.
    -s, --set             Assign permission sets to AWS accounts and groups/users. Use -c to stay in a loop checking request results instead of exiting immediately.
    -c, --check           Requires -s to work. Loops checking the assignment request status every few seconds.
    -o OUTPUT, --output OUTPUT
    Output file for -l --list, -p --principals.
    -i INPUT, --input INPUT
    Input file for -s --set.
    -d DEBUG, --debug DEBUG
    Debug log file, always utilize the highest verbosity possible for the log messages.
    --profile PROFILE     AWS Session profile name (when using named profiles instead of default).
    
  4. Run python main.py -p -o users-groups-before-switch.csv --profile profile_name which outputs all the users and groups available in IAM Identity Center directory to a file, users-groups-before-switch.csv. If the profile_name is not provided the script will use the boto3 credential resolution process to obtain AWS credentials. Example output shown in Table 3.
    Table 3 – Example output
    user_or_group,principal_name,principal_id,identity_store_id
    USER,johnd@example.com,28c173c0-10c1-70fb-e2c2-aa5c852f0ac2,d-9267757dce
    USER,kumar@example.com,08d19360-4091-70cc-557a-406b85eae56f,d-9267757dce
    USER,Alpha@example.com,d8f133a0-6011-70d0-1d8d-582ffd79712a,d-9267757dce
    USER,jane@example.com,38a12380-10c1-7038-4f7b-5283bd12429b,d-9267757dce
    GROUP,AWS-Admins,982133b0-60b1-708b-c792-3417cd12b105,d-9267757dce
    
  5. Run python main.py -l -o idc-assignments-before-switch.csv --profile profile_name which outputs all the current assignments to a file, idc-assignments-before-switch.csv which can be used for comparison. Example output shown in Table 4.
    Table 4 – Example output of user/group assignments
    account_id,permission_set,principal_name,user_or_group
    123456789,AWSCloudShellAccess,jane@example.com,USER
    123456789,AWSAdministratorAccess,AWS-Admins,GROUP
    123456789,AWSAdministratorAccess,kumar@example.com,USER
    987654321,AWSReadOnlyAccess,jane@newexample.com,USER
    987654321,AWSDeveloperAccess,jane@newexample.com,USER
    987654321,AWSNeworkAdministratorAccess,AWS-Admins,GROUP
    

    Before moving to the next step, it is a good idea to audit the currently assigned permission sets to ensure least-privilege access. This can be achieved by using IAM Access Analyzer which continuously monitors permissions of roles and users that are granted but are not used. Example finding by IAM Access Analyzer for a role created by IAM Identity Center that is unused (Figure 2).

    Screen Capture of the Identity and Access Management console showing a single unused IAM role finding under Access Reports, Access Analyzer, Unused access section.

    Figure 2 – IAM Access Analyzer finding details

  6. Follow the steps described in Change your identity source to switch from AD to an external IdP or vice versa. Keep in mind that changing your identity source to or from AD deletes users and groups from the IAM Identity Center directory. This change also removes any assignments that you configured in IAM Identity Center. This should be carefully executed only after you ensure that all the user, groups, and their assignments are safely backed up using step 4 and Step 5.
  7. Once the identity source has been successfully changed and the users and groups have been provisioned to AWS IAM Identity Center either using AD Sync or SCIM provisioning proceed to the following steps.
  8. Run python main.py -p -o users-groups-after-switch.csv --profile profile_name, which outputs all the users and groups to users-groups-after-switch.csv file. Compare the output with the previously generated users-groups-before-switch.csv file to ensure that no users/groups are missing after provisioning.
  9. Create a new permission set mapping CSV file which can be used as an input to the script to recreate the permission set assignments to users and groups. You can use the contents of the idc-assignments-before-switch.csv as it is or modify the mapping to your organization’s specific requirements. Make sure to account for possible IdP identifier changes. Please make sure to keep the file format as same with headers for example, idc-assignments.csv(Table 5).
    Table 5 – Example output of idc_assignments.csv
    account_id,permission_set,principal_name,user_or_group
    123456789,AWSCloudShellAccess,jane@example.com,USER
    123456789,AWSAdministratorAccess,AWS-Admins,GROUP
    123456789,AWSAdministratorAccess,kumar@example.com,USER
    987654321,AWSReadOnlyAccess,jane@newexample.com,USER
    987654321,AWSDeveloperAccess,jane@newexample.com,USER
    987654321,AWSNeworkAdministratorAccess,AWS-Admins,GROUP
    
  10. Run python main.py -i idc-assignments.csv -s -c to create the permission set assignments. Using the -s option assigns the permission sets to AWS accounts and groups or users. Use -c to stay in a loop checking request results instead of exiting the script immediately. Example output of a successful execution, shown in Table 6.
    Table 6 – Example output of a successful execution
    Waiting 5 seconds
     Request ['123456789', 'AWSCloudShellAccess', 'jane@newexample.com', 'USER'], status: SUCCEEDED
     Request ['123456789', 'AWSCloudShellAccess', 'jane@newexample.com', 'USER'], status: SUCCEEDED
     Request ['987654321', 'AWSCloudShellAccess', 'jane@newexample.com', 'USER'], status: SUCCEEDED
     Request ['987654321', 'AWSCloudShellAccess', 'AWS-Admins', 'GROUP'], status: SUCCEEDED
    
  11. Confirm that the permission set assignments are correct by checking in the AWS IAM Identity Center Console or by running the script with the --list option as explained in step 5 and comparing the files.

Conclusion

Switching between AD and an external Identity Provider (IdP) in AWS IAM Identity Center can be a complex and time-consuming process, especially for organizations with a large number of users, groups, and assignments. By leveraging the solution provided in this blog post, you can streamline the transition process, minimize downtime, and ensure a smooth handover of user access and permissions.


About the Authors