Skip to content

RFC 0010: ACL-based memory partitioning and cross-user access - #30

Open
galiniliev wants to merge 2 commits into
mainfrom
dev/galin/memory-acl
Open

RFC 0010: ACL-based memory partitioning and cross-user access#30
galiniliev wants to merge 2 commits into
mainfrom
dev/galin/memory-acl

Conversation

@galiniliev

@galiniliev galiniliev commented Jul 7, 2026

Copy link
Copy Markdown

Summary

Proposes session-scoped, ACL-enforced memory partitioning for OpenClaw: multiple users can share an agent in group channels without exposing each other's — or the owner's — private memory. When an enterprise IdP (Entra ID, Okta, Google Workspace) is connected, its tenant/user IDs become the canonical ACL principals.

Three documents:

  • rfcs/0010-acl-based-memory-partitioning.md — the RFC proper, including a normative-core vs. follow-ups table, a security posture & risk assessment with ranked residual risks, and a non-normative Appendix A (deferred cross-user grants)
  • rfcs/0010/openclaw-memory-broker-design.md — broker design: schema, evaluation semantics, retrieval pipeline, failure modes, runtime notes on the existing node:sqlite + sqlite-vec stack
  • rfcs/0010/implementation-plan.md — component breakdown (core src/memory-acl/ + optional enterprise plugin), phases, and integration points with existing code

Key design decisions

  • Memory stays markdown files. The directory tree is the partition primitive (memory/users/{id}, channels/{id}, shared/, projections/{id}); SQLite is an index + policy catalog (pointer + hash + scope + ACL + lineage + exposure audit), never the content store.
  • Session-scoped attribution, not per-tool-call identity guessing. The gateway stamps scope at routing time (user for verified DMs, channel for groups, agent for autonomous runs). Steering mid-run never switches principals; shared-DM sessions refuse user-scope mounts.
  • Mount model for multiplayer privacy. Personal stores are never readable from group sessions (structural placement, not row filters). Deliberate sharing paths: tenant shared/, opt-in projections, and a write-only postbox with trust tiering (labeled | review-required | off; enterprise default conservative).
  • Deny-by-default with a normative permission lattice (admin ⇒ derive ⇒ read ⇒ retrieve); allow satisfied by placement or ACL rows; two-phase enforcement — the prefilter never excludes evaluator-allowed items, the postfilter is the security boundary.
  • Identity hardening: adapters fetch raw token material; core validates (JWKS/issuer/audience) and constructs principals behind an operator allowlist. Group snapshots fail closed with a bounded staleness window (fail-open is break-glass, doctor-flagged).
  • Transcripts and compaction are governed: transcripts carry session scope; compaction summaries are broker derive operations with lineage — no unscoped artifacts.
  • Deferred (non-normative): direct cross-user grants (Appendix A) and cross-instance federation (future RFC). Until then there is no cross-user read path at all.

Honest limits (stated in-document)

Phase 0 provides retrieval/tool-layer isolation. Deployments with untrusted channel members and exec enabled require the out-of-process broker tier before claiming adversarial isolation (§2.1, risk 1). Semantic laundering through the context window remains detect-not-prevent (Non-Goals §1).

Review guide

Start with "What Accepting This RFC Means" (top of the Proposal) — accepting this RFC accepts the normative core only; follow-ups are individually revisitable. The Security Posture & Risk Assessment section at the end lists what's enforced, ranked residual risks, and which are accepted vs. addressed vs. open.

Adds RFC 0010 with its supporting broker design and implementation plan:
session-scoped, ACL-enforced memory partitioning so multiple users can
share an agent in group channels without exposing each other's — or the
owner's — private memory.

Core design:
- Memory stays markdown files; the directory tree is the partition
  primitive (users/{id}, channels/{id}, shared/, projections/{id}) and
  SQLite is an index + policy catalog (pointer + hash, scope, ACL,
  lineage, exposure audit), built on the existing node:sqlite +
  sqlite-vec stack
- Session-scoped attribution: principals stamped at routing time (user
  for verified DMs, channel for groups, agent for autonomous runs);
  steering never switches principals; shared-DM sessions refuse user
  mounts
- Mount model: personal stores are never readable from group sessions;
  sharing is deliberate — tenant shared/, opt-in projections, and a
  write-only postbox with trust tiering (labeled | review-required |
  off; enterprise default conservative)
- Deny-by-default evaluation with a normative permission lattice
  (admin => derive => read => retrieve); allow satisfied by placement or
  ACL rows; two-phase enforcement where the prefilter never excludes
  evaluator-allowed items and the postfilter is the security boundary
- Enterprise identity: Entra/Okta/Google principals via verified
  bindings; adapters fetch raw token material, core validates and
  constructs principals behind an operator allowlist; group snapshots
  fail closed with a bounded staleness window
- Transcripts carry session scope; compaction summaries are broker
  derive operations with lineage — no unscoped artifacts
- Cross-user grants sketched but deferred (non-normative Appendix A);
  cross-instance federation out of scope for a future RFC
- Security posture & risk assessment section with ranked residual
  risks; Phase 0 is retrieval/tool-layer isolation, with the
  out-of-process broker tier required for adversarial isolation

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@clawsweeper

clawsweeper Bot commented Jul 7, 2026

Copy link
Copy Markdown

Codex review: needs real behavior proof before merge. Reviewed July 6, 2026, 9:58 PM ET / 01:58 UTC.

Summary
The PR adds RFC 0010 and two sidecar documents for ACL-enforced, session-scoped memory partitioning, identity binding, broker semantics, and an implementation plan.

Reproducibility: not applicable. This PR proposes an RFC and sidecar design documents rather than reporting a runtime bug to reproduce.

Review metrics: 1 noteworthy metric.

  • RFC payload: 3 files added, 2,692 insertions. The PR is a broad security design proposal, so review confidence depends on maintainer discussion rather than ordinary docs checks alone.

Merge readiness
Overall: 🦐 gold shrimp
Proof: 🌊 off-meta tidepool
Patch quality: 🦐 gold shrimp
Result: ready for maintainer review.

Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch.

Rank-up moves:

  • Fill rfc_pr with the full pull request URL.
  • [P2] Add or link the required maintainer-discussion context before asking maintainers to accept the normative core.

Risk before merge

  • [P1] Merging while the RFC remains status: draft would conflict with the repository lifecycle for draft RFCs.
  • [P1] The proposal defines a core memory security boundary, identity binding model, transcript scoping, and broker semantics, so maintainer security/product acceptance is required before it becomes repository policy.
  • [P1] The PR body does not show the required maintainer-discussion thread, so process completion is not visible from the review context.

Maintainer options:

  1. Hold Until RFC Acceptance Is Explicit (recommended)
    Fill rfc_pr, link the maintainer discussion, and merge only after maintainers accept the normative security core and update lifecycle fields.
  2. Intentionally Merge A Draft RFC
    Maintainers could choose to store this draft on main, but that would be an explicit exception to the current README lifecycle.
  3. Pause Or Split The RFC
    If the ACL boundary is too broad for one acceptance decision, pause this PR and ask for narrower RFCs.

Next step before merge

  • [P1] The gating action is maintainer security/RFC acceptance; the rfc_pr metadata fix is mechanical but does not settle the product direction.

Maintainer decision needed

  • Question: Should OpenClaw accept RFC 0010's normative core for ACL-enforced memory partitioning as the intended memory security boundary, or keep it draft pending narrower security/product review?
  • Rationale: The PR is an RFC rather than an implementation patch, and it defines identity, memory access, transcript, and broker boundaries that automation cannot accept on maintainers' behalf.
  • Likely owner: Josh Lehman — Josh has the closest existing RFC history around session, transcript, memory identity, and storage boundary design.
  • Options:
    • Keep Draft For Security Review (recommended): Leave the PR open, fix metadata, attach the required discussion context, and have maintainers explicitly accept or narrow the normative core before merge.
    • Accept The Normative Core: If maintainers agree with the security boundary, update lifecycle fields and merge the RFC as accepted.
    • Split The Proposal: If the scope is too broad, split identity, memory broker, and grant follow-ups into narrower RFCs before acceptance.

Security
Cleared: The diff is RFC text only and does not change code execution, dependencies, workflows, secrets, or package resolution; the security-boundary choice is captured as a maintainer decision.

Review findings

  • [P3] Fill the RFC pull request metadata — rfcs/0010-acl-based-memory-partitioning.md:9
Review details

Best possible solution:

Keep the RFC open as a draft, fill the metadata/linkage, add the maintainer-discussion context, and merge only after maintainers explicitly accept or narrow the normative security core.

Do we have a high-confidence way to reproduce the issue?

Not applicable: this PR proposes an RFC and sidecar design documents rather than reporting a runtime bug to reproduce.

Is this the best way to solve the issue?

Unclear: an RFC is the right surface for this broad design, but the PR still needs lifecycle metadata and explicit maintainer security/product acceptance before merge.

Full review comments:

  • [P3] Fill the RFC pull request metadata — rfcs/0010-acl-based-memory-partitioning.md:9
    README.md says new RFCs should set rfc_pr to the RFC pull request, but this new RFC still leaves it blank. Fill it with the full pull request URL so the merged RFC keeps a durable review link.
    Confidence: 0.94

Overall correctness: patch is correct
Overall confidence: 0.87

AGENTS.md: not found in the target repository.

Codex review notes: model internal, reasoning high; reviewed against a8e0ba2701d6.

Label changes

Label changes:

  • add feature: ✨ showcase: ClawSweeper spotlight: unusually compelling feature idea for maintainer attention. The proposal targets a high-value privacy boundary for shared agents by separating personal, channel, and tenant memory access.

Label justifications:

  • P2: This is a substantial memory privacy and security-boundary RFC, but it is not an urgent runtime regression.
  • merge-risk: 🚨 other: Merging a draft security RFC before lifecycle acceptance would canonize product direction that CI cannot validate.
  • rating: 🦐 gold shrimp: Overall readiness is 🦐 gold shrimp; proof is 🌊 off-meta tidepool and patch quality is 🦐 gold shrimp.
  • feature: ✨ showcase: ClawSweeper spotlight: unusually compelling feature idea for maintainer attention. The proposal targets a high-value privacy boundary for shared agents by separating personal, channel, and tenant memory access.
  • status: 👀 ready for maintainer look: ClawSweeper has no concrete contributor-facing blocker left for this PR. Not applicable: This is an RFC-only design proposal in the RFC repository, so there is no runtime changed behavior for the contributor to prove in a real setup.
Evidence reviewed

What I checked:

  • RFC frontmatter is still missing the PR link: The latest PR head leaves rfc_pr: blank in the new RFC frontmatter even though the repository metadata policy says this should point to the pull request. (rfcs/0010-acl-based-memory-partitioning.md:9, a925820bd766)
  • Repository RFC lifecycle policy: The README says new RFCs should remain unmerged while draft, need a maintainer-discussion thread, and should set rfc_pr to the RFC pull request. (README.md:80, a8e0ba2701d6)
  • RFC process history: git blame ties the current draft lifecycle and rfc_pr rules to kevinlin-openai's RFC process update, so the finding is based on current repository policy rather than a style preference. (README.md:80, e366ea9825a4)
  • PR scope and merge state: GitHub reports this PR as three added RFC files with 2,692 insertions, a clean merge state, and no maintainer reviews yet. (a925820bd766)
  • Current main does not already contain this RFC: Current main has no RFC 0010 files and searching for the central ACL-memory terms found no existing implementation of this RFC in the repository. (a8e0ba2701d6)
  • Related same-repo item is not canonical: The only provided related PR, RFC: Claws #27, is a separate draft Capability Packs RFC rather than the same ACL memory-partitioning work.

Likely related people:

  • kevinlin-openai: Authored the current README and template rules for RFC lifecycle metadata, including draft handling and the rfc_pr expectation. (role: RFC process author; confidence: high; commits: e366ea9825a4, f4fdf38f4717; files: README.md, rfcs/0000-template.md)
  • Josh Lehman: Authored and updated the approved plugin SDK session/transcript storage RFC, which is the closest existing RFC area to this PR's memory, transcript, and identity scope. (role: adjacent memory/session RFC contributor; confidence: medium; commits: a9cf8cc4d427, 86183ca73c4c; files: rfcs/0007-plugin-sdk-session-transcript-storage.md)
  • ragesaq: Authored the context-engine runtime settings RFC, which is adjacent to context assembly and cross-session boundary design. (role: adjacent context-engine RFC contributor; confidence: medium; commits: 951ec46d8675; files: rfcs/0008-context-engine-runtime-settings.md)
  • Dallin Romney: Recently clarified the sidecar layout that this PR uses for its implementation plan and broker design documents. (role: RFC sidecar layout contributor; confidence: medium; commits: 3aa7d727383f; files: README.md, rfcs/0000-template.md)
What the crustacean ranks mean
  • 🦀 challenger crab: rare, exceptional readiness with strong proof, clean implementation, and convincing validation.
  • 🦞 diamond lobster: very strong readiness with only minor maintainer review expected.
  • 🐚 platinum hermit: good normal PR, likely mergeable with ordinary maintainer review.
  • 🦐 gold shrimp: useful signal, but proof or patch confidence is still limited.
  • 🦪 silver shellfish: thin signal; proof, validation, or implementation needs work.
  • 🧂 unranked krab: not merge-ready because proof is missing/unusable or there are serious correctness or safety concerns.
  • 🌊 off-meta tidepool: rating does not apply to this item.

Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics.

How this review workflow works
  • ClawSweeper keeps one durable marker-backed review comment per issue or PR.
  • Re-runs edit this comment so the latest verdict, findings, and automation markers stay together instead of adding duplicate bot comments.
  • A fresh review can be triggered by eligible @clawsweeper re-review comments, exact-item GitHub events, scheduled/background review runs, or manual workflow dispatch.
  • PR/issue authors and users with repository write access can comment @clawsweeper re-review or @clawsweeper re-run on an open PR or issue to request a fresh review only.
  • Maintainers can also comment @clawsweeper review to request a fresh review only.
  • Fresh-review commands do not start repair, autofix, rebase, CI repair, or automerge.
  • Maintainer-only repair and merge flows require explicit commands such as @clawsweeper autofix, @clawsweeper automerge, @clawsweeper fix ci, or @clawsweeper address review.
  • Maintainers can comment @clawsweeper explain to ask for more context, or @clawsweeper stop to stop active automation.
Review history (1 earlier review cycle)
  • reviewed 2026-07-07T01:21:58.717Z sha 2350be0 :: needs real behavior proof before merge. :: [P3] Fill the RFC pull request metadata

@clawsweeper clawsweeper Bot added rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. P2 Normal priority bug or improvement with limited blast radius. merge-risk: 🚨 other 🚨 Merging this PR has meaningful risk outside the owned taxonomy. labels Jul 7, 2026
@clawsweeper clawsweeper Bot mentioned this pull request Jul 7, 2026
The Gateway caller-identity pattern established in openclaw/openclaw#96883
is the seam this RFC's session-scoped attribution builds on.

Co-Authored-By: Claude Opus 4 <noreply@anthropic.com>
@clawsweeper clawsweeper Bot added the feature: ✨ showcase ClawSweeper spotlight: unusually compelling feature idea for maintainer attention. label Jul 7, 2026
@clawsweeper clawsweeper Bot mentioned this pull request Jul 9, 2026
@clawsweeper

clawsweeper Bot commented Jul 18, 2026

Copy link
Copy Markdown

ClawSweeper status: review started.

I am starting a fresh review of this pull request: RFC 0010: ACL-based memory partitioning and cross-user access This is item 1/1 in the current shard. Shard 0/1.

This placeholder means the worker is alive and reading the current context. I will edit this same comment with the actual review when the claws are done clicking.

Crustacean status: shell secured, claws on keyboard, evidence pebbles being sorted.

@giodl73-repo giodl73-repo left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a thoughtful security model: session-scoped attribution, structural mounts, deny-by-default evaluation, transcript lineage, and the explicit exec ceiling are the right concerns. Before accepting the normative core, I think the storage identity and shared-workspace authority need to be made implementable across OpenClaw's supported platforms and deployment topologies.

Findings

  • [P1] Separate canonical principals from filesystem path keys. The RFC defines principals such as entra:{tenant_id}:{object_id} and then places {canonical_user_id} directly under memory/users/. Colons are invalid in Windows path components, and arbitrary IdP/channel identifiers can contain other unsafe or normalization-sensitive characters. Define a stable, versioned filesystem-key encoding (or opaque hash plus catalog mapping), with collision and migration behavior. ACL principal strings should never be interpolated directly into paths.

  • [P1] Define the physical storage and write authority for shared scopes. The proposed {workspace}/memory/{users,channels,shared,projections} tree assumes one workspace can safely contain every user's personal store plus tenant/channel state. Lobster today has per-user OneDrive-backed git workspaces; other deployments may have a shared agent root. The RFC needs an explicit topology contract separating user-owned personal storage, channel/workspace-owned storage, and tenant-admin-governed storage, then describing how the broker mounts views across those roots. In particular, who may write/promote/delete content in shared/? “Hand-editable Markdown” must not turn a user's repo write into an unaudited tenant-wide injection path.

  • [P2] Make projections explicit audience grants, not “all channels I am in.” The current rule dynamically exposes a projected item in every channel where the user is a live member. Joining a new channel can therefore widen an old sharing decision. Prefer a named channel/workspace audience, purpose, expiry, audience preview, and revocation. Live membership should constrain an explicit grant, not create one.

  • [P3] Complete the RFC lifecycle metadata. Keep the document draft until the normative security core is explicitly accepted, populate rfc_pr with this PR URL, and link the maintainer security/product discussion required by the repository process.

For the Lobster/shared-workspace direction, the key architectural question is whether permissions slice broker-mounted stores owned by different authorities, rather than relocating all private and shared bytes beneath one editable workspace root. Resolving that here will make the RFC usable by both local OpenClaw and enterprise hosts without weakening inspectability.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

feature: ✨ showcase ClawSweeper spotlight: unusually compelling feature idea for maintainer attention. merge-risk: 🚨 other 🚨 Merging this PR has meaningful risk outside the owned taxonomy. P2 Normal priority bug or improvement with limited blast radius. rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants