Skip to content

agent: all guests share one memory scope, so any guest can read another's saved memories #85

Description

@zuckerberg-db

Found by isaac review of genie-agent vs main, and verified against the source.

What happens

resolve_scope partitions durable memory by the caller's own identity:

# agent/agent_server/utils_memory.py:41
if headers.get("x-forwarded-access-token"):
    return get_user_workspace_client().current_user.me().id

Every guest authenticates as the same service principal. Phase 6b creates exactly one
firefly-guest-sp and reuses it if present (BOOTSTRAP.md:697), and the Vercel proxy mints a
workspace bearer for that SP. So me().id is identical for all guests, and they all resolve to
one memory partition.

Any guest can therefore read, overwrite, or delete memories saved by any other guest. For a
demo whose whole point is a shareable guest link, that is a cross-tenant data path.

Why the E2E suite never caught it

The regression harness drives exactly one guest per run, so it cannot observe cross-guest
leakage no matter how many times it passes. This was invisible to it by construction, not by
accident — nine consecutive green runs say nothing about this defect.

Suggested fix

Derive the scope from the per-guest identity rather than the shared SP: the guest user id or
email that the proxy already knows (proxy-injected header, or custom_inputs), so each guest
gets an isolated partition. Whatever is chosen, it must not be a value every guest shares.

Worth adding a harness case that runs two distinct guests and asserts neither sees the other's
memories — otherwise a future regression here is equally invisible.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions