Lab: Implementing Secure Authentication with IAM Roles and Secrets Manager
Authentication Mechanisms
Lab: Implementing Secure Authentication with IAM Roles and Secrets Manager
In this lab, you will apply industry-standard authentication mechanisms within an AWS environment. You will move away from risky long-term IAM user credentials and instead implement IAM Roles for service-to-service authentication and AWS Secrets Manager for secure credential storage and rotation.
[!WARNING] Remember to run the teardown commands at the end of this lab to avoid ongoing charges for the EC2 instance and Secrets Manager secrets.
Prerequisites
- An active AWS Account.
- AWS CLI configured on your local machine with
AdministratorAccess. - Basic familiarity with the Linux command line.
- Access to a region where Amazon EC2 and AWS Secrets Manager are available (e.g.,
us-east-1).
Learning Objectives
- Create and attach an IAM Role to an EC2 instance to eliminate hardcoded credentials.
- Implement the Principle of Least Privilege using custom IAM policies.
- Securely store and retrieve sensitive information using AWS Secrets Manager.
- Verify authentication flows through the AWS CLI.
Architecture Overview
This diagram illustrates the flow of authentication. Instead of storing an Access Key on the EC2 instance, the instance "assumes" a role to gain temporary security credentials.
Step-by-Step Instructions
Step 1: Create a Least-Privilege IAM Policy
First, we define exactly what our data processor is allowed to do. We want it to list objects in a specific bucket and retrieve a specific secret.
# Create a policy file
cat <<EOF > lab-policy.json
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": ["s3:ListBucket", "s3:GetObject"],
"Resource": ["arn:aws:s3:::brainybee-lab-*", "arn:aws:s3:::brainybee-lab-*/*"]
},
{
"Effect": "Allow",
"Action": "secretsmanager:GetSecretValue",
"Resource": "*"
}
]
}
EOF
# Create the IAM Policy
aws iam create-policy --policy-name DataEngineerLabPolicy --policy-document file://lab-policy.json▶Console Alternative
Navigate to
. Select the
tab and paste the code above. Name it
DataEngineerLabPolicy.
Step 2: Create the IAM Role and Instance Profile
Services cannot "assume" a role unless we grant them permission to do so via a Trust Policy.
# Create trust policy for EC2
cat <<EOF > trust-policy.json
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": { "Service": "ec2.amazonaws.com" },
"Action": "sts:AssumeRole"
}
]
}
EOF
# Create the Role
aws iam create-role --role-name DataEngineerRole --assume-role-policy-document file://trust-policy.json
# Attach the policy from Step 1 (Replace <ACCOUNT_ID>)
aws iam attach-role-policy --role-name DataEngineerRole --policy-arn arn:aws:iam::<YOUR_ACCOUNT_ID>:policy/DataEngineerLabPolicy
# Create Instance Profile (required for EC2 to use a role)
aws iam create-instance-profile --instance-profile-name DataEngineerInstanceProfile
aws iam add-role-to-instance-profile --instance-profile-name DataEngineerInstanceProfile --role-name DataEngineerRoleStep 3: Store a Secret in Secrets Manager
Instead of hardcoding a database password in your app, you will store it in the managed service.
aws secretsmanager create-secret --name "lab/db/password" \
--description "Database password for data engineering lab" \
--secret-string "{\"username\":\"admin\",\"password\":\"P@ssw0rd123!\"}"[!TIP] In a production environment, you would enable Rotation to automatically change this password every 30-90 days.
Step 4: Launch EC2 with the Instance Profile
Now we launch a small instance and tell AWS to give it the identity we just created.
# Launch t2.micro instance
aws ec2 run-instances --image-id ami-0c101f26f147fa7fd --count 1 --instance-type t2.micro \
--iam-instance-profile Name=DataEngineerInstanceProfile \
--tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=AuthenticationLab}]'Checkpoints
- Verify Role Attachment: Navigate to the EC2 console. Select your instance and check the "IAM Role" field. It should say
DataEngineerRole. - Test Authentication: SSH into your instance (or use EC2 Instance Connect) and run:
If successful, you will see the JSON secret without ever having to runbash
aws secretsmanager get-secret-value --secret-id lab/db/passwordaws configureon that machine.
Visual Concept: IAM Policy Structure
\begin{tikzpicture}[node distance=2cm] \draw[thick, fill=blue!10] (0,0) rectangle (6,4); \node at (3,3.5) {\textbf{IAM Policy Document}}; \draw[fill=white] (0.5,0.5) rectangle (2.5,2.5); \node[align=center, font=\scriptsize] at (1.5,1.5) {\textbf{Effect}\Allow/Deny}; \draw[fill=white] (3.5,0.5) rectangle (5.5,2.5); \node[align=center, font=\scriptsize] at (4.5,1.5) {\textbf{Principal}\Who?}; \draw[->, thick] (3,-0.5) -- (3,0.5) node[midway, right] {Evaluation}; \end{tikzpicture}
Troubleshooting
| Error | Likely Cause | Fix |
|---|---|---|
An error occurred (AccessDenied) | The IAM Policy does not have the correct ARN for the secret or bucket. | Check the Resource block in lab-policy.json. |
InstanceProfile not found | There is a propagation delay in IAM. | Wait 60 seconds and try the command again. |
Connection Timeout | Security Group is not allowing SSH (Port 22). | Update the VPC Security Group to allow your IP on port 22. |
Concept Review
| Mechanism | Best Use Case | Security Benefit |
|---|---|---|
| IAM User | Humans accessing the Console/CLI. | Individual accountability. |
| IAM Role | Applications or Services (EC2, Lambda). | No long-term credentials to leak. |
| Secrets Manager | Database credentials, API Keys. | Automatic rotation and encryption. |
| Identity Center | Large organizations with many users. | Centralized SSO and directory sync. |
Clean-Up / Teardown
To avoid charges, delete these resources in order:
# 1. Terminate EC2 Instance (Get ID from console or previous output)
aws ec2 terminate-instances --instance-ids <YOUR_INSTANCE_ID>
# 2. Delete Secret
aws secretsmanager delete-secret --secret-id lab/db/password --force-delete-without-recovery
# 3. Remove Role from Profile and Delete
aws iam remove-role-from-instance-profile --instance-profile-name DataEngineerInstanceProfile --role-name DataEngineerRole
aws iam delete-instance-profile --instance-profile-name DataEngineerInstanceProfile
aws iam detach-role-policy --role-name DataEngineerRole --policy-arn arn:aws:iam::<YOUR_ACCOUNT_ID>:policy/DataEngineerLabPolicy
aws iam delete-role --role-name DataEngineerRole
aws iam delete-policy --policy-arn arn:aws:iam::<YOUR_ACCOUNT_ID>:policy/DataEngineerLabPolicyCost Estimate
- EC2 t2.micro: Free Tier eligible (otherwise ~$0.0116/hour).
- Secrets Manager: $0.40 per secret per month (pro-rated for this lab: <$0.01).
- IAM: Free.
Stretch Challenge
Try to modify the IAM Policy so the EC2 instance can only retrieve the secret if it is accessed from within your specific VPC. Look up the aws:SourceVpc condition key in AWS documentation.