Implementing AWS S3 Read-Only Roles with Open Policy Agent

The bucket waits in silence, holding terabytes of data you need but cannot risk exposing. Access must be clean, verifiable, and locked to read-only. That is where Open Policy Agent (OPA) meets AWS S3 roles.

Using OPA for AWS S3 read-only roles gives you full control over who can see what, and when. You define policies as code, test them before deployment, and enforce them at the edge. No hidden permissions. No accidental writes.

Start by creating an IAM role in AWS with the s3:GetObject and s3:ListBucket actions. Attach this role to your application or service identity. This ensures AWS allows only the read operations you specify.

OPA sits between your application and AWS’s SDK or API calls. You write a Rego policy that inspects the request context—user identity, request path, resource tags—and returns allow = true only if the role matches your rules. Everything else is denied.

Example Rego snippet:

package s3read

default allow = false

allow {
 input.action == "s3:GetObject"
 input.role == "read-only-role"
}
allow {
 input.action == "s3:ListBucket"
 input.role == "read-only-role"
}

Integrate OPA with your API gateway or service middleware. All S3 requests pass through OPA, and the decision log captures every access attempt, giving you a transparent audit trail.

This approach scales across multiple buckets and accounts. You can enforce consistent AWS S3 read-only access rules across microservices or teams, without relying solely on IAM policy syntax.

When OPA policies and AWS roles work together, security is deterministic. You know the exact shape of your access graph. You can ship changes with confidence, backed by automated tests for every policy.

Don’t just read about it—see it live. Try implementing AWS S3 read-only roles with OPA in hoop.dev and watch it run in minutes.