there is no explicit deny \u2192 implicit deny<\/li>\n<\/ul>\n\n\n\nA side note on cross-account access<\/h2>\n\n\n\n Until now, we\u2019ve considered only access within the same account, but what would happen if we need to evaluate also cross-account access? It\u2019s simpler than it looks: request is evaluated on policies and permission from the perspective of both the trusted and trusting account and allowed only if both are evaluated as an allow!<\/p>\n\n\n\n
If you think about this, it\u2019s more restrictive than single access. Since AWS permission starts with an implicit deny, you must explicitly set the permissions on both accounts before evaluating the request as an allow.<\/p>\n\n\n\n
Permission intersections<\/h2>\n\n\n\n After understanding what is involved in deciding when a request is allowed, we can move on to how they interact.<\/p>\n\n\n\n
This led to two practical scenarios, one with and one without Resource-based policies. The main point here is to understand that the only case in which one\u2019s effective permissions can exceed that of the whole intersection is when Resource-based policies are involved.<\/strong><\/p>\n\n\n\n<\/p>\n\n\n\n <\/figure>\n\n\n\n<\/p>\n\n\n\n
When Resource-based policies are involved, if they evaluate as an allow, you\u2019re taking the final decision before the policy evaluation flow would evaluate Identity-based, Permission Boundaries, and Session policies. This results in permissions granted that can exceed the ones explicitly allowed by those policies.<\/p>\n\n\n\n
About SCPs inheritance<\/h2>\n\n\n\n The last thing to say is about Service Control Policies and the fact that they can be inherited.<\/p>\n\n\n\n
Strangely, this doesn\u2019t work as one should expect (but it\u2019s for the better, trust me).<\/p>\n\n\n\n
When one thinks about inheritance, usually in programming, but even in other fields, one thinks about getting the parent’s configurations to the child. If we apply this to SCPs, Organizational Units, and accounts, one can define the SCPs at the root level and then inherit everything. Well, that\u2019s NOT how it works.<\/p>\n\n\n\n
Since DENY statements are evaluated first, in practice, only DENY statements are inherited<\/strong>.<\/p>\n\n\n\nIf you deny a service in an SCP, there is no way to grant it in a lower-level OU or Account.<\/p>\n\n\n\n
So, when an SCP is evaluated, there are actually only two SCPs that concur with the outcome:<\/p>\n\n\n\n
\nThe parent SCP \u2014 it\u2019s the SCP evaluated of the next higher-level SCP; this needs to be navigated to the Root to the Organization, so it just needs to add the next layer, one step at a time<\/li>\n\n\n\n The current SCP \u2014 the SCP which is currently being evaluated<\/li>\n<\/ol>\n\n\n\n<\/p>\n\n\n\n <\/figure>\n\n\n\n<\/p>\n\n\n\n
From this perspective, you can see that ALLOW statements are not inherited but need to be explicitly set in the SCP of the Account or Organization Unit. This is for security purposes, as we want to explicitly set the boundaries of accounts and organizational units to avoid implicit significant permissions.<\/p>\n\n\n\n
Deny strategy<\/h3>\n\n\n\n With a deny strategy, actions are allowed by default through a FullAccess SCP managed directly by AWS. You attach that SCP to all Accounts and OU and you need to specify what services and actions are prohibited:<\/p>\n\n\n\n
<\/p>\n\n\n\n <\/figure>\n\n\n\n<\/p>\n\n\n\n
This is the default configuration of AWS Organizations so that account admins can delegate all services and actions until you create and attach an SCP that denies a specific service.<\/p>\n\n\n\n
The benefit of this approach is that deny statements require less maintenance<\/strong> because you don’t need to update them when AWS adds new services, and it\u2019s supported out of the box. You can also restrict access to specific resources or define conditions for when SCPs are in effect.<\/p>\n\n\n\nThis is a great way to start for smaller organizations that need to act fast and don\u2019t have strict requirements over governance and security.<\/p>\n\n\n\n
Allow strategy<\/h3>\n\n\n\n With an allow strategy, you must remove the AWS-managed FullAWSAccess SCP. Now all actions for all services are implicitly denied, and you need to create an SCP that explicitly permits only those services and actions you want to allow. This case is the same schema as the inheritance evaluation.<\/p>\n\n\n\n
The benefit of this approach is that you have more control over what is allowed<\/strong>. Since everything is implicitly denied, this way is easier to scope down the actual boundaries of an account. Since deny permissions are inherited, you don\u2019t have to specify it everywhere.<\/p>\n\n\n\nHowever, it requires more maintenance since you have to manually allow each service (and this includes new services). And it comes with some limitations on the allow statements: Resource elements can only have a \u201d*\u201d entry,<\/strong> and they can’t have a Condition.<\/strong><\/p>\n\n\n\nThis approach’s value shines when services may not be needed by a large portion of the organization but may still be required for specific use cases. In this scenario, it\u2019s simpler to elevate permissions and satisfy security and governance concerns while allowing flexibility and exceptions.<\/p>\n\n\n\n
Just a few examples<\/h2>\n\n\n\n So let\u2019s see those SCPs in action; here, I put some examples so you can better picture what an SCP looks like in a real-world scenario.<\/p>\n\n\n\n
Pipeline only account<\/h3>\n\n\n\n In this case, we\u2019ve created an SCP to deny everything except changes that run through pipelines. The use case is to create an automation-only account where no manual action is allowed, but changes are always deployed through pipelines.<\/p>\n\n\n\n
{\n \"Version\": \"2012-10-17\",\n \"Statement\": [\n {\n \"Sid\": \"DenyAllExceptPipelines\",\n \"Effect\": \"Deny\",\n \"NotAction\": [\n \"codepipeline:*\",\n \"codebuild:*\",\n \"codecommit:*\",\n \"codedeploy:*\",\n \"codestar:*\",\n \"cloudformation:*\",\n \"iam:*\",\n \"s3:*\",\n \"logs:*\",\n \"cloudwatch:*\",\n \"cloudtrail:*\",\n \"codestar:*\",\n \"codestar-notification:*\",\n \"codeartifact:*\",\n \"kms:*\",\n \"tag:*\",\n \"access-analyzer:*\",\n \"codestar-connections:*\",\n \"ssm:GetParameter*\",\n \"sts:*\",\n \"events:*\"\n ],\n \"Resource\": \"*\",\n \"Condition\": {\n \"StringNotLike\": {\n \"aws:PrincipalArn\": [\n \"arn:aws:iam::MY-ACCOUNT-ID:role\/MY-ROLE\"\n ]\n }\n }\n }\n ]\n}<\/code><\/pre>\n\n\n\nBackup protection<\/h3>\n\n\n\n In this SCP, we implemented a way to protect all backups made through AWS backup by deletion. Notice that both S3 and Backup vaults are protected and the service cannot be turned down.<\/p>\n\n\n\n
{\n\t\"Version\": \"2012-10-17\",\n\t\"Statement\": [\n\t\t{\n\t\t\t\"Sid\": \"DenyS3BackupDelete\",\n\t\t\t\"Action\": [\n\t\t\t\t\"s3:DeleteObject\",\n\t\t\t\t\"s3:DeleteObjectVersion\",\n\t\t\t\t\"s3:DeleteObjectTagging\",\n\t\t\t\t\"s3:DeleteBucket\"\n\t\t\t],\n\t\t\t\"Resource\": [\n\t\t\t\t\"arn:aws:s3:::MY-S3-BACKUP*\/*\"\n\t\t\t],\n\t\t\t\"Effect\": \"Deny\"\n\t\t},\n\t\t{\n\t\t\t\"Sid\": \"DenyBackupDelete\",\n\t\t\t\"Action\": [\n\t\t\t\t\"backup:DeleteBackupVault\",\n\t\t\t\t\"backup:DeleteBackupVaultAccessPolicy\",\n\t\t\t\t\"backup:PutBackupVaultAccessPolicy\"\n\t\t\t],\n\t\t\t\"Resource\": [\n\t\t\t\t\"arn:aws:backup:*:*:backup-vault:MY-BACKUP-VAULT\"\n\t\t\t],\n\t\t\t\"Effect\": \"Deny\",\n\t\t\t\"Condition\": {\n\t\t\t\t\"StringNotLike\": {\n\t\t\t\t\t\"aws:PrincipalARN\": \"arn:aws:iam::*:role\/MY-EXECUTION-ROLE\"\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\t\"Sid\": \"DenyBackupTurnoffService\",\n\t\t\t\"Action\": [\n\t\t\t\t\"backup:UpdateRegionSettings\"\n\t\t\t],\n\t\t\t\"Resource\": [\n\t\t\t\t\"*\"\n\t\t\t],\n\t\t\t\"Effect\": \"Deny\",\n\t\t\t\"Condition\": {\n\t\t\t\t\"StringNotLike\": {\n\t\t\t\t\t\"aws:PrincipalARN\": [\n\t\t\t\t\t\t\"arn:aws:iam::*:role\/MY-EXECUTION-ROLE\"\n\t\t\t\t\t]\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t]\n}<\/code><\/pre>\n\n\n\nConclusion<\/h2>\n\n\n\n Congratulations, you\u2019ve managed to get to the end of the blog post! We\u2019ve gone from the policy evaluation flow to the actual implementation of SCPs, passing through the understanding of all the details that concur in policy and boundary interaction.<\/p>\n\n\n\n
From seeing the SCP examples, as with any governance tool, their implementation is extremely tied to how your organization is structured and works. So I truly believe this knowledge should be well internalized and widely understood within the organization.<\/p>\n\n\n\n
Now you\u2019re on your way to mastery; see you next time, and let me know how your cloud journey is going!<\/p>\n\n\n\n
<\/p>\n\n\n\n
Time to thank Nico and the rest of the Leapp team for this complete blog post! <\/em><\/p>\n\n\n\nHow was your trip through Service Control Policies? <\/em>Let us know in the comments!<\/p>\n\n\n\nCurious about this open-source project? Visit the GitHub repository<\/a> (and drop a star if you like it!), and the website<\/a><\/em> or read more about IAM and Cloud Access Management on their blog<\/a><\/em>.<\/p>\n","protected":false},"excerpt":{"rendered":"Today we are proud to welcome a special guest post: straight from the IAM- focused Noovolari Leapp’s blog, Nicol\u00f2 Marchesi […]<\/p>\n","protected":false},"author":1,"featured_media":5719,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[472],"tags":[278,586,566,582,633,635],"yoast_head":"\n
IAM policies and Service Control Policies (SCPs): How to master and secure access and permissions in an AWS Landing Zone - Proud2beCloud Blog<\/title>\n \n \n \n \n \n \n \n \n \n \n \n \n\t \n\t \n\t \n \n \n \n \n \n \n\t \n\t \n\t \n