Attribute-Based Access Control
Attribute-Based Access Control
Available to Enterprise Plan customers only.
Overview
ABAC scopes a single API key to a subset of the actions and data available in a project. Project-level isolation separates one project from another. ABAC adds a second level of control inside a project, so that different keys in the same project may have different permissions.
Zep uses two complementary access systems:
- RBAC governs human access to the web application through account roles and member permissions.
- ABAC governs API key access to project data. It evaluates each request against the policies attached to the calling key.
ABAC supports two common use cases:
- Least-privilege access for multi-agent systems. Each agent authenticates with its own API key, and each key is scoped to only the data and operations that agent requires.
- Data isolation for multi-tenant deployments. A single project may store data for many tenants on a shared graph. Each key is restricted to one tenant’s data through the metadata attached at ingestion.
A key with no ABAC policies has full read and write access to project data. ABAC is opt-in per key.
How a request is evaluated
ABAC evaluates a request in two layers, in order:
- Action layer. Determines whether the request action is permitted. The outcome applies to the whole request: it proceeds, or it returns
403. - Attribute layer. For a permitted request that returns data, determines which objects appear in the response. It filters search, list, and read results by the source metadata of each object. It never overrides an action-level denial; it only narrows what a permitted read returns.
Three controls determine the result:
- Role — the key’s base posture, either
default_allowordefault_deny. - Policy sets — reusable collections of allow and deny rules attached to the key.
- Mode — set on both the key and each policy set, one of
off,report_only, orenforce.
API key roles
Every API key has a role that sets its starting permissions before any policy is evaluated. You choose the role when you create the API key in the Zep web app.
A default_allow key with no policies has full data access, which preserves the behavior of keys created before ABAC. A default_deny key authenticates and reaches the API, but every data operation returns 403 until a policy grants access.
Use default_deny for keys issued to external integrations, partners, or limited-scope agents, where each permitted action should be enumerated explicitly.
Policy sets and modes
A policy set is a named, versioned collection of rules. One set may attach to many keys, and one key may have many sets attached. A policy set is written as YAML:
Each rule has an id, an effect of allow or deny, a non-empty list of actions, and an optional attributes map for source-based rules.
Mode exists at two levels. The key’s abac_mode is the master switch, and each policy set has its own mode. A set is evaluated only when the key is not off and the set is not off.
When several rules match, denial takes precedence, otherwise a matching allow rule produces an allow, otherwise the result is neutral and the role base decides. What a matching deny produces depends on the rule: a deny without attributes is an action-level denial and the whole request returns 403, while a deny with attributes excludes only the matching objects from an otherwise-permitted read — search and list results drop them, and single-object reads return 404.
Action-level policies
Action-level policies gate actions. An action is the dotted name of one SDK method or API route, such as thread.get, graph.search, thread.add_messages, or user.delete.
The readonly macro
readonly is a macro that expands to every action that does not mutate project data. It is computed at evaluation time, so new read-only endpoints are covered automatically. Write actions are always listed explicitly.
This table is illustrative, not an exhaustive list of actions.
Example: a read-only key
A key that may read project data but write nothing. The recommended pattern is a default_deny key that is granted reads:
Attached to a default_deny key in enforce mode, read requests succeed and write requests return 403.
Example: read access plus one write
Allow rules combine, so a literal write grant may be added alongside the macro:
Example: blocking specific actions
Starting from a default_allow key, a deny rule blocks destructive actions regardless of other rules, because denial takes precedence:
Source-based policies
Action-level policies decide whether a read runs. Source-based policies decide which objects that read returns. They are the mechanism behind multi-tenant data isolation on a shared graph.
Tagging data at ingestion
Every object derived from ingestion carries effective metadata: the combined metadata of all the episodes that contributed to it. To make data eligible for source-based policies, attach metadata when you add it to the graph; see Adding business data for how. Metadata accepts up to 10 keys, with scalar values or arrays of scalars.
Every node, edge, community, and summary derived from those episodes inherits the metadata in its effective metadata. See Episode metadata projection for how metadata propagates to derived objects.
Matching is exact set equality
A source-based rule adds an attributes map. Each key maps to a non-empty list of required values. An object satisfies a constraint on a key when its effective value set for that key is exactly equal to the required set, neither a subset nor a superset.
The superset case is the important one. Effective metadata is the union over every contributing source, so an extra value means a source the grant does not name helped produce the object. Equality fails closed in that case to avoid returning data from an uncovered source.
When a constraint names several keys, they combine with AND. An object is admitted only when its effective value set matches exactly for every named key.
Example: scope a key to one tenant
A key that may search the graph but should only return objects sourced entirely from tenant acme:
The search runs, and the result set contains only objects whose effective tenant is exactly {acme}.
Example: hide objects with a deny rule
Attributes also work on deny rules, with the opposite effect. On a key that may already read the data, a deny rule with attributes hides the objects whose effective metadata matches. Denial takes precedence, so matching objects are removed even when an allow rule would otherwise return them.
Allow rules combine disjunctively. An unconstrained allow for the same action, such as a bare readonly grant, makes every object eligible and nullifies a sibling source constraint. To enforce a positive source restriction, do not also grant an unconstrained allow for that action.
What a caller sees
Filtering happens during the read, so pagination and limits operate over the visible set.
Managing policies
ABAC management is restricted to account administrators; project API keys are the subjects of ABAC and may not manage it. Policy sets are created, attached, and detached with the zepctl CLI. The dashboard is used to set an API key’s role and to review ABAC decisions.
Dashboard
When ABAC is enabled for an account, the dashboard exposes the key role at creation, an editable role with a security-change warning, a computed capabilities badge, and the ABAC decision for each request on the API log view.
zepctl
zepctl authenticates through the browser and manages policy sets and keys:
Rolling out with report-only
report_only mode evaluates policies and records the result without changing the response. Use it to measure the impact of a policy before enforcing it.
Author and attach the policy
Write the policy set in enforce mode and attach it to the key, but set the key’s abac_mode to report_only. No request is blocked or filtered yet.
Let traffic flow
Each request records the decision it would have reached under enforcement, including the action, the outcome, and whether the result differs from the key’s current behavior.
Auditing
ABAC produces two kinds of records:
- Management operations, such as creating, updating, or deleting a policy set, attaching or detaching a set, and changing a key’s role or mode, are recorded as audit events.
- Runtime decisions are recorded on each API log record, with the evaluated action, the outcome, and the mode.
The API log view filters by ABAC outcome and mode, which supports both the report-only rollout above and ongoing review of enforced policies.