Leveraging AWS IAM for Service-to-Service Authentication and Authorization

am
AWSome Diary
8 min readJul 11, 2024

--

AWS Identity and Access Management (IAM) provides robust tools to manage and secure service-to-service interactions within your AWS environment. This article delves into the intricacies of leveraging AWS IAM for service-to-service authentication and authorization, offering a comprehensive guide with use cases, examples, commands, and scripts.

Understanding AWS IAM

What is AWS IAM?

AWS Identity and Access Management (IAM) is a web service that enables you to manage access to AWS services and resources securely. With IAM, you can create and manage AWS users and groups, and use permissions to allow or deny their access to AWS resources.

Core Concepts of IAM

  1. Users: Represents a person or application that interacts with AWS resources. Users have permanent long-term credentials and are used for interactive access or programmatic access to AWS.
  2. Groups: Collections of users with common access permissions.
  3. Roles: IAM roles are sets of permissions that define what actions are allowed and denied by an entity in the AWS environment. Unlike users, roles do not have long-term credentials. Instead, entities assume roles and are granted temporary security credentials.
  4. Policies: JSON documents that define permissions and can be attached to users, groups, or roles. Policies dictate what actions are allowed or denied on which resources.

Service-to-Service Authentication and Authorization

Service-to-Service Authentication

Service-to-service authentication involves verifying the identity of one service when it communicates with another. This ensures that only authenticated services can access your AWS resources.

Service-to-Service Authorization

Service-to-service authorization determines what actions a service can perform on resources. This is controlled using IAM policies, which can be attached to roles that services assume.

Use Cases

1. EC2 Instance Accessing S3 Buckets

In many scenarios, EC2 instances need to interact with S3 buckets, for example, to store logs or read data files. Using IAM roles, you can securely grant EC2 instances the permissions they need without embedding credentials.

2. Lambda Function Accessing DynamoDB

Lambda functions often need to read from or write to DynamoDB tables. By assigning an IAM role to the Lambda function, you can manage permissions easily and securely.

3. ECS Task Accessing Secrets Manager

ECS tasks might need to retrieve sensitive data from AWS Secrets Manager, such as database credentials or API keys. IAM roles enable ECS tasks to access Secrets Manager securely.

4. CodeBuild Accessing ECR

AWS CodeBuild projects often need to pull images from or push images to Amazon Elastic Container Registry (ECR). Using IAM roles, you can grant CodeBuild the necessary permissions to interact with ECR repositories.

5. CloudFormation Stack Actions

AWS CloudFormation stacks often create and manage multiple resources that need to interact. By using IAM roles, you can ensure that your CloudFormation stacks have the necessary permissions to perform their tasks.

Step-by-Step Examples

Example 1: EC2 Instance Accessing S3 Buckets

Create an IAM Role for EC2: To allow an EC2 instance to access S3, you first need to create an IAM role with a trust policy that grants the EC2 service permission to assume the role.

aws iam create-role --role-name EC2S3AccessRole --assume-role-policy-document file://ec2-trust-policy.json
  • ec2-trust-policy.json:
{   "Version": "2012-10-17",   "Statement": [     {       "Effect": "Allow",       "Principal": {         "Service": "ec2.amazonaws.com"       },       "Action": "sts:AssumeRole"     }   ] }

Attach an S3 Access Policy to the Role: Attach a policy that grants the necessary S3 permissions to the role.

aws iam attach-role-policy --role-name EC2S3AccessRole --policy-arn arn:aws:iam::aws:policy/AmazonS3FullAccess

Launch an EC2 Instance with the Role: Specify the IAM role when launching the EC2 instance.

aws ec2 run-instances --image-id ami-12345678 --count 1 --instance-type t2.micro --iam-instance-profile Name=EC2S3AccessRol

Access S3 from the EC2 Instance: Once the instance is running, it can access S3 using the role’s permissions.

aws s3 ls

Example 2: Lambda Function Accessing DynamoDB

Create an IAM Role for Lambda: Create a role that the Lambda function can assume, with a trust policy allowing Lambda to assume the role.

aws iam create-role --role-name LambdaDynamoDBAccessRole --assume-role-policy-document file://lambda-trust-policy.json
  • lambda-trust-policy.json:
{   "Version": "2012-10-17",   "Statement": [     {       "Effect": "Allow",       "Principal": {         "Service": "lambda.amazonaws.com"       },       "Action": "sts:AssumeRole"     }   ] }

Attach a DynamoDB Access Policy to the Role: Attach a policy that grants the necessary DynamoDB permissions to the role.

aws iam attach-role-policy --role-name LambdaDynamoDBAccessRole --policy-arn arn:aws:iam::aws:policy/AmazonDynamoDBFullAccess

Create a Lambda Function with the Role: Specify the IAM role when creating the Lambda function.

aws lambda create-function --function-name MyLambdaFunction --runtime python3.8 --role arn:aws:iam::123456789012:role/LambdaDynamoDBAccessRole --handler lambda_function.lambda_handler --zip-file fileb://function.zip

Access DynamoDB from the Lambda Function: Use the AWS SDK for Python (Boto3) to interact with DynamoDB.

import boto3  def lambda_handler(event, context):     dynamodb = boto3.resource('dynamodb')     table = dynamodb.Table('MyTable')     response = table.get_item(Key={'id': '123'})     return response

Example 3: ECS Task Accessing Secrets Manager

Create an IAM Role for ECS Task: Create a role that ECS tasks can assume, with a trust policy allowing ECS to assume the role.

aws iam create-role --role-name ECSSecretsManagerRole --assume-role-policy-document file://ecs-trust-policy.json

ecs-trust-policy.json:

{   "Version": "2012-10-17",   "Statement": [     {       "Effect": "Allow",       "Principal": {         "Service": "ecs-tasks.amazonaws.com"       },       "Action": "sts:AssumeRole"     }   ] }

Attach a Secrets Manager Access Policy to the Role: Attach a policy that grants the necessary Secrets Manager permissions to the role.

aws iam attach-role-policy --role-name ECSSecretsManagerRole --policy-arn arn:aws:iam::aws:policy/SecretsManagerReadWrite

Configure ECS Task Definition to Use the Role: Specify the IAM role in the ECS task definition.

{   "family": "my-ecs-task",   "taskRoleArn": "arn:aws:iam::123456789012:role/ECSSecretsManagerRole",   "containerDefinitions": [     {       "name": "my-container",       "image": "my-image",       "essential": true     }   ] }

Access Secrets Manager from ECS Task: Use the AWS SDK for Python (Boto3) to retrieve secrets from Secrets Manager.

import boto3  def get_secret():     client = boto3.client('secretsmanager')     response = client.get_secret_value(SecretId='MySecret')     return response['SecretString']

Example 4: CodeBuild Accessing ECR

Create an IAM Role for CodeBuild: Create a role that CodeBuild projects can assume, with a trust policy allowing CodeBuild to assume the role.

aws iam create-role --role-name CodeBuildECRRole --assume-role-policy-document file://codebuild-trust-policy.json

codebuild-trust-policy.json:

{   "Version": "2012-10-17",   "Statement": [     {       "Effect": "Allow",       "Principal": {         "Service": "codebuild.amazonaws.com"       },       "Action": "sts:AssumeRole"     }   ] }

Attach an ECR Access Policy to the Role: Attach a policy that grants the necessary ECR permissions to the role.

aws iam attach-role-policy --role-name CodeBuildECRRole --policy-arn arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryFullAccess

Create a CodeBuild Project with the Role: Specify the IAM role when creating the CodeBuild project.

{   "name": "my-codebuild-project",   "source": {     "type": "GITHUB",     "location": "https://github.com/my-repo.git"   },   "artifacts": {     "type": "NO_ARTIFACTS"   },   "environment": {     "type": "LINUX_CONTAINER",     "image": "aws/codebuild/standard:4.0",     "computeType": "BUILD_GENERAL1_SMALL",     "privilegedMode": true,     "environmentVariables": []   },   "serviceRole": "arn:aws:iam::123456789012:role/CodeBuildECRRole" }

Access ECR from CodeBuild: In the build specification file, use the AWS CLI to interact with ECR.

version: 0.2  phases:   pre_build:     commands:       - $(aws ecr get-login --no-include-email --region us-west-2)       - docker pull my-repo/my-image:latest   build:     commands:       - docker build -t my-repo/my-image:latest .       - docker tag my-repo/my-image:latest 123456789012.dkr.ecr.us-west-2.amazonaws.com/my-repo/my-image:latest   post_build:     commands:       - docker push 123456789012.dkr.ecr.us-west-2.amazonaws.com/my-repo/my-image:latest

Example 5: CloudFormation Stack Actions

Create an IAM Role for CloudFormation: Create a role that CloudFormation stacks can assume, with a trust policy allowing CloudFormation to assume the role.

aws iam create-role --role-name CloudFormationRole --assume-role-policy-document file://cloudformation-trust-policy.json

cloudformation-trust-policy.json:

{   "Version": "2012-10-17",   "Statement": [     {       "Effect": "Allow",       "Principal": {         "Service": "cloudformation.amazonaws.com"       },       "Action": "sts:AssumeRole"     }   ] }

Attach a Custom Policy to the Role: Create and attach a policy that grants the necessary permissions for the stack actions.

{   "Version": "2012-10-17",   "Statement": [     {       "Effect": "Allow",       "Action": [         "s3:*",         "ec2:*"       ],       "Resource": "*"     }   ] }

Save this as cloudformation-policy.json, then create and attach it:

aws iam create-policy --policy-name CloudFormationPolicy --policy-document file://cloudformation-policy.json aws iam attach-role-policy --role-name CloudFormationRole --policy-arn arn:aws:iam::123456789012:policy/CloudFormationPolicy

Specify the IAM Role in CloudFormation Template: In your CloudFormation template, specify the role for the stack.

AWSTemplateFormatVersion: '2010-09-09' Resources:   MyBucket:     Type: 'AWS::S3::Bucket'     Properties:       BucketName: 'my-bucket'

When creating the stack, specify the IAM role:

aws cloudformation create-stack --stack-name my-stack --template-body file://template.yaml --role-arn arn:aws:iam::123456789012:role/CloudFormationRole

Commands and Scripts

List IAM Roles

Use this command to list all IAM roles in your AWS account.

aws iam list-roles

Get IAM Role Details

Use this command to get detailed information about a specific IAM role.

aws iam get-role --role-name MyRole

Create a Custom IAM Policy

Define the Policy: Create a JSON file defining the policy. Here is an example for S3 access: my-policy.json:

{   "Version": "2012-10-17",   "Statement": [     {       "Effect": "Allow",       "Action": [         "s3:GetObject",         "s3:PutObject"       ],       "Resource": "arn:aws:s3:::my-bucket/*"     }   ] }

Create the Policy: Use the AWS CLI to create the policy.

aws iam create-policy --policy-name MyS3Policy --policy-document file://my-policy.json

Attach a Policy to a Role

Attach an existing policy to a role.

aws iam attach-role-policy --role-name MyRole --policy-arn arn:aws:iam::123456789012:policy/MyS3Policy

Detach a Policy from a Role

Detach a policy from a role.

aws iam detach-role-policy --role-name MyRole --policy-arn arn:aws:iam::123456789012:policy/MyS3Policy

Delete an IAM Role

Delete an IAM role that is no longer needed.

aws iam delete-role --role-name MyRole

Best Practices for Using IAM Roles for Service-to-Service Authentication and Authorization

Principle of Least Privilege

Always follow the principle of least privilege when assigning permissions. Grant only the permissions that are necessary for a service to perform its tasks, and no more.

Use Managed Policies

Where possible, use AWS managed policies. These policies are maintained by AWS and provide permissions for many common use cases.

Regularly Review IAM Policies and Roles

Regularly review your IAM policies and roles to ensure they are still necessary and secure. Remove any unused or overly permissive roles and policies.

Use Role Sessions

Use role sessions with temporary security credentials wherever possible. This reduces the risk of long-term credentials being compromised.

Monitor and Log IAM Activity

Enable AWS CloudTrail to monitor and log IAM activity. This provides an audit trail of who did what and when, helping you detect and respond to potential security incidents.

Rotate Keys and Credentials

Regularly rotate access keys and credentials. This reduces the risk of compromised keys being used for extended periods.

Use IAM Conditions

Use IAM conditions to add an additional layer of security. Conditions allow you to specify when a policy is in effect, based on factors such as time, IP address, or other request attributes.

AWS IAM provides a secure and flexible framework for managing service-to-service authentication and authorization. By leveraging IAM roles and policies, you can ensure that your services interact securely and efficiently without the need to hardcode credentials. Following best practices and regularly reviewing your IAM setup will help maintain a secure and well-managed AWS environment.

--

--

am
AWSome Diary

Unapologetically Nerdy. Privacy | Encryption | Digital Rights | FOSS | Video Tech | Security | GNU/Linux. Check out https://git.aloke.tech