Managing service permissions in AWS

As you have probably realized by now, we are already using IAM extensively. Every system and CloudFormation template we created in the book included one or more IAM resources. Until now, we tried to minimize the complexity of that section to focus on the other resources, our templates, but tightening these rules is one of the most effective ways there is to improve the security of our architecture.

We will take the example of our Hello World application running on top of EC2 to demonstrate how we can tighten the permissions for our role.

When we worked on our CI/CD pipeline, we started to use CodePipeline and CodeDeploy to deploy our application. Whenever someone merges a change in our application, CodePipeline takes the new code and puts it on S3. After that, the CodeDeploy agent takes it from S3 and installs it on our EC2 instance. To make that possible, we had to change our role to allow our instances to communicate with S3.

We did that by creating the following policy:

t.add_resource(IAMPolicy( 
    "Policy", 
    PolicyName="AllowS3", 
    PolicyDocument=Policy( 
        Statement=[ 
            Statement( 
                Effect=Allow, 
                Action=[Action("s3", "*")], 
                Resource=["*"]) 
        ] 
    ), 
    Roles=[Ref("Role")] 
)) 

In plain English, we said that our EC2 instances are allowed to do any S3 operation on any S3 bucket. Since our application inherits these permissions, if someone manages to find an exploit in your application and perform some remote code execution, they will be able to do many undesirable actions. This includes accessing all our S3 buckets, including the ones with our load balancer logs and your application artifacts. They will also be able to create new S3 buckets, either to store their own content or even try to create a phishing attack by storing a virus with the hope that someone finds the bucket and tries to open the objects it contains.

To be able to install the new artifacts, CodeDeploy only needs read access to S3, therefore we could change the statement in the preceding policy to the following:

Statement( 
    Effect=Allow, 
    Action=[ 
      Action("s3", "Get*"), 
      Action("s3", "List*") 
    ], 
    Resource=["*"]) 
) 

In addition, we can restrict the resources to only allow those actions to target the S3 buckets used by CodeDeploy. Since the service uses one bucket per region, your new statement would look as follows:

Statement( 
    Effect=Allow, 
    Action=[ 
      Action("s3", "Get*"), 
      Action("s3", "List*") 
    ], 
      "Resource": [ 
        "arn:aws:s3:::codedeploydemobucket/*", 
        "arn:aws:s3:::aws-codedeploy-us-east-2/*", 
        "arn:aws:s3:::aws-codedeploy-us-east-1/*", 
        "arn:aws:s3:::aws-codedeploy-us-west-1/*", 
        "arn:aws:s3:::aws-codedeploy-us-west-2/*", 
        "arn:aws:s3:::aws-codedeploy-ca-central-1/*", 
        "arn:aws:s3:::aws-codedeploy-eu-west-1/*", 
        "arn:aws:s3:::aws-codedeploy-eu-west-2/*", 
        "arn:aws:s3:::aws-codedeploy-eu-central-1/*", 
        "arn:aws:s3:::aws-codedeploy-ap-northeast-1/*", 
        "arn:aws:s3:::aws-codedeploy-ap-northeast-2/*", 
        "arn:aws:s3:::aws-codedeploy-ap-southeast-1/*",         
        "arn:aws:s3:::aws-codedeploy-ap-southeast-2/*", 
        "arn:aws:s3:::aws-codedeploy-ap-south-1/*", 
        "arn:aws:s3:::aws-codedeploy-sa-east-1/*", 
        "arn:aws-cn:s3:::aws-codedeploy-cn-north-1/*" 
      ] 
) 

With the hardening of IAM, we can efficiently restrict what our systems and users can do when interacting with AWS. We will now look at improving our network.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset