Files
oam/knowledge base/cloud computing/aws/iam.md
2025-06-24 01:01:24 +02:00

20 KiB

Identity and Access Management

Controls who is authenticated (signed in) and authorized (has permissions) to use resources.

Authentication is provided by matching the sign-in credentials to a principal trusted by the AWS account.
Principals are IAM users, federated users, IAM roles, and applications.

Authorization is provided by sending requests to grant the principal access to resources.
Such access is given in response to the authorization request only if policies exist that grant the principal permission to the actions and the resources defined in the request.

Example

When first signing in to the console, one lands on the console's homepage. At this point, one isn't accessing any specific service.

When selecting a service, a request for authorization is sent to that service. It checks if one's principal is on the list of authorized users, what policies are being enforced to control the level of access granted, and any other policy that might be in effect.

The service returns all the requested data for which the principal passes the checks, and errors for the rest.

Authorization requests can be made by principals within the same AWS account, or from other AWS accounts trusted by the first.

Once authorized, the principal can take action or perform operations on resources in the AWS account.

Principal Description Notes
User Represents a human or a workload.
Defined by its name and credentials.
No permissions by default
Role Defines a set of permissions for making requests to AWS services.
Defines what actions can be performed on which resources.
Can be assumed by AWS services and other principals

Principals and AWS Services can assume Roles.
Trust is needed both ways, meaning Roles can be assumed if and only if both:

  • The Principal or Service assuming the Role is granted the sts:AssumeRole permissions to that Role.
  • The assumed Role's trust relationship does allow the Principal or Service to assume it.

Service Roles are different from Service-linked Roles.
From Using service-linked roles:

A service role is an IAM role that a service assumes to perform actions on your behalf.
An IAM administrator can create, modify, and delete a service role from within IAM.

A service-linked role is a type of service role that is linked to an AWS service.
The service can assume the role to perform an action on your behalf.
Service-linked roles appear in your AWS account and are owned by the service. An IAM administrator can view, but not edit the permissions for service-linked roles.

Refer aws.permissions.cloud for a community-driven source of truth for AWS IAM.

  1. Users
  2. Groups
  3. Policies
    1. Trust Policies
    2. Trust Relationships
  4. Roles
    1. Assume Roles
      1. Require MFA for assuming Roles
  5. Further readings
    1. Sources

Users

Refer IAM Users.

Represent human users or workloads needing to interact with AWS resources.
Consist of a name and credentials.
Applications using their credentials to make requests are typically referred to as service accounts.

IAM Users with administrator permissions are not the same thing as the AWS Account's root user.
The root user is required to perform some specific tasks on the account, which will not be available if signed in as any other user.

IAM identifies IAM Users via:

  • A friendly name that IAM will use to display Users in the AWS Management Console.
  • A unique identifier returned only when using the API, and not visible in the console.
  • An ARN usable to uniquely identify a IAM User across all of AWS.

Users can access AWS in different ways depending on their credentials:

  • Console password: nothing more than passwords used to sign in to interactive sessions.
    Disabling a password (console access) for a User prevents them from signing in to the Console using their sign-in credentials, but it does not change their permissions nor prevent them from accessing the Console using assumed roles.
  • Access keys: allow programmatic requests to AWS' APIs.
  • SSH keys: SSH public keys in the OpenSSH format used to authenticate with CodeCommit.
  • Server certificates: SSL/TLS certificates usable to authenticate with some services.

When using the Management Console to create IAM Users, one must include a console password or an access key.
By default, brand new IAM Users created using the APIs have no credentials of any kind.

By default, Users have no permissions and can do nothing.

Users can be assigned permissions boundaries.
Those allow the use of managed policies to limit the maximum permissions that an identity-based policy can grant to an IAM User or Role.

Each IAM User is associated with one and only one AWS account.
Any activity performed by IAM Users in one's account is billed to the account.

The number and size of IAM resources in an AWS account are limited.
Refer IAM and AWS STS quotas.

Only one IAM User can exist with a specific username, no matter the path defined at its creation.

Groups

Refer IAM user groups.

Collections of IAM users.
They allow to specify permissions for multiple users.

Groups can be assigned Policies. Any User in a Group inherits the Group's permissions.

Groups cannot be used as Principals in a Policy.
Groups relate to permissions, not authentication, and Principals are authenticated IAM entities.

One Group can contain many Users, and one User can belong to multiple Groups.

Groups can contain only Users, not Roles nor other Groups.

There is no default Group that automatically includes all users in the AWS account.

The number and size of IAM resources in an AWS account are limited.
Refer IAM and AWS STS quotas.

Policies

Refer Policies.

Define which actions are available for principals on which resources under which conditions.
Their effect can be to allow or deny such actions. A deny statement always overwrites allow statements.

Watch out for explicit Deny statements, as they could prevent users from do seemingly completely unrelated things - like accessing a Pulumi state file in a S3 bucket when an explicit Deny statement blocks IAM users from listing IAM Groups when they are not logged in with MFA.

Mostly stored as structured JSON documents.
Each Policy comes with one or several statements. Each statement defines an effect.

IAM does not expose Policies' Sid element in the IAM API, so it cannot be used to filter retrieved statements.

Logical evaluation:

  • Statements in a Policy operate in an OR fashion.
    As in, at least one statement must allow access to a set of resources.
  • Conditions in a Statement operate in an AND fashion.
    As in, all conditions must resolve true for the statement to allow access.
  • Operator values in a Condition operate in an OR fashion.
    As in, at least one value must match for a Condition to resolve true.

Policy examples:

Give a user temporary RO access to a bucket
  1. Create the policy:

    {
      "Version": "2012-10-17",
      "Statement": [{
        "Sid": "AllowAttachedPrincipalsTemporaryROAccessToBucket",
        "Effect": "Allow",
        "Action": [
          "s3:GetObject",
          "s3:GetObjectAttributes",
          "s3:ListBucket",
          "s3:ListBucketVersions"
        ],
        "Resource": [
          "arn:aws:s3:::my-bucket",
          "arn:aws:s3:::my-bucket/*"
        ],
        "Condition": {
          "DateLessThan": {
            "aws:CurrentTime": "2024-03-01T00:00:00Z"
          }
        }
      }]
    }
    
    $ aws iam create-policy --output 'yaml' \
      --policy-name 'temp-ro-access-my-bucket' --policy-document 'file://policy.json'
    - Policy:
        Arn: arn:aws:iam::012345678901:policy/temp-ro-access-my-bucket
        AttachmentCount: 0
        CreateDate: '2024-02-25T09:34:12+00:00'
        DefaultVersionId: v1
        IsAttachable: true
        Path: /
        PermissionsBoundaryUsageCount: 0
        PolicyId: ANPA2HKHE74L11PTJGB3V
        PolicyName: temp-ro-access-my-bucket
        UpdateDate: '2024-02-25T09:34:12+00:00'
    
  2. Attach the newly created policy to the user:

    aws iam attach-user-policy \
      --user-name 'my-user' --policy-arn 'arn:aws:iam::012345678901:policy/temp-ro-access-my-bucket'
    

Trust Policies

Specific type of resource-based policy for IAM roles.
Used to allow Principals and other AWS Services to assume Roles.

Trust Relationships

Trust Policies used by AWS services to assume Roles in one's account to be able to manage resources on behalf of Users.

Roles

Refer IAM roles.

IAM identities that have specific permissions but cannot have standard long-term credentials such as passwords or access keys associated with it.
Roles are meant to be used to delegate access to AWS Services or other Principals that cannot normally act on those resources.

Principals and AWS Services can assume Roles to gain such delegated permissions.
Trust is needed both ways, meaning Roles can be assumed if and only if both:

  • The Principal or Service assuming the Role is granted the sts:AssumeRole permissions to that Role.
  • The assumed Role's trust relationship does allow the Principal or Service to assume it.

Roles are assumed in sessions.
When assuming Roles, they provide the assuming identity with temporary security credentials that are only valid for that session.

Only one IAM Role can exist with a specific name, no matter the path defined at its creation.

Assume Roles

Refer Introduction to AWS IAM AssumeRole.

Principals and AWS Services can assume Roles as long as:

  1. The Principal or Service trying to assume the end Role has assigned Policies that would allow it to.

    {
        "Version": "2012-10-17",
        "Statement": [
            {
                "Effect": "Allow",
                "Action": "sts:AssumeRole",
                "Resource": [
                    "arn:aws:iam::012345678901:role/EksAdminRole",
                    "arn:aws:iam::987654321098:role/EcsAuditorRole"
                ]
            }
        ]
    }
    
  2. The assumed Role's Trust Relationships allows the Principal in the point above to assume it.

    {
        "Version": "2012-10-17",
        "Statement": [
            ,
            {
                "Effect": "Allow",
                "Principal": {
                    "AWS": [
                      "arn:aws:iam::012345678901:user/halJordan",
                      "arn:aws:sts::987654321098:role/OtherRole"
                      "arn:aws:sts::987654321098:assumed-role/EcsAuditorRole/specific-session-name"
                    ]
                },
                "Action": "sts:AssumeRole"
            }
        ]
    }
    

Allowed entities can assume Roles using the STS AssumeRole API.

$ aws sts assume-role --role-arn "arn:aws:iam::012345678901:role/EksAdminRole" \
  --role-session-name "lookAt-halJordan-heIsThe-EksAdminRole-now" --duration-seconds '900' --output 'yaml'

AssumedRoleUser:
  Arn: arn:aws:sts::012345678901:assumed-role/EksAdminRole/lookAt-halJordan-heIsThe-EksAdminRole-now
  AssumedRoleId: AROA2HKHF0123456789OA:lookAt-halJordan-heIsThe-EksAdminRole-now
Credentials:
  AccessKeyId: ASIA2HKHF012345ABCDE
  Expiration: '2024-08-06T10:29:15+00:00'
  SecretAccessKey: C2SGbkwmfHWzf44DX6IQQirg5XCGwpLX0Ai++Qkq
  SessionToken: IQoJb3jPZ2luX2VjEAIaCWV1LXdlc3QtMSJHMEUCIQCGEihh9rBi1cL8ebhQVdcKl8Svzm5VCIC/ebCdxpORiA…4A==

One can assume Roles in a chain fashion, assuming one Role to then assume another Role.

Role chaining limits one's CLI or API role session duration to a maximum of 1 hour at the time of writing.
This duration cannot be increased. Refer Can I increase the duration of the IAM role chaining session?.

Require MFA for assuming Roles

Refer Using AWS CLI Securely with IAM Roles and MFA.

Add the "Bool": {"aws:MultiFactorAuthPresent": true} condition to the Role's Trust Relationships.

{
    "Version": "2012-10-17",
    "Statement": [{
        "Effect": "Allow",
        "Principal": {
            "AWS": "arn:aws:iam::012345678901:user/halJordan"
        },
        "Action": "sts:AssumeRole",
        "Condition": {
            "Bool": {
                "aws:MultiFactorAuthPresent": true
            }
        }
    }]
}

When requiring MFA with AssumeRole, identities must pass values for the SerialNumber and TokenCode parameters.
SerialNumbers identify the users' hardware or virtual MFA devices, while TokenCodes are the time-based one-time password (TOTP) value that devices produce.

$ aws sts assume-role --output 'yaml' --duration-seconds '900' \
  --role-arn 'arn:aws:iam::012345678901:role/EksAdminRole' --role-session-name 'lookAt-him-heIsThe-EksAdmin-now' \
  --serial-number 'arn:aws:iam::012345678901:mfa/gopass' --token-code '123456'
AssumedRoleUser:
  Arn: arn:aws:sts::012345678901:assumed-role/EksAdminRole/lookAt-him-heIsThe-EksAdmin-now
  AssumedRoleId: AROA2HKHF74L72AABBCCDD:lookAt-him-heIsThe-EksAdmin-now
Credentials:
  AccessKeyId: ASIA2HKHF74L7YOAUZHR
  Expiration: '2025-04-12T08:09:46+00:00'
  SecretAccessKey: ErhyPKjQkI3GbrnszpOvMTi8AvmziGbSIOIcNS9k
  SessionToken: IQoJb3JpZ2…LxEOLkm9U

For CLI access, users will need to add the mfa_serial setting to their profile.

[default]


[role-with-mfa]
source_profile = default
role_arn = arn:aws:iam::012345678901:role/EksAdminRole
mfa_serial = arn:aws:iam::012345678901:mfa/gopass
$ AWS_PROFILE='role-with-mfa' aws sts get-caller-identity --output 'yaml'
Enter MFA code for arn:aws:iam::012345678901:mfa/gopass:
Account: '012345678901'
Arn: arn:aws:sts::012345678901:assumed-role/EksAdminRole/botocore-session-1234567890
UserId: AROA2HKHF74L72AABBCCDD:botocore-session-1234567890

Further readings

Sources