Skip to content
← Blog
Technical field note
6 min read

Ceph RGW Bucket Policies, Without the IAM Fog

Bucket policies are simply rules attached to a bucket: who can do what, on which resources, under which conditions. The RGW-specific details are where people get caught.

Operator note: Ceph RGW features and supported policy/API behavior vary by release. Check the documentation for your deployed version before turning an example into production policy.

Think of bucket access policies in Ceph RGW as the S3 JSON policy language attached to a bucket. Their job is to answer:

“Who can do what on this bucket or its objects?”

They are not about replication or storage durability. They are about authorization. Ceph RGW supports a subset of the Amazon S3 bucket policy language, and bucket policies are managed through standard S3 operations, not through radosgw-admin.

The mental model

Authorization in RGW usually comes from a combination of:

Request arrives at RGW
   │
   ├── Identity says: "who is calling?"
   │      access key / user / role / account
   │
   ├── Policy evaluation says: "what are they allowed to do?"
   │      IAM-style policy + bucket policy + ACLs
   │
   └── Result
          Allow or Deny

Ceph RGW supports S3-compatible users, and in newer releases also supports a subset of AWS-style IAM APIs for accounts, users, roles, and policies. Roles can issue temporary credentials and carry permission policies.

What a bucket policy can control

A bucket policy can target the bucket itself (example: allow ListBucket) or the objects inside the bucket (example: allow GetObject on arn:aws:s3:::mybucket/*).

That split matters a lot:

Bucket ARN:        arn:aws:s3:::mybucket
Object ARN(s):     arn:aws:s3:::mybucket/*

If you only grant access to mybucket/*, the caller may still fail bucket-level operations like listing. That structure is visible in Ceph’s own bucket policy examples, which use object resources like arn:aws:s3:::happybucket/.

The core JSON shape

A bucket policy in RGW looks like standard S3 policy JSON:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": { "AWS": ["arn:aws:iam::tenant:user/alice"] },
      "Action": ["s3:GetObject"],
      "Resource": ["arn:aws:s3:::mybucket/*"]
    }
  ]
}

The main fields mean:

  • Effect: Allow or Deny
  • Principal: who the statement applies to
  • Action: which S3 API actions are covered
  • Resource: bucket ARN or object ARN pattern
  • Condition: optional constraints such as IP, TLS, time, user-agent

Ceph RGW documents support for this policy model as a subset of S3 bucket policy behavior.

What “Principal” means in Ceph RGW

This is the identity the rule applies to. In RGW, that can include Ceph/RGW users and, in newer account/IAM setups, IAM-style users or roles. Ceph’s example shows principals in an AWS-like ARN form, such as:

arn:aws:iam::usfolks:user/fred:subuser

That tells you RGW is trying to stay close to S3/IAM-style principal naming, even though the backend is Ceph.

With newer User Accounts and IAM API support, account-scoped users and roles become more relevant, and resources created by account users are owned by the account, not by an individual standalone user.

Conditions you can use

Ceph RGW supports a limited set of condition keys for bucket/object requests. The docs list support for these keys across requests:

  • aws:CurrentTime
  • aws:EpochTime
  • aws:PrincipalType
  • aws:Referer
  • aws:SecureTransport
  • aws:SourceIp
  • aws:UserAgent
  • aws:username

So in practice, useful RGW bucket policy patterns include:

Force HTTPS

{
  "Effect": "Deny",
  "Principal": "*",
  "Action": "s3:*",
  "Resource": [
    "arn:aws:s3:::mybucket",
    "arn:aws:s3:::mybucket/*"
  ],
  "Condition": {
    "Bool": { "aws:SecureTransport": "false" }
  }
}

Restrict by source IP

{
  "Effect": "Allow",
  "Principal": "*",
  "Action": ["s3:GetObject"],
  "Resource": ["arn:aws:s3:::mybucket/*"],
  "Condition": {
    "IpAddress": { "aws:SourceIp": "10.0.0.0/8" }
  }
}

Time-bound access

Use aws:CurrentTime or aws:EpochTime to limit when access is valid. Ceph explicitly documents support for those keys.

One subtle but important limit

Ceph’s docs note that bucket policies do not yet support string interpolation. That means policy constructs that rely on AWS variable substitution are not something you should assume will work in RGW.

So for RGW, it is safer to write explicit principals and explicit resources rather than clever reusable variable-heavy policies.

Common patterns

1) Read-only access to objects

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": { "AWS": ["arn:aws:iam::acct:user/app-reader"] },
      "Action": ["s3:GetObject"],
      "Resource": ["arn:aws:s3:::reports/*"]
    }
  ]
}

2) Allow list + read

You often need both bucket-level and object-level permissions:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": { "AWS": ["arn:aws:iam::acct:user/app-reader"] },
      "Action": ["s3:ListBucket"],
      "Resource": ["arn:aws:s3:::reports"]
    },
    {
      "Effect": "Allow",
      "Principal": { "AWS": ["arn:aws:iam::acct:user/app-reader"] },
      "Action": ["s3:GetObject"],
      "Resource": ["arn:aws:s3:::reports/*"]
    }
  ]
}

3) Cross-account or cross-user log delivery

Ceph’s bucket logging docs explicitly mention that source and log buckets may belong to different accounts, with the proper bucket policy set on the log bucket.

That is a good real example of why bucket policies matter: they let one bucket owner permit controlled writes from another identity.

How bucket policies fit with ACLs and IAM

A practical way to see the layers:

ACLs           = old-style per-bucket/per-object grants
Bucket policy  = resource-based policy attached to the bucket
IAM policy     = identity-based policy attached to user/role/account

Ceph says ACLs and bucket policies are supported in RGW’s S3 feature matrix, and newer RGW IAM/account features add user/role policy management on top.

So the usual guidance is:

  • use bucket policy for resource sharing
  • use IAM/role policy for what an identity is allowed to do in general
  • keep ACLs minimal unless you specifically need them

How you manage bucket policies

This is an easy place to trip up:

Bucket policy management in RGW:
   use S3 API / S3 client
   not radosgw-admin

Ceph explicitly says bucket policies are managed through standard S3 operations, not radosgw-admin.

So you typically use something like aws s3api put-bucket-policy, aws s3api get-bucket-policy, and aws s3api delete-bucket-policy against your RGW S3 endpoint.

Ownership matters

In older/non-account usage, resources are typically owned by the individual user that created them. In newer account mode, resources created by account users or roles are owned by the account itself. That changes how sharing and permissions feel, because the “owner” becomes the account boundary rather than a single raw user.

That is especially important if you are trying to mimic AWS-style org/account patterns on RGW.

Practical rules of thumb

Need to let someone list a bucket?     Include bucket ARN
Need to let someone read objects?      Include object ARN pattern
Need tighter control?                  Add SourceIp / SecureTransport / time conditions
Need reusable identity logic?          Prefer IAM/role policy
Need resource sharing?                 Prefer bucket policy

RGW-specific caveats worth checking

For Ceph RGW, I would assume:

  • subset, not full AWS policy parity
  • supported condition keys are limited to the documented set
  • string interpolation is not supported in bucket policies
  • manage policies through S3 API calls, not admin CLI

The short version

A Ceph RGW S3 bucket policy is a resource-based JSON access policy attached to a bucket that controls which users/roles/accounts can perform which S3 actions on the bucket and its objects, with partial AWS compatibility and a documented subset of supported condition features.

Official references

For the exact actions, condition keys and limitations supported by your release, use the Ceph bucket policy documentation and the RGW S3 compatibility matrix.