The bucket sat wide open. Access logs told the story: too many hands where only a select few should reach. You need control, and you need it baked into code before the first policy hits production. This is where Policy-as-Code for AWS S3 read-only roles proves its worth.
Policy-as-Code moves access rules out of ad-hoc console clicks and into version-controlled, testable code. For AWS S3, that means defining IAM policies that lock down permissions to only the operations your workflows require: s3:GetObject, s3:ListBucket, and nothing more. By codifying these in Terraform, Pulumi, or CloudFormation, you remove guesswork and enforce the principle of least privilege from day one.
A secure read-only IAM policy for S3 starts with minimal actions and scoped resources. Specify the exact bucket ARN and, when possible, limit paths or prefixes. Avoid wildcards unless there’s a strong operational reason. Every permission line should have a justification you can defend. In a Policy-as-Code setup, this policy is stored in your repo, peer-reviewed, and deployed through CI/CD.