AWS IAM Primer

AWS IAM at its core is the central authorization service. This article provides an overview on how to navigate its basic features and how it fits together with other AWS services.

  • AWS
  • IAM
  • STS
Profile picture of Patrick

Patrick

Software Engineer


Hero Background Image

AWS IAM - AWS Identity and Access Management is a set of services for managing who can access what on your AWS account. This article will give you a basic overview of what IAM can do and what it provides as a core functionality.

Introduction

IAM appears as one of the most essential services. It defines who (the subject) can do what (the actions) on what (the object). However, AWS started humbly without dedicated identity and access management. AWS introduced IAM later in 2011.

Purpose

IAM solves the following problem: Given a subject attempting to do an action on some resources, is the subject allowed to do so? It is first and foremost a central authorization service meant to implement mandatory access control (MAC).

In addition, it provides two authentication mechanisms: One for Console Access (split into root user access and account user access) and the other for programmatic access (via Access key and secret access key). It outsources other authentication via identity providers and AWS STS.

Authorization

At its core, IAM defines what is an Identity (subject), what are Resources (objects) and what are Actions. These three things are bundled in a policy, which contains a list of statements. Each statement declares a list of actions, that are either allowed or denied for a list of resources. The subject is the identity that the policy is attached to. Or, if the policy is attached to a resource, then the subject is the Principal defined in the policy.

Each other service that integrates with IAM, e.g. EC2 or DynamoDB, declares its actions and its resources for IAM.

Let's have a look at an example policy to demonstrate the different parts:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "dynamodb:DescribeTable",
                "dynamodb:GetItem",
                "dynamodb:PutItem"
            ],
            "Resource": [
                "arn:aws:dynamodb:eu-central-1:123456789012:table/*"
            ],
            "Condition": {
                "ForAllValues:StringEquals": {
                    "dynamodb:LeadingKeys": [
                        "${aws:PrincipalTag/TenantID}"
                    ]
                }
            }
        }
    ]
}

As you can see, each statement has an Effect, that can be either Allow or Deny. It refers to a list of Actions. In order to ensure globally unique names, AWS decided to prefix all actions of a service with the service's short name. In this example that is dynamodb: for DynamoDB. Further, it refers to a list of resources, each identified by an ARN. Note, that ARNs are globally unique and that Effects, Actions and Resources can contain wildcards. With all that, the IAM policy evaluator will then just match strings in order to determine authorization.

Lastly, since it is each service's responsibility to integrate with IAM, their integration quality varies. Especially for those older than IAM. Some allow more fine-grained control over resources than others.

Policy Details

In addition to resources and actions, you can define conditions in policy statements to further narrow down permissions. You can even add variables to refer to context-specific values like the identity that made an AWS API request. This is useful, when you are aiming for least privileges or attribute based access control (ABAC). Unfortunately, the restrictive power of conditions varies between services as well.

As previously mentioned, policies can be attached to identities as well as certain types of resources like S3 Buckets. Additionally, there are several more places where policies can reside. When doing a request, IAM considers all relevant policies using the logic shown in this flow chart. Note, that as first step it checks all policies for possible applicable Deny-statements. If it finds one, it returns an explicit deny. This is a special response to signal that a policy denies access. All other deny-responses mean, that one of the applicable policies does not explicitly allow the action. Just be aware of the exceptions mentioned on above page.

Outsourcing of identities

Since IAM only allows you to authenticate as root user or another user and not as a role (or AWS service), there is another mechanism to assume a role. However, it is not AWS IAM directly that provides that feature, but AWS STS --- a service that can generate temporary credentials to authenticate an entity. In order to ensure that a role can only be used by a specific external entity, each role can have a trust policy, which allows the sts:AssumeRole, sts:AssumeRoleWithWebIdentity or similar actions to a certain Principal. That means, IAM defines that a certain role can be used by a specific external identity via temporary credentials, whether by an AWS service, another account's user or role or an OIDC- or SAML-user. And in the same way identities from the same account may be allowed to assume that role via temporary credentials.

Access to external identities is defined as follows in a trust policy:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::124356789012:role/TrackingServiceRole"
      },
      "Action": "sts:AssumeRole"
    },
    {
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::124356789012:role/TrackingServiceRole"
      },
      "Action": "sts:TagSession",
      "Condition": {
        "StringLike": {
          "aws:RequestTag/TenantID": "*"
        }
      }
    }
  ]
}

When you attach this policy to a role X, you allow the role arn:aws:iam::124356789012:role/TrackingServiceRole to take on role X and therefore act with its permissions.

Troubleshooting

When using your created policies you will often encounter different authorization errors like:

User: arn:aws:iam::123456789012:user/mateojackson is not authorized to perform: widgets:GetWidget on resource: my-example-widget

or

User: arn:aws:iam::777788889999:user/JohnDoe is not authorized to perform:
codecommit:ListRepositories because no service control policy allows the codecommit:ListRespositories action

or

User: arn:aws:iam::123456789012:user/JohnDoe is not authorized to perform:
codedeploy:ListDeployments on resource: arn:aws:codedeploy:us-east-1:123456789012:deploymentgroup:* because no permissions boundary allows the codedeploy:ListDeployments action

Each error message will provide you with hints on the evaluation step which made the authorization fail.

First, note that IAM-integration is service-specific and not all IAM-features are supported by all services. See for an overview: https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_aws-services-that-work-with-iam.html

For more general troubleshooting you can test policies using the policy simulator, which you can reach via the AWS Console through a button on the permissions tab of a user or user group. Note, that the policy simulator only takes into account the specified policies and not any resource policies deployed in your account.

Lastly, you can try the permissions yourself by trying to make real calls. For example, you can configure a role with the desired permissions and assume it yourself and then find the calls afterwards on AWS CloudTrail. Just be aware, that depending on the service CloudTrail might take more than 10 minutes to update and that some services are not fully integrated with CloudTrail.

Summary

This was a quick and basic overview of AWS IAM, the identity and access management. A service that defines Identities, Resources and Actions. It connects these three in policies to declare who can do what on the AWS account. Identities are defined directly in IAM or indirectly mentioned in the policy as Principal that can assume an IAM role. While evaluating policies for authorization IAM takes into account several policies defined in different places. And lastly, AWS services declare possible Resources and Actions each and support IAM authorization features to varying degrees.


Über den Autor

Profile picture of Patrick

Patrick

Software Engineer