- Project Overview
- Prerequisites
- Objectives
- Architecture Diagram
- Step-by-Step Implementation
- Use Case Scenarios
- Security Best Practices
- Important Security Notes
- Learning Outcomes
- Future Improvements
- Resources & References
- Author
This project demonstrates the implementation of the Principle of Least Privilege in AWS. The goal was to move away from using root accounts or full-access admin users by creating a specialized IAM user with strictly limited permissions.
The project involves creating a custom JSON policy that restricts a user to only read and list files from a specific S3 bucket, denying all other actions.
| Attribute | Details |
|---|---|
| ⏱️ Time to Complete | 30-45 minutes |
| 📚 Difficulty Level | Beginner-Intermediate |
| 💰 AWS Cost | Free Tier Eligible |
| 🔧 Services Used | IAM, S3, AWS CLI |
Before starting this project, ensure you have:
- AWS Account with Administrator access
- AWS CLI installed and configured (Installation Guide)
- Basic understanding of JSON syntax
- An existing S3 bucket (or create one for testing)
| Objective | Description |
|---|---|
| 🆔 Identity Management | Create a dedicated programmatic user (s3-read-user) |
| 🔒 Access Control | Draft a custom IAM policy using JSON for granular permissions |
| ✅ Verification | Authenticate and test permissions using the AWS CLI |
This architecture demonstrates:
- IAM User with programmatic access credentials
- Custom Policy attached with specific S3 permissions
- Single Bucket Access -
my-secure-bucket✅ - Other Buckets Denied - Access blocked ❌
- Log in to the AWS Management Console as an Administrator
- Navigate to IAM Dashboard → Users → Add user
- Configure the user details:
| Setting | Value |
|---|---|
| Username | s3-read-user |
| Access Type | Programmatic Access |
| Permissions | Custom Policy (created in Phase 2) |
⚠️ Important: Save the Access Key ID and Secret Access Key securely. You won't be able to view the secret key again after this step!
Instead of attaching a managed policy like AmazonS3ReadOnlyAccess (which grants access to all buckets), I created an Inline Policy to restrict access to a specific resource.
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowS3ReadAccess",
"Effect": "Allow",
"Action": [
"s3:ListBucket",
"s3:GetObject"
],
"Resource": [
"arn:aws:s3:::my-secure-bucket",
"arn:aws:s3:::my-secure-bucket/*"
]
}
]
}| Component | Purpose | Scope |
|---|---|---|
s3:ListBucket |
Allows listing objects inside the bucket | Bucket level ARN |
s3:GetObject |
Allows downloading/reading files | Object level (/*) |
| Resource Restriction | Policy is locked to my-secure-bucket |
Prevents access to any other data |
💡 Why two ARN formats?
AWS S3 permissions work at two levels:
- Bucket Level (
arn:aws:s3:::bucket-name) - For operations likeListBucket - Object Level (
arn:aws:s3:::bucket-name/*) - For operations likeGetObject
Both must be specified to allow complete read access!
After generating the credentials, configure the local environment to simulate a developer accessing cloud resources.
aws configure --profile s3-userWhen prompted, enter the following:
AWS Access Key ID: [Paste Key ID]
AWS Secret Access Key: [Paste Secret Key]
Default region name: us-east-1
Default output format: json
# List objects in the allowed bucket
aws s3 ls s3://my-secure-bucket --profile s3-user✅ Expected Result: Successfully listed files
2025-01-01 10:00:00 1024 config.json
2025-01-01 10:00:00 2048 data.csv
2025-01-01 10:00:00 512 readme.txt
Test that the policy correctly denies access to other buckets:
# Attempt to list a different bucket (should fail)
aws s3 ls s3://other-sensitive-bucket --profile s3-user❌ Expected Result: Access Denied
An error occurred (AccessDenied) when calling the ListObjectsV2 operation: Access Denied
This configuration is ideal for:
| Use Case | Description |
|---|---|
| 🔌 Third-party Applications | Giving an external reporting tool access to read logs from one specific bucket |
| 👨💻 Developers | Allowing a frontend developer to fetch assets without admin rights |
| ⚙️ Microservices | Services that only need to read configuration files |
| 🔄 CI/CD Pipelines | Automated deployment processes requiring read access to artifact buckets |
| 📊 Analytics Tools | Read-only access for data visualization tools |
| Practice | Description | Status |
|---|---|---|
| Least Privilege | User has 0 permissions by default; only explicit allowances added | ✅ |
| Resource Constraints | Policy restricted to specific ARNs, not * (all resources) |
✅ |
| Credential Safety | Access Keys not hardcoded; used via AWS CLI profiles | ✅ |
| Separation of Duties | Created specific user instead of sharing Admin credentials | ✅ |
| Regular Auditing | Use CloudTrail to monitor IAM user activity | ✅ |
| No Root Usage | Root account not used for day-to-day operations | ✅ |
🚨 Never commit AWS credentials to version control!
| Method | Best For | Security Level |
|---|---|---|
| Environment Variables | Local development | ⭐⭐ |
| AWS CLI Profiles | Developer workstations | ⭐⭐⭐ |
| IAM Roles | EC2/Lambda (preferred) | ⭐⭐⭐⭐⭐ |
| AWS Secrets Manager | Production applications | ⭐⭐⭐⭐⭐ |
| AWS SSO | Enterprise environments | ⭐⭐⭐⭐⭐ |
# ❌ DON'T: Hardcode credentials
export AWS_ACCESS_KEY_ID="AKIAXXXXXXXXXXXXXXXX"
# ✅ DO: Use profiles or IAM roles
aws s3 ls --profile s3-userAfter completing this project, you will understand:
- How to create IAM users with programmatic access
- Writing custom JSON policies for fine-grained access control
- The difference between inline and managed policies
- How to test IAM permissions using AWS CLI
- Implementing the Principle of Least Privilege
- Resource-level permissions vs. service-level permissions
| Enhancement | Description | Priority |
|---|---|---|
| 🔐 MFA Enforcement | Add condition in policy to require Multi-Factor Authentication | High |
| 🎭 IAM Roles | Transition from IAM Users to IAM Roles for EC2 integration | High |
| 📜 Policy Versioning | Implement policy version control using AWS Policy Simulator | Medium |
| 🔔 CloudWatch Alarms | Set up alerts for unauthorized access attempts | Medium |
| ⏱️ Session Policies | Implement temporary credentials with session policies | Low |
| 🏷️ Resource Tags | Add tag-based access control for dynamic environments | Low |
| Resource | Description |
|---|---|
| 📖 AWS IAM Best Practices | Official AWS security guidelines |
| 🪣 S3 Bucket Policies | Comprehensive S3 access control |
| 🧪 AWS Policy Simulator | Test policies before deployment |
| 🛡️ OWASP Cloud Security | Cloud security best practices |
| 📋 CIS AWS Foundations Benchmark | Security compliance standards |
This project is licensed under the MIT License - see the LICENSE file for details.
⭐ If this project helped you understand IAM policies, please star the repository!
Made with ❤️ for the Cloud Security Community





