Archived this solution due to AWS Organizations now supports service control policies (SCPs) in AWS China Regions
AWS Organizations provides central governance and management for multiple accounts. Central security administrators use service control policies (SCPs) with AWS Organizations to establish controls that all IAM principals (users and roles) adhere to.
However, Service Control Policies (SCPs) feature in AWS Organizations is not available in the China regions (BJS and ZHY) yet as time of writing.
This repository is part of the Chinese blog post that guides users through implementing a SCP Alternative Solution for China Region from scratch.
Please refer to branch release-1.0
for the code snippest used in the Chinese blog post.
For any new deployments, please refer to main
branch.
Please read the Limitation about the solution before deploying to your production environment.
Before diving into the architecture, let’s learn more about policy evaluation logic in AWS.
In an AWS account where SCP is applied, the above flow chart provides details about Determining whether a request is allowed or denied within an account .
In a multi account environment, you'll also need to consider Cross-account policy evaluation logic as the figure above.
Based on the evaluation logic in AWS multi-account environment, SCPs are similar to IAM boundaries, in that they define the maximum set of actions that can be allowed. The difference is that SCPs applies to principals of accounts, and IAM permission boundary applies to principals of IAM users and roles.
Based on the rationale above, the SCP alternative solution is to implement an automated pipeline to ensure the "SCP policies" are applied to all IAM user/roles within the target account by IAM permission boundary policy.
The purpose of the design is to simulate the native SCP as possible as we can, also considering the migration path to native SCP once it’s available.
The architecture is based on AWS native services, the core AWS services used are:
AccountId | MgtId | OuId | ScpCustomPolicyList (L) | ScpPolicyPathList (L) | ScpUpdateTime (S) |
---|---|---|---|---|---|
1123456789 | 2123456789 | OU-abcd-xxxxxxxx | [ { "S" : "arn:aws-cn:iam::1123456789:policy/CustomPermissionBoundaries" }] | [ { "S" : "permission-boundary-policy/ou-abcd-xxxxxxxxx.json" }] | Tue Jul 20 11:00:38 2021 |
The infrastructure required in this solution can be deployed by the CloudFormation templates.
Prior to deploying the solution to your environment, it is necessary to have the appropriate prerequisites. Verify that your AWS multi-account environment has the supported prerequisites before starting the installation.
Clone the repository, and switch to the top-level folder of the repo. Run make
command:
➜ make
zip assets/scp-s3-event-dispatcher.zip lambda/scp-s3-event-dispatcher.py
updating: lambda/scp-s3-event-dispatcher.py (deflated 74%)
zip assets/scp-iam-event-dispatcher.zip lambda/scp-iam-event-dispatcher.py
updating: lambda/scp-iam-event-dispatcher.py (deflated 77%)
zip assets/scp-account-register.zip lambda/scp-account-register.py
updating: lambda/scp-account-register.py (deflated 77%)
cp -f cloudformation/scp-service-catalog-product-template.yaml assets/scp-service-catalog-product-template.yaml
The lambda artifacts and the required cloudformation template are created under assets
directory:
➜ ls assets
scp-account-register.zip scp-s3-event-dispatcher.zip
scp-iam-event-dispatcher.zip scp-service-catalog-product-template.yaml
Login to Security account and perform the following deployment:
OrganizationAccessRoleName
) which won't attach the IAM permission boundary policy scp-enforce-policy
in the target account.Log in to the management account, select the CloudFormation template file 040-create-iam-role-in-master-account.yaml, and create an IAM role that allows the security account to assume to:
After the deployments, all required infra resources for the solutiion are created successfully. Follow the instructions below to manage the "SCP policies" in the alternative solution.
With the alternative solution, the SCP policy is defined in a json file and stored in S3 bucket. The SCP policy file for the Organization Unit or Account must exist in advance.
scp-alt-<Security-Account-ID>
.ou-47kj-8dquliyv.json
for demo purpose)
account-<ACCOUNT-ID>.json
<OrganizationUnit-ID>.json
permission-boundary-policy
in the S3 bucket manually if the folder doesn't existpermission-boundary-policy
For any AWS accounts which needs to be managed by the alternative solution, it's required to be registered and initilized via the SCP Service catalog product first.
Make sure the SCP policy file for the account or the organization unit is already uploaded to the S3 bucket above.
Service Catalog
service, choose the service catalog product SCP Account register
, and click launch:
enroll-account-0123456789012
0123456789012
ou-47kj-8dquliyv
CreateCloudTrail
- The option to create dedicated CloudTrail for the SCP solution. This can be set to "no" if the CloudTrail is already setup in the target account.Behind the sense, the lambda function scp-account-register deployed in security account will be triggered by the CloudFormation stack.
OrganizationAccountAccessRole
by default), an IAM policy scp-enforce-policy
is created and associated to all IAM users/roles in the member account except the administrator IAM role.In case the actions in SCP policy need to be updated, follow the instructions to update the policy:
ou-47kj-8dquliyv.json
for demo purpose)permission-boundary-policy
(Overwrite the existing file directly if it already exists.)
Behind the sense, the lambda function scp-iam-event-dispatcher deployed in security account will be triggered by the object update event configured in the S3 bucket.
In many case that the user should have the ability to create new IAM user or role via CLI/Console/SDK. As long as the account is registered, with the dedicated event rule and cloudtrail deployed in the target account, any newly created IAM users/roles will automatically attach the IAM permission boundary policy, to be restricted by "SCP policy".
The steps below demostrate how the newly created IAM user/role is retricted by IAM permission boundary policy.
Behind the sense, the event rule deployed in this account captures the IAM activity, and trigger the lambda function scp-iam-event-dispatcher deployed in security account.
In the case (E.g: the size of the policy exceeds limit 6,144 characters), the execution of the lambda function is failed. The security administrators need to get notified as soon as possible to mitigate the issue.
A dedicated SNS topic is created in the account, the security administrators can opt-in subscribe the failures events.
Email
to subscribe the failure notifications.This is for the case that it needs to move to native SCP with SCP feature is natively supported in AWS Organizations. The steps below will work through to finish the migration from SCP alternative solution to native SCP.
Note: The SCP syntax is exactly the same between SCP Alternative Solution and Native SCP. You don't need any modifications on the "SCP Policies" while moving to native SCP.
Note: The dedicated S3 bucket scp-alt-
needs to be deleted manually.
This is a SCP workaround solution by using AWS IAM's permission boundary, the user should be aware of the limitations prior to using it:
Deny
actions will be appended to the default IAM permission boundary policy by default.
{
"Sid": "EnforceDeny1",
"Effect": "Deny",
"Action": [
"iam:DeleteUserPermissionsBoundary",
"iam:DeleteRolePermissionsBoundary",
"iam:PutRolePermissionsBoundary",
"iam:PutUserPermissionsBoundary"
],
"Resource": "*",
"Condition": {
"ArnNotLike": {
"aws:PrincipalArn": "arn:aws-cn:iam::*:role/<Protected-IAM-Organization-Role>"
}
}
},
{
"Sid": "EnforceDeny2",
"Effect": "Deny",
"Resource": [
"arn:aws-cn:iam::<Target-AWS-Account-ID>:policy/scp-enforce-policy",
"arn:aws-cn:cloudtrail:cn-north-1:<Target-AWS-Account-ID>:trail/scp-trail",
"arn:aws-cn:s3:::scp-trail-bucket-<Target-AWS-Account-ID>",
"arn:aws-cn:events:cn-north-1:<Target-AWS-Account-ID>:rule/scp-event-rule",
"arn:aws-cn:iam::<Target-AWS-Account-ID>:role/<Protected-IAM-Organization-Role>"
],
"Condition": {
"ArnNotLike": {
"aws:PrincipalArn": "arn:aws-cn:iam::*:role/<Protected-IAM-Organization-Role>"
}
}
}
OrganizationAccountAccessRole
by default) is whitelisted since the role is used to access to member accounts for the Lambda functions. The user can specify custom role name by CloudFormation parameter OrganizationAccessRoleName
during the deployment.stacksets-exec-xxxxx
is whitelisted since it's used for CloudFormation StackSets.In most of the cases, the allow all actions should be given as defined in the example policy.
iam:CreateRole
and iam:CreateUser
must be deployed in Beijing
(cn-north-1
) AWS Region as all of the IAM event are available only in this region. These rules are created by Lambda during the Service Catalog Product provisioning for target account and REGION
value is set to cn-north-1
in source code.Message in logs | Reasoning | Outcome |
---|---|---|
Resource not found. (Service: AWSServiceCatalog; Status Code: 400; Error Code: ResourceNotFoundException; Request ID: 38b658c5-24c3-4b52-8908-6a831a4f1458; Proxy: null) | It would randomly fails while creating the service catalog from CloudFormation. | Re-try |
If you can't identity the root cause from the CloudFormation Console. Most of the errors should be present in the CloudWatch Log groups for the 3 lambda functions.
scp-account-register.py - For the process of account register.
scp-iam-event-dispatcher.py - For the process of updating the SCP policy files in S3 bucket.
scp-s3-event-dispatcher.py - For the newly created IAM users/roles in the target accounts.
This sample code is made available under the MIT-0 license. See the LICENSE file.