Official AWS guide to securing your account with IAM. Read the "Security best practices in IAM" section. Read →
Before touching anything in AWS, do this immediately after creating your account:
The root account has unlimited privileges and cannot be restricted. If compromised, everything is lost. Lock it away — enable MFA, then never log in as root except for emergencies.
IAM controls who can do what to which AWS resources. The fundamental principle is least privilege: grant only the permissions actually needed, nothing more.
// Example IAM policy: read-only access to one S3 bucket
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:GetObject",
"s3:ListBucket"
],
"Resource": [
"arn:aws:s3:::my-app-bucket",
"arn:aws:s3:::my-app-bucket/*"
]
}
]
}
When your EC2 instance needs to access S3, don't put AWS credentials in your code or environment. Attach an IAM role to the EC2 instance. The AWS SDK automatically uses the role's temporary credentials.
# Create a role with S3 read access and attach to EC2
# Via AWS CLI:
aws iam create-role --role-name MyAppEC2Role --assume-role-policy-document file://ec2-trust-policy.json
aws iam attach-role-policy --role-name MyAppEC2Role --policy-arn arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess
# Your Node.js app using AWS SDK automatically uses the role:
const s3 = new AWS.S3(); // No credentials needed — role is auto-used
Never hardcode AWS access keys in code or CI/CD. For EC2: use IAM roles. For GitHub Actions: use OIDC federation (configure once, no keys to rotate).
# Install AWS CLI v2
curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
unzip awscliv2.zip && sudo ./aws/install
# Configure with your IAM user credentials
aws configure
# AWS Access Key ID: [from IAM console]
# AWS Secret Access Key: [from IAM console]
# Default region: us-east-1
# Default output: json
# Verify
aws sts get-caller-identity
# Use named profiles for multiple accounts
aws configure --profile production
aws s3 ls --profile production