CephXXXIV · Multi-Tenancy ConceptsMulti-Tenancy Concepts
RGW tenants and bucket namespace separation
What you'll learn
- Create tenanted RGW users
- Explain how tenants partition the bucket namespace
- Address tenanted resources in S3 requests
- Choose between tenants and separate zones
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
Why this matters in production
S3 bucket names are global within a deployment by default, which means the
first customer to create backups prevents every other customer from
doing so. For a service with external customers that is unacceptable, and
the tenant mechanism is the supported fix.
The problem tenants solve
Without tenants:
radosgw-admin user create --uid=alice --display-name="Alice"
radosgw-admin user create --uid=bob --display-name="Bob"
# alice creates bucket "backups"
# bob cannot create "backups" — the name is taken
With tenants, each gets an independent namespace:
radosgw-admin user create --tenant=acme --uid=alice --display-name="Alice at Acme"
radosgw-admin user create --tenant=globex --uid=bob --display-name="Bob at Globex"
Now acme/backups and globex/backups are different buckets. Users are
identified as tenant$uid:
radosgw-admin user info --tenant=acme --uid=alice
radosgw-admin user list
# "acme$alice"
# "globex$bob"
Addressing tenanted resources
A tenanted user’s own buckets are addressed normally — the tenant is implicit from their credentials:
aws --endpoint-url https://rgw.example.com s3 ls s3://backups
Cross-tenant access, where granted by policy, uses the explicit form:
s3://acme:backups/object-key
This matters when writing bucket policies that reference principals in other tenants.
Per-tenant administration
# quotas
radosgw-admin quota set --tenant=acme --uid=alice \
--quota-scope=user --max-size=50T
radosgw-admin quota enable --tenant=acme --uid=alice --quota-scope=user
# usage
radosgw-admin usage show --tenant=acme --uid=alice
# suspend an entire customer's access
radosgw-admin user suspend --tenant=acme --uid=alice
Tenants versus zones
| Requirement | Mechanism |
|---|---|
| Separate bucket namespaces | tenants |
| Per-customer quotas and usage | tenants |
| Separate storage pools per customer | separate placement targets |
| Separate geographic replication | separate zonegroups |
| Complete infrastructure separation | separate clusters |
Tenants are a naming and administrative boundary within one RGW deployment. Customers sharing the deployment share its gateways, its pools, and its failure modes.
Quiz
Knowledge check · 4 questions
Q1. What problem does the RGW tenant mechanism solve?
Q2. A non-tenanted RGW user can be migrated into a tenant without copying data.
Q3. Plan an S3 service for external customers.
A team is building an S3-compatible service for external customers on Ceph. The initial launch has one pilot customer. They plan to add tenants later "once there is more than one customer".
Q4. Why can a client not defeat tenant separation by constructing its own request?
Passing score: 75%. Answers are checked in this browser.
Production discipline
Adopt tenants at service launch even with a single customer; the retrofit cost grows with every object stored and there is no cheap migration. Establish the tenant naming convention and the addressing format in client documentation early, since cross-tenant policy references depend on it.
Cross-course references
- Kubernetes: namespaces partition resource names for exactly the same reason
- Linux: per-user home directories partition a shared filesystem namespace the same way