Skip to main content
RunBook Academy

CephXLVIII · RGW TroubleshootingRGW Troubleshooting

Working an AccessDenied to its source

Advanced⏱ ~17 minawsradosgw-admin

What you'll learn

  • Enumerate the mechanisms that can deny access
  • Check each in the correct order
  • Diagnose policy and ACL interactions
  • Verify a grant actually works

Prerequisites

None — start here.

Verified against Ceph Tentacle 20.2.x · Ceph Squid 19.2.x (supported previous) · cephadm matches the verified Ceph release · podman 4.x · csi-rbd and csi-cephfs current · RBD / CephFS / RGW current (matches Ceph release) · Linux kernel 5.15+ (5.10 minimum) · Ubuntu 24.04 LTS (Ceph host baseline) · Debian 12 (Bookworm) (Ceph host baseline) · Rocky Linux / RHEL / AlmaLinux 9.x (Ceph host baseline) · Proxmox VE 9.x (cross-course integration) · Kubernetes 1.31+ (cross-course integration) · 2026-08-18

Not yet marked complete on this device.

Why this matters in production

AccessDenied is emitted by four independent mechanisms, and they interact. Checking them in a fixed order — cheapest and most decisive first — resolves it in minutes instead of by trial and error.

The four mechanisms

MechanismScopeOverrides
User suspensioneverything the user doeseverything
Bucket policy explicit Denythe bucketany Allow
Bucket policy Allow / no matchthe bucketdefault deny
Bucket and object ACLsthe bucket or objectpolicy may already have allowed
Subuser access levelthe parent user’s whole scopelimits what the credential can do

The order to check

1. Is the user suspended?

radosgw-admin user info --uid=analytics | jq '.suspended'

One field, and it overrides everything. Check it first.

2. Is there an explicit Deny in the bucket policy?

aws --endpoint-url $EP s3api get-bucket-policy --bucket data | jq -r '.Policy' | jq .

Look for "Effect": "Deny" and check whether its conditions match the failing request. A deny cannot be overridden.

3. Does the policy grant what is being attempted?

Check both the action and the resource ARN. ListBucket needs the bucket ARN; GetObject needs the object ARN.

4. Do the ACLs permit it?

aws --endpoint-url $EP s3api get-bucket-acl --bucket data
aws --endpoint-url $EP s3api get-object-acl --bucket data --key file.txt

Objects carry their own ACL, so an object uploaded by a different user may be inaccessible even where the bucket permits it.

5. Is the credential a subuser with a limiting access level?

radosgw-admin user info --uid=analytics | jq '.subusers'

The cross-user object case

aws --endpoint-url $EP s3api put-object --bucket shared --key f.txt --body f.txt \
    --acl bucket-owner-full-control

When user A uploads to user B’s bucket, the object is owned by A by default and B cannot read it despite owning the bucket. The bucket-owner-full-control ACL at upload time is the fix, and a bucket policy can require it:

{"Effect": "Deny", "Principal": "*", "Action": "s3:PutObject",
 "Resource": "arn:aws:s3:::shared/*",
 "Condition": {"StringNotEquals": {"s3:x-amz-acl": "bucket-owner-full-control"}}}

Verifying a grant

# as the granted credential, attempt the specific operation
AWS_ACCESS_KEY_ID=$K AWS_SECRET_ACCESS_KEY=$S \
  aws --endpoint-url $EP s3api get-object --bucket data --key file.txt /tmp/out

# and confirm the denial still holds where it should
AWS_ACCESS_KEY_ID=$K AWS_SECRET_ACCESS_KEY=$S \
  aws --endpoint-url $EP s3api get-object --bucket other --key file.txt /tmp/out

Quiz

Knowledge check · 4 questions

  1. Q1. A bucket owner receives AccessDenied on an object in their own bucket, uploaded by another user. Why?

  2. Q2. Checking user suspension should come first when investigating AccessDenied.

  3. Q3. Resolve access failures in a shared bucket.

    Several teams upload to a shared bucket. The bucket owner can list all objects but receives AccessDenied when reading objects uploaded by other teams. The bucket policy grants the owner full access.

  4. Q4. Why do ACLs and bucket policies both exist rather than one replacing the other?

Passing score: 75%. Answers are checked in this browser.

Production discipline

Check the four denial mechanisms in order — suspension, explicit deny, policy grant, ACLs — rather than guessing; the order is by cost and decisiveness. Require bucket-owner-full-control on shared buckets through a policy, since object ownership is the mechanism that most often produces confusing denials.

Cross-course references

  • Kubernetes: RBAC plus admission plus PodSecurity all denying independently is the same layered model
  • Linux: POSIX permissions plus ACLs plus MAC labels each denying separately follows the same pattern