Skip to content

Latest commit

 

History

History
142 lines (96 loc) · 4.41 KB

File metadata and controls

142 lines (96 loc) · 4.41 KB

Access Control

Memory Engine uses tree-grant RBAC (Role-Based Access Control) enforced at the database level with PostgreSQL Row-Level Security.

Users

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 alice

Users 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

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 update

Roles are implemented as users with canLogin: false. This means grants work the same way for users and roles.

Grants

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 read

Grants are hierarchical -- a grant on work covers work.projects, work.projects.api, etc.

Actions

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.

Grant option

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-option

Alice can now grant read and create on work.projects to other users.

Ownership

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 list

Ownership 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.

How it works

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:

  1. Check the user's access with me grant check <user> <path> read
  2. Verify the memory exists by checking as a superuser
  3. Check that the user has grants covering the memory's tree path
  4. Remember that grants are hierarchical -- a grant on work covers work.projects.* :::

Example: team setup

# 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