Memory Engine uses tree-grant RBAC (Role-Based Access Control) enforced at the database level with PostgreSQL Row-Level Security.
A user is a principal within an engine. Users can:
- Own memories
- Receive grants to access tree paths
- Authenticate via API keys
- Belong to roles
Create a user:
me user create aliceUsers with the --superuser flag bypass all access checks. Users with --createrole can create other users and roles.
Users created with --no-login are roles -- they cannot authenticate directly but can be granted access that members inherit.
Roles group users together. When a grant is given to a role, all members of that role inherit the access.
# Create a role
me role create engineering
# Add members
me role add-member engineering alice
me role add-member engineering bob
# Grant access to the role (all members inherit it)
me grant create engineering work.projects read create updateRoles are implemented as users with canLogin: false. This means grants work the same way for users and roles.
Grants control what actions a user (or role) can perform on a tree path. A grant specifies:
- user -- who receives the access
- path -- which tree path (and all descendants)
- actions -- what they can do:
read,create,update,delete
# Grant read and create access to a tree branch
me grant create alice work.projects read create
# Grant full access
me grant create bob work read create update delete
# Check access
me grant check alice work.projects.api readGrants are hierarchical -- a grant on work covers work.projects, work.projects.api, etc.
| Action | Description |
|---|---|
read |
Search and retrieve memories |
create |
Create new memories |
update |
Update existing memories |
delete |
Delete memories |
Grant management and ownership are controlled separately: grants with --with-grant-option let a grantee re-grant their access, and ownership (me owner set) gives a user full admin access to a tree path. Superuser bootstrap is handled via the superuser flag on the user row, not via a grant action.
When creating a grant with --with-grant-option, the grantee can re-grant that same access to others:
me grant create alice work.projects read create --with-grant-optionAlice can now grant read and create on work.projects to other users.
Each tree path can have at most one owner. The owner has implicit admin access to that path and all descendants.
# Set owner
me owner set work.projects.api alice
# Check owner
me owner get work.projects.api
# List all ownership records
me owner listOwnership is distinct from grants:
- Grants are explicit, cumulative, and can be given to multiple users.
- Ownership is unique per path and provides automatic admin access.
Access control is enforced by PostgreSQL Row-Level Security (RLS) policies on the me.memory table. When a user authenticates with an API key, the database session is configured with their identity. Every query automatically checks whether the user has the required grant for the memory's tree path.
This means access control cannot be bypassed by application bugs -- it's enforced by the database itself.
:::warning[The invisible wall]
When RLS denies access, you get empty results, not errors. A search returns fewer results silently. A memory.get returns "not found" even if the memory exists. This is by design (PostgreSQL RLS behavior), but it can be confusing when debugging.
If you're seeing missing results:
- Check the user's access with
me grant check <user> <path> read - Verify the memory exists by checking as a superuser
- Check that the user has grants covering the memory's tree path
- Remember that grants are hierarchical -- a grant on
workcoverswork.projects.*:::
# Create users
me user create alice
me user create bob
me user create carol
# Create a shared role
me role create team
me role add-member team alice
me role add-member team bob
me role add-member team carol
# Grant the team read access to everything
me grant create team "" read
# Grant write access to specific branches
me grant create alice work.frontend read create update
me grant create bob work.backend read create update
me grant create carol work.infra read create update delete