docs: mark R5 done, reframe R1 in plan (owner/grant-native read gate)
This commit is contained in:
@@ -148,7 +148,7 @@
|
|||||||
|
|
||||||
**Gaps / recommendations (honest ceiling — ranked):**
|
**Gaps / recommendations (honest ceiling — ranked):**
|
||||||
|
|
||||||
- **R1 — Reuse, don't fork, the ACL logic.** The FUSE mount (`cubefs::nullspace::Acl::permits`) already implements owner/group/other permission checks, but the daemon does NOT share it — `admit_mutate` today only checks owner-match + grant, not the `mode` bits. Recommend lifting `Acl`/`permits` into a shared `cubeacl` crate (or `cubesys::acl`) so daemon + FUSE enforce identical rules. Right now a record with mode `0600` is still readable by any other owner unless a grant exists — that's a read-permission gap.
|
- **R1 — Reuse, don't fork, the ACL logic.** The FUSE mount (`cubefs::nullspace::Acl::permits`) implements owner/group/other checks, but its identity is POSIX **uid/gid**, incompatible with the daemon's name-based `HELLO` identity (`Owner{local,remote}` matching `CubeHeader.owner_local_user`). A literal `Acl` lift would be a square peg. **Resolution (2026-08-11):** the daemon's read gate (R5) is implemented *owner/grant-native* — same `admit_*` model as writes — rather than importing `Acl`. This closes the actual read-privacy gap without forking the uid/gid concept. If POSIX `mode`-bit semantics are ever wanted in the daemon, the right move is to add `mode` to `CubeHeader` and a name-keyed `permits()` in `grants.rs`, not to lift FUSE `Acl`. Status: R5 DONE (commit 0e579a0); R1 reframed as "reuse the enforcement *concept*, not the struct."
|
||||||
|
|
||||||
- **R2 — Grant table is single-record-per-tenant (O(n) scan).** `read_bucket` deserializes the whole JSON array on every `grant`/`revoke`/`grant_allows` call. Fine for an agent memory store (tens of grants), but recommend a prefix-indexed bucket (one coord per `grantee` or per scope) before scaling past ~1k grants/tenant.
|
- **R2 — Grant table is single-record-per-tenant (O(n) scan).** `read_bucket` deserializes the whole JSON array on every `grant`/`revoke`/`grant_allows` call. Fine for an agent memory store (tens of grants), but recommend a prefix-indexed bucket (one coord per `grantee` or per scope) before scaling past ~1k grants/tenant.
|
||||||
|
|
||||||
@@ -156,7 +156,7 @@
|
|||||||
|
|
||||||
- **R4 — Identity is asserted, not authenticated.** `HELLO` carries a self-asserted `(tenant, owner)` with no signature/challenge. For a single-owner box on a private network (the user's model) this is acceptable; if the box is ever exposed beyond loopback/LAN, add a mutual-auth step (e.g. a pre-shared key or the existing cubecrypt header-flag encrypted handshake) before stamping identity. The `cubecrypt` crate already has `HEADER_FLAG_ENCRYPTED` at bit 12 — wire it into the HELLO frame.
|
- **R4 — Identity is asserted, not authenticated.** `HELLO` carries a self-asserted `(tenant, owner)` with no signature/challenge. For a single-owner box on a private network (the user's model) this is acceptable; if the box is ever exposed beyond loopback/LAN, add a mutual-auth step (e.g. a pre-shared key or the existing cubecrypt header-flag encrypted handshake) before stamping identity. The `cubecrypt` crate already has `HEADER_FLAG_ENCRYPTED` at bit 12 — wire it into the HELLO frame.
|
||||||
|
|
||||||
- **R5 — Read-gating not enforced.** `admit_mutate` only fires on writes. Reads (`run`/`get`) currently ignore grants/owner. If read-privacy matters (it does for a memory store), add an `admit_read` mirror that checks owner/grant-read before returning a record body.
|
- **R5 — Read-gating now enforced.** `admit_read(coord)` mirrors `admit_mutate` (owner → read-grant → deny; unowned world-readable), wired into `run` (read+execute) and `stat` (metadata read), gated by `enforce_owner` exactly like writes. Tests: `read_gate_blocks_non_owner_and_allows_read_grant`, `read_gate_requires_identity_under_enforce`. DONE 2026-08-11 (commit 0e579a0). Note `ls` lists a directory via `cubefs::CubeFs::readdir` and is NOT per-entry gated yet — acceptable since `ls` reveals only names within a tenant the caller already reached; flag if directory-level privacy is needed.
|
||||||
|
|
||||||
- **R6 — Audit log.** Every grant/revoke/write is in the WAL but not attributable to *who* at the app layer. Add a `grant_audit` null-space record (append-only) listing `(seq, granter, grantee, perms, scope, ts)` so delegation is auditable — important the moment more than one human/agent touches a tenant.
|
- **R6 — Audit log.** Every grant/revoke/write is in the WAL but not attributable to *who* at the app layer. Add a `grant_audit` null-space record (append-only) listing `(seq, granter, grantee, perms, scope, ts)` so delegation is auditable — important the moment more than one human/agent touches a tenant.
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user