Roles with persistent escalated permissions are considered risky and provide a high-value target for attackers. However, Infrequent elevated privileges are still required for business needs on managing cloud infrastructure. A time-based pattern provides access for the platform and security team while ensuring the security of our cloud infrastructure by limiting the lifespan of escalated permissions. Requests for elevated privilege should be logged for future audit and threat detection.
The idea
Follow my previous post on StackSet. You already have a way to manage your multi AWS accounts at scale. Now the time comes you need to perform some administrative task in one of the target accounts, what should you do?
The security and DevOps team occasionally needs a powerful IAM role to operate in AWS accounts with administrative permission for escalation. However, if the over-permissive role has a persistent presence in a deployed account, it becomes a clear target since it can be assumed by a human.
Luckily, something that IAM offers in its policy language is the condition field. We can parametrize the CloudFormation template of the IAM role with a validity timestamp in its condition field, as defined by IAM timed condition. This approach will expire the IAM permissions after the denoted timestamp.
So the Cloud Formation template would look something like the following:
AWSTemplateFormatVersion:2010-09-09Description:This template builds a time-boxed privilege IAMParameters:SourceAccountNumber:Description:Source account numberType:StringPermissionStartTime:Description:Timestamp for when the permission starts. https://www.w3.org/TR/NOTE-datetimeType:StringDefault:'2019-07-16T12:00:00Z'AllowedPattern:.+PermissionTerminateTime:Description:Timestamp for when the permission ends. https://www.w3.org/TR/NOTE-datetimeType:StringDefault:'2019-07-16T15:00:00Z'AllowedPattern:.+Resources:ElevatedAdmin:Type:'AWS::IAM::Role'Properties:AssumeRolePolicyDocument:Version:2012-10-17Statement:-Effect:AllowPrincipal:AWS:-!Sub'arn:aws:iam::${SourceAccountNumber}:role/<SOURCE_IAM_ROLE>'Action:-'sts:AssumeRole'Path:/Admin/RoleName:Timed-Elevated-AdminPolicies:-PolicyName:Timed-Elevated-PolicyPolicyDocument:Version:2012-10-17Statement:-Effect:DenyAction:-'iam:AttachRolePolicy'-'iam:DeleteRolePolicy'-'iam:DetachRolePolicy'-'iam:PutRolePolicy'-'iam:UpdateAssumeRolePolicy'Resource:!Sub'arn:aws:iam::${AWS::AccountId}:role/Admin/Timed-Elevated-Admin'-Effect:AllowAction:'*'Resource:'*'Condition:DateGreaterThan:'aws:CurrentTime':!RefPermissionStartTimeDateLessThan:'aws:CurrentTime':!RefPermissionTerminateTime
It is important to always think further in terms of IAM privilege escalation, therefore more restriction around the IAM role itself is created in the CloudFormation template. However, if you notice that CreateRole is not blocked, and one can pretty easily set up another shadow admin. One can always add in more restrictions in creating roles, attaching policy, update policy, etc.
Removal of the role
We can either use the AWS Step Function wait state timer module or a CloudWatch timer to kick off Lambda before we trigger the removal of the target IAM role. Below is the sample code to remove the IAM role provisioned by the StackSets execution.
By relying on the AWSCloudFormationStackSetExecutionRole Role, we assumed that the ExecutionRole will have the permission in the account to do as instructed. To ensure this is always the case, we can create an organization-level Service Control Policy(SCPs) to protect the role once it’s created.
We went over protecting privilege IAM roles in the member accounts, but we still have…ahem…a single point of failure, which is our StackSets master account. We want the following IAM rule to be attached to the operator, so they cannot arbitrarily modify the CloudFormation template used to deploy the IAM.
In this post, we went through using the time condition field for IAM policy, protecting IAM role in both identity-based policy and Service Control Policy(SCP). The journey to protect IAM never ends, some additional idea worth exploring include: Tag enforcement for CloudFormation deployment, timed access for user-based removal of Active Directory group, Using Hashicorp Vault to provide short term IAM credentials