CephXXXII · Least Privilege CapabilitiesLeast Privilege Capabilities
Minimal capabilities for CephFS clients
What you'll learn
- Construct a minimal CephFS client capability set
- Restrict a client to a subtree with path scoping
- Apply root_squash and read-only restrictions
- Verify a path restriction is actually enforced
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
A CephFS client without path restriction sees the entire filesystem. On a shared filesystem that is every tenant’s data, and the restriction that prevents it lives in the cephx capability rather than in POSIX permissions — so getting it right is a storage-side decision, not an application one.
The three capabilities
ceph fs authorize cephfs client.app / rw
That helper generates the full set. Expanded, it is:
caps: [mds] allow rw fsname=cephfs
caps: [mon] allow r fsname=cephfs
caps: [osd] allow rw tag cephfs data=cephfs
| Capability | Purpose |
|---|---|
mds | metadata operations — the namespace itself |
mon | fetch the FS map and OSD map |
osd | read and write file data in the data pools |
The tag cephfs data=<fsname> form is important: it grants access to the
filesystem’s data pools by tag rather than by name, so adding a data pool
later does not require a capability change.
Path restriction
This is the mechanism that makes multi-tenant CephFS work:
ceph fs authorize cephfs client.tenant-a /tenants/a rw
ceph fs authorize cephfs client.tenant-b /tenants/b rw
Each client can only traverse and modify within its subtree. The MDS enforces this on every metadata operation — a client cannot escape its path by constructing its own requests, because the check is server-side.
ceph auth get client.tenant-a
# caps: [mds] allow rw fsname=cephfs path=/tenants/a
Read-only and multiple paths
# read-only access to a shared area plus read-write to its own
ceph fs authorize cephfs client.tenant-a /shared r /tenants/a rw
root_squash
ceph fs authorize cephfs client.untrusted /tenants/c rw root_squash
root_squash maps UID 0 on the client to an unprivileged identity,
exactly as NFS does. Without it, root on the client host is root on the
filesystem subtree, which for a client host you do not fully control is a
significant grant.
Verifying enforcement
# mount as the restricted client, then attempt to escape
# MON is a monitor address from `ceph mon dump`; substitute your own:
MON=192.0.2.11:6789
mount -t ceph "$MON:/" /mnt/test -o name=tenant-a,secret=...
# should fail or show only the permitted subtree
ls /mnt/test/tenants/b # must be denied
Test the denial. A path restriction that has not been tested from the client side is an assumption.
Quiz
Knowledge check · 4 questions
Q1. A CephFS client is given `mds allow rw` with no path restriction, but mounts only `mon:/tenants/a`. What can it access?
Q2. The osd capability generated by `ceph fs authorize` uses a tag so that data pools added to the filesystem later remain accessible.
Q3. Set up multi-tenant CephFS on client hosts you do not control.
Three research groups need shared CephFS access. Each group administers its own client hosts, including root access. They must not see each other's data, and there is a shared reference dataset all three should read but not modify.
Q4. What does root_squash change for a CephFS client, and when does it matter most?
Passing score: 75%. Answers are checked in this browser.
Production discipline
Use ceph fs authorize rather than hand-writing CephFS
capabilities — the tag-based OSD grant and the correct MDS clause are easy
to get subtly wrong. Verify path restrictions by attempting to escape them
from a real client, and apply root_squash by default on any host outside
your administrative control.
Cross-course references
- Kubernetes: subPath volume mounts are a convenience, not a boundary, exactly as here
- Linux: NFS export path restrictions and root_squash are the direct analogues