Ravindra BagaleCourses & study guides

14. Amazon S3: Buckets, Objects, Policies and Presigned URLs

14.7 Encryption, Logging, IAM Roles and the S3 Security Checklist

Encryption at rest (संग्रहित माहितीचे कूटबद्धीकरण): every new object is encrypted with SSE-S3 by default. For more control, choose SSE-KMS (keys in AWS KMS, every use logged in CloudTrail). Encryption in transit: always HTTPS – enforce it with the DenyInsecureTransport statement from 14.3.

Access from EC2 – use an IAM role, never access keys on the server. Create a role once, attach it to the instance, and the CLI and SDKs pick up temporary credentials automatically.

  1. IAM → Roles → Create role → Trusted entity: AWS service → EC2.
  2. Attach a custom policy (below), name the role reels-ec2-role.
  3. EC2 → select instance → Actions → Security → Modify IAM role → choose the role.
  4. On the instance: aws sts get-caller-identity shows assumed-role/reels-ec2-role/....
{
  "Version": "2012-10-17",
  "Statement": [{
    "Effect": "Allow",
    "Action": ["s3:PutObject", "s3:GetObject", "s3:DeleteObject"],
    "Resource": "arn:aws:s3:::ravindra-reels-media-pune/videos/*"
  }]
}

Logging and monitoring: enable server access logging (or CloudTrail data events) into a separate log bucket, so you can answer "who downloaded this file, from which IP, when?".

CORS – needed when JavaScript on https://yourdomain.com talks to the bucket directly (for example browser uploads with presigned PUT URLs). Allow only your own origin:

[{ "AllowedOrigins": ["https://yourdomain.com"], "AllowedMethods": ["GET", "PUT"],
   "AllowedHeaders": ["*"], "MaxAgeSeconds": 3000 }]
S3 security checklist Done?
Account-level Block Public Access ON (except deliberate website buckets) ☐
Object Ownership = Bucket owner enforced (ACLs disabled) ☐
Bucket policy has no Principal: "*" Allow (except GetObject on website buckets) ☐
DenyInsecureTransport statement added ☐
Default encryption SSE-S3 or SSE-KMS ☐
Versioning ON + lifecycle rule for old versions ☐
Apps use IAM roles with least privilege, scoped to a prefix ☐
Access logging or CloudTrail data events enabled ☐
Private content served with short presigned URLs ☐
No secrets, backups or .git inside public buckets ☐

Why this matters for security

Access keys copied onto a server (or pushed to GitHub) are among the most common ways cloud accounts get compromised – bots scan public repositories for them continuously. IAM roles give short-lived credentials that rotate automatically and never sit in a file you might leak.

Ravindra Bagale's Tip

Running aws configure on EC2 and entering your personal access key – this is students' biggest mistake. The key stays in ~/.aws/credentials, and if the server is compromised, the attacker gets your whole account. Always use an IAM role on EC2, and avoid long-term keys even on your laptop as far as possible. Remember: role = no keys.

Lab

Create reels-ec2-role with the policy above, attach it to an EC2 instance, and run aws sts get-caller-identity, aws s3 cp into videos/ (works) and into other/ (AccessDenied). Then run through the checklist for your demo bucket and tick every row.

Thodkyaat sangaycha tar

  • S3 = buckets (globally unique names) + objects addressed by keys; prefixes only look like folders.
  • Everything is private by default; Block Public Access is the master safety switch – keep it ON.
  • Bucket policies = Effect / Principal / Action / Resource / Condition; bucket ARN vs bucket/*.
  • Static website: public GetObject only; for HTTPS and a domain use CloudFront with OAC.
  • Versioning + lifecycle protect against deletes and overwrites; deletes create delete markers.
  • Presigned URLs give short, temporary access to private objects – keep expiry short.
  • EC2 talks to S3 with an IAM role, never with access keys on disk; enforce HTTPS and encryption.

Samjla ka? Nasel tar 14.3 aani 14.6 punha vacha – project madhe he doghe lagnar aahet. Aata pudhe jaauya RDS MySQL kade!