Wednesday 11 May 2022

AWS Identity and Access Management (IAM)



AWS Identity and Access Management (IAM) is a web service that we use to:
  • securely control access to AWS resources
  • centrally manage permissions that control which AWS resources users can access
  • control who is authenticated (signed in) and authorized (has permissions) to use resources

We can already identify several entities here: users, resources, permissions. If we go to AWS Console and open an IAM Dashboard page we can see the full list of all IAM entities:



Let's explain each of them and also their relations.


Users

  • Root user - account owner that performs tasks requiring unrestricted access
    • created when you sign up for AWS for the first time
    • accessed by signing in with the email address and password that were used to create the account
    • has complete admin privileges
    • can be used to manage any service within AWS but this is not recommended; this user is like root user on Unix systems or admin on Windows and should be used only for special tasks
    • used to log in to AWS Management console where it can create other users (IAM users); this is actually recommended use of root user
  • (Regular) IAM user - user within an account that performs daily tasks 
    • an entity that we/root create in AWS to represent the person or application that uses it to interact with AWS in an account
    • consists of:
      • name
      • long-term credentials
    • 2 types of access can be configured for it:
      • Access to the AWS Management Console
        • requires username and password
      • Programmatic access used to interact programmatically in Terminal on Unix and PowerShell in Windows
        • requires Access Key ID and Secret Access Key
        • can't be used to log in to AWS Management Console

When user is created, AWS assigns to it the least privilege permissions.


Policies


Permissions define what user can and can't do and they are assigned to users and user groups. They are not attached to users directly but via IAM policies.

IAM policies:
  • define AWS permissions
  • get attached to:
    • users
    • user groups
    • roles
  • can be:
    • AWS-managed
    • custom (customer-managed)
Policy Example: AdministratorAccess policy allows admin access to all resources and services. It is managed by AWS.

IAM policies are defined in JSON format: IAM JSON policy elements reference - AWS Identity and Access Management. IAM policies can be created and managed in visual editor and using JSON.

AdministratorAccess policy:

{
    "Version": "2022-05-11",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "*",
            "Resource": "*"
        }
    ]
}

Asterisk (*) means "all". Allow all actions on all resources.

There are many AWS-managed policies. Each of them is meant to be attached to a user with specific job role. Examples:
  • AdministratorAccess - administrator
  • Billing - view billing information, setup and manage payments
  • DatabaseAdministrator - DB admin
  • NetworkAdministrator - network admin
  • ViewOnlyAccess - view-only user

User Groups



If multiple users need to have same permissions, they need to have attached multiple policies e.g. AmazonEC2FullAccess and AmazonS3FullAccess

Instead of attaching policies to each user, we can create IAM User Group, make these users its members and then attach these policies to this group. For example, we can create a user group named Admins and give that group administrative permissions. Any user in that group automatically has the permissions that are assigned to the group.

User group:
  • is a collection of IAM users
  • simplifies permissions management by allowing managing policies (grant, change, and remove permissions) of multiple users at once
Using groups is a best-practice way to manage users' permissions by job functions,  AWS service access or our custom permissions. We can still attach policies to individual users.


Roles


How to manage permissions for services? E.g. what if EC2 instance needs to access S3 bucket. By default, just like users, resources don't have permissions to access other resources. Unlike users, we can't attach IAM policies to resources. We need to create IAM roles

IAM roles define access permissions for a resource. We need to create e.g. S3Access role and attach to it IAM policy AmazonS3FullAccess that we used for the user group. Then we attach this role to EC2 instance of interest.

IAM roles are a secure way to grant permissions to entities that we trust:
  • IAM users in another account
  • Application code running on an EC2 instance that needs to perform actions on AWS resources
  • An AWS service that needs to act on resources in your account to provide its features
  • Users from a corporate directory who use identity federation with SAML

IAM roles are used to provide access:
  • from one AWS service to another
  • to IAM user belonging to another AWS account
  • to applications to interact with services in AWS
  • to users managed outside AWS e.g. by Active Directory
Example of custom-made policy: the one which allows user to create and delete tags on EC2 instance:

CreateEC2TagsPolicy:

{
    "Version": "2022-05-11",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "ec2:DeleteTags",
                "ec2:CreateTags"
            ],
            "Resource": "*"
        }
    ]
}


IAM entities Identifiers


When we create IAM entities we assign to them friendly names. Furthermore, if we create these IAM resources via IAM API or AWS CLI, we can assign to them paths. 

Each resource gets assign an identifier in Amazon Resource Name (ARN) format: 

arn:partition:service:region:account:resource

Examples:

arn:aws:iam::123456789012:root
arn:aws:iam::123456789012:user/JohnSmith
arn:aws:iam::123456789012:user/engineering/devops/BojanKomazec

In the last example /engineering/devops/ is the path that was specified during user creation.



Creating a User and User Group in AWS Management Console


Log in to AWS Management Console with your root account.



Security, Identity and Compliance >> IAM
IAM service does not depend on the region so region is set to Global. Users, groups and roles are available in all regions.

Account Management >> Users >> Add User
We need to provide: 
  • User name
  • Desired Access type (both can be selected):
    • Programmatic access - enables access key ID and secret access key for the AWS API, CLI, SDK and other development tools
    • AWS Management Console access - enables a password that allows users to sign-in to the AWS Management Console
      • Require password reset - enable so user must create a new password at next sign-in. Users automatically get the IAMUserChangePassword policy to allow them to change their own password.
Next >> Permissions

Set permissions has 3 tabs:
  • Add user to group
  • Copy permissions from existing user
  • Attach existing policies directly
Next >> Tags

IAM Tags are key-value pairs you can add to your user. Tags can include user information such as an e-mail address, or can be descriptive, such as a job title. 

Next >> Review >> Create User

Add user - Success page: this is the only place and time when we can see/access/download the secret access key. We can download it within .csv file. 

Account Management >> Users: select user => Summary page
Summary page tabs:
  • Permissions
    • Add permissions (button); this can be done in 3 ways:
      • Add user to group
        • Create Group (button); shows list of all policies; we need to check those that we want to be attached to this group and then press button "Create group"
      • Copy permissions from existing user
      • Attach existing policies directly
        • check the desired policy 
    • Policies list:
      • for each policy we can see policy summary and JSON
  • Groups
  • Tags
  • Security Credentials
  • Access Advisor

Access Management >> Groups, select group => Summary page

Summary page has 3 tabs:
  • Users
  • Permissions
    • Attach Policy (button)
  • Access Advisor

Creating a Policy in AWS Management Console


Access Management >> Policies
Page shows:
  • Create Policy button - for creating a custom policy
    • Create Policy page has 2 tabs:
      • Visual Editor
        • We need to choose the service that the policy will be applicable for e.g. EC2
        • We then need to choose actions allowed in chosen service
          • Access level:
            • List
            • Read
            • Tagging
            • Write
            • Permissions management
        • We then need to choose resources this policy can be applied on
      • JSON
    • Review: 
      • set the name of the policy
      • set the description of the policy
  • list of all existing policies

Creating a Role in AWS Management Console


Access Management >> Roles; main page contains:
  • Create role (button)
    • Select type of trusted entity:
      • AWS Service (EC2, Lambda, ...) - allows AWS service to perform actions on our behalf e.g. EC2 or Lambda to call AWS services on our behalf
      • Another AWS account
      • Web identity (Cognito or OpenID provider)
      • SAML federation (corporate directory)
    • Add tags
    • Review
  • list of all roles

Programmatic Access


AWS CLI is an open source tool that allows interacting with AWS services using command line tools like Unix shell or Terminal and PowerShell in Windows. 

Installing AWS CLI on Mac



To verify installation:

% which aws
/usr/local/bin/aws

% aws --version
aws-cli/2.6.3 Python/3.9.11 Darwin/20.5.0 exe/x86_64 prompt/off


Configuring AWS CLI


% aws configure
AWS Access Key ID [None]: 
AWS Secret Access Key [None]: 
Default region name [None]: 
Default output format [None]: 

AWS Access Key ID and Secret Key are those that are downloaded when user was created. ID can be visible after that but secret key can be found only in downloaded file, it can be unveiled in AWS Management Console. 

For default region name we might want to put geographically closest region to our location. 

Default output format can be yaml, JSON, text or table.
 
$ ls  /home/bojan/.aws
config  credentials
 
$ cat  /home/bojan/.aws/config
[default]
region = eu-west-1
output = json

$ cat  /home/bojan/.aws/credentials
[default]
aws_access_key_id = ABC...DEF
aws_secret_access_key = DFCdfsg...sdceD

 
To check what region has been set:
 
$ aws configure get region 
eu-west-1
 
To check what Access Key ID and Secret Key have been set:
 
$ aws configure get aws_access_key_id

$ aws configure get aws_secret_access_key
 
 
How to maintain multiple AWS accounts on the same machine?
 
We need to use profiles. As we can see in the config files above, default is the default profile. To add a profile named e.g. profile2:

$ cat  /home/bojan/.aws/credentials
[default]
aws_access_key_id = ABC...DEF
aws_secret_access_key = DFCdfsg...sdceD

[profile2]
aws_access_key_id = xxx...xxx
aws_secret_access_key =xxx...xxx

In order to use profile2 we need to use --profile switch to specify it
 
$ aws [command] [sub-command] --profile profile2

To avoid repeating this, we can set AWS_PROFILE environment variable to desired profile:
 
$ export AWS_PROFILE=profile2
 

Using AWS CLI


AWS CLI command syntax:

$ aws
usage: aws [options] <command> <subcommand> [<subcommand> ...] [parameters]
To see help text, you can run:

  aws help
  aws <command> help
  aws <command> <subcommand> help



<command> is usually a service we want to interact with e.g. iam
<subcommand> specifies which operations to perform e.g. create-user
 

Example: creating a user


$ aws iam create-user --user-name test-user-1
{
    "User": {
        "Path": "/",
        "UserName": "test-user-1",
        "UserId": "AIDBBQ3OFFXCBT3AQWDK7",
        "Arn": "arn:aws:iam::136201378220:user/test-user-1",
        "CreateDate": "2022-05-12T11:55:25Z"
    }
}

Arn = Amazon Resource Name, a unique name assign to every resource in AWS

To see help for each command or subcommand:

$ aws iam help
$ aws iam create-user help

Example: list users

 
$ aws iam list-users
{
    "Users": [
          ...
         {
             "Path": "/",
             "UserName": "test-user-1",
             "UserId": "AIDBBQ3OFFXCBT3AQWDK7",
             "Arn": "arn:aws:iam::136201378220:user/test-user-1",
             "CreateDate": "2022-05-12T11:55:25Z"
        },
         ...
    ]
}
 

 
If using LocalStack:
 
$ aws --endpoint http://aws:4566 iam list-users
 

Example: deleting a user:

 
$ aws iam delete-user --user-name test-user-1

 

Example: attaching a policy to a user:

 
$ aws --endpoint http://aws:4566 iam attach-user-policy --user-name amelia --policy-arn arn:aws:iam::aws:policy/AdministratorAccess
 
 

Example: creating a group:

 
$ aws --endpoint http://aws:4566 iam create-group --group-name project-calabria-developers               {
    "Group": {
        "Path": "/",
        "GroupName": "project-calabria-developers",
        "GroupId": "c2tuoijto26m2cvuensk",
        "Arn": "arn:aws:iam::000000000000:group/project-calabria-developers",
        "CreateDate": "2022-05-12T13:53:47.627000+00:00"
    }
}

Example: adding a user to a group:


$ aws --endpoint http://aws:4566 iam add-user-to-group --group-name project-calabria-developers --user-name meridith
 
 
 

Example: check policies attached to the group: 

 
$ aws --endpoint http://aws:4566 iam list-attached-group-policies --group-name project-calabria-developers 
 
 

Example: check policies attached to user:

 
$ aws --endpoint http://aws:4566 iam list-attached-user-policies --user-name meridith


Example: attach a policy to a group

 
$ aws --endpoint http://aws:4566 iam attach-group-policy --group-name project-calabria-developers --policy-arn arn:aws:iam::aws:policy/AmazonEC2FullAccess 
 

How to check which AWS account is used by aws cli?

$ aws sts get-caller-identity
{
    "UserId": "AIDAQQ3OFFXCDDYYVTMN5",
    "Account": "046202377221",
    "Arn": "arn:aws:iam::046202377221:user/bojan.komazec"
}



How to authenticate to AWS via 3rd Party Identity Provider Services?



If we already manage user identities outside of AWS (e.g. via Google, Microsoft etc...) we can:
  • use Identity Providers (IdPs) instead of creating IAM users in our AWS account
  • give these external user identities permissions to use AWS resources in our account. This is useful if:
    • our organization already has its own identity system, such as a corporate user directory
    • we are creating a mobile app or web application that requires access to AWS resources

External IdP provides identity information to AWS using:
  • OpenID Connect (OIDC)
    • connects applications, like GitHub Actions, that do not run on AWS to AWS resources
  • SAML 2.0 (Security Assertion Markup Language 2.0)
    • Examples of well-known SAML identity providers are Shibboleth and Active Directory Federation Services
When we use an identity provider, we don't have to create custom sign-in code or manage our own user identities. The IdP provides that for us. Our external users sign in through an IdP, and we can give those external identities permissions to use AWS resources in our account. Identity providers help keep our AWS account secure because we don't have to distribute or embed long-term security credentials, such as access keys, in our application.

Best Practices





---

No comments: