Tyler Sengia

Unit 2: AWS IAM and KMS

Study notes for Identity Access Management and Key Management Service.

According to the shared-responsibility model of AWS, users are required to maintain IAM Policies and cryptographic keys to ensure their cloud resources stay secure.

IAM is complex. There’s a lot to unbox. I’ve found that memorizing the vocabulary terms and authorization flows to be key to gaining deeper understanding to the system. Once I understood the vocab, I created my own IAM Users, Groups, Roles, and policies in my personal AWS account, and that taught me more.

IAM Groups cannot be used as Principals

You cannot specify an IAM Group as a Principal in a resource-based IAM Policy!
The documentation explains that you cannot specify an IAM Group because “groups relate to permissions, not authentication, and principals are authenticated IAM entities”.
At first, this is extremely confusing, but if you dig deeper, you will realize that Principals must be authenticated entities. IAM Groups are not authenticated entities because “you can’t use a group to sign in”.

So, how do you allow all users of a single IAM Group to assume an IAM Role?
Thankfully John Rotenstein provided an answer on StackOverflow:
Attach a policy to the group that grants permission for the sts:AssumeRole action on your desired IAM Role.

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "123",
            "Effect": "Allow",
            "Action": [
                "sts:AssumeRole"
            ],
            "Resource": [
                "arn:aws:iam::123456789012:role/desired-role"
            ]
        }
    ]
}

One thing to note, the trust policy example that John includes with his answer is not secure. Read the comments of the answer to understand.

IAM is Eventually Consistent

Distributed services have different types of guarantees for the data due to the PACELC theorem.

IAM is an eventually consistent service, which means policies/changes you make may not be applied to all regions immediately. However, over time all changes will end up in every region.

This could be a problem if you do something such as:

  1. Create a publically accessible S3 bucket named important-financial-documents in the eu-west-1 region
  2. Make a new IAM policy in us-east-2 that makes the S3 bucket private
  3. Upload some sensitive financial documents to the S3 bucket

Because you made a new IAM policy to make the bucket private before uploading the files, you assume your files are secure. However, the IAM policy may take some time to propagate from the us-east-2 region over to the eu-west-1 region. This leaves a window of time when your S3 bucket is publically accessible!

Ways to avoid this issue:

  1. When creating a new resource, have IAM policies already in place and/or attach existing policies to them.
  2. When creating a new IAM policy, create it in the same region as the resources that it protects.

This is an inconvenience, and there’s no good way to tell if your IAM changes have propagated out to every region yet, even though the IAM User Guide says to “verify that the changes have been propagated before production workflows depend on them”.

IAM Users are not for Public Customers

Should I use AWS IAM for the login/signup page for a public facing application?
For example, if I built a new social media app, should the users be signing in with an IAM User and password?

The answer is no.

AWS IAM is intended for those maintaining or building the application. IAM Users should be developers, managers, product owners, contractors and others who are in your enterprise. Domestic customers that are using your AWS-hosted product will not use AWS IAM. Instead, you can use something such as Amazon Cognito for authentication and authorization. Or, you can create your own API hosted on AWS instead. Either way, AWS IAM is not for customer logins, it is intended for maintainers and developers.

However, if you are not developing a domestic, public facing application, this can become more tricky.

For example, suppose you are a contractor providing DevOps services to another business. Your business maintains a GitLab server, build runners, and artifact hosting on AWS. In this case, it would be acceptable to create an IAM User (or setup cross AWS account access) for the customer so that their developers can access the AWS resources using IAM login information.

Key Management Service

At first glance, the AWS KMS service seems like an odd service. To encrypt data with an AWS KMS symmetric key, you must first send that data via HTTPS to the KMS service. That is very counter-intuitive. Why would I send my sensistive data to another service to get encrypted?
Why shouldn’t I encrypt my data locally?

Sending the sensitive data to AWS KMS is not a risk because it is sent via HTTPS with TLS 1.2 or TLS 1.3. AWS KMS has additional security requirements for the connection too. If TLS 1.2 or TLS 1.3 had a serious flaw, then we would have much larger problems than whatever data you sent to AWS KMS.

AWS KMS makes it easy to meet encryption and key management requirements. You no longer need to install FIPS-120 certified software or deal with rolling keys on your network. AWS KMS takes care of all of those things.

This guide only serves to connect ideas already presented in AWS documentation to provide a more complete learning path. After reading this, you should take the time to read these resources as well:

Bookmarks to Keep

Here are some links that I recommend adding to your bookmarks list for quickly looking up AWS information:

Anki Deck

AWS IAM and KMS Anki Deck