Skip to main content

Users

Users are the most common type of principal and the primary way people access the system. They authenticate through email and password and can own datasets, be granted permissions on others.
Default user behavior — When no user is specified, Cognee uses a default user with email “default_user@example.com” for development and testing.

User Authentication

Users authenticate through email and password. Changing a password signs out all of that user’s existing sessions. See Session revocation on password change.

User Management

Users can:
  • Own datasets and be granted permissions on others
  • Belong to one or more tenants, acting inside one active tenant at a time
  • Have direct permissions on datasets
  • Inherit permissions from their tenant and roles
The User model defines what gets stored in the SQL database. The users table contains:
  • id: Unique identifier (UUID primary key, references principals.id)
  • email: User’s email address (unique)
  • hashed_password: Encrypted password
  • tenant_id: ID of the user’s active tenant (nullable) — membership is stored separately in the user_tenants table, so this is the one tenant the user is currently acting inside, not the full list
  • parent_user_id: ID of the parent user (UUID, nullable, self-referencing FK to users.id). When an agent or service user creates datasets, the parent user automatically inherits full permissions on those datasets. The parent also holds every permission its agents were granted directly (read, write, delete or share), within the parent’s active tenant — only the agents’ own grants, not their tenants or roles, and not grants held by agents of agents. The parent also reads its agents’ stored configurations over GET /api/v1/configuration/get_user_configuration/. Visibility runs downward only — an agent cannot read its parent’s configurations. Agents are one level deep: a user with a parent_user_id cannot create agents of its own (PermissionDeniedError, HTTP 403). Set to null for regular human users.
  • is_active: Whether the user account is active
  • is_verified: Whether the user’s email is verified
  • is_superuser: Whether the user has superuser privileges
Agents follow their parent when it goes away. Deleting a user (for example through DELETE /api/v1/users/{id}) deletes their agents, including any sub-agents created before agents were limited to one level, together with their API keys and stored configurations, in the same transaction. Datasets an agent owned keep the deleted id as their owner, as a deleted user’s own datasets do; on Postgres, their dataset-database mapping is deleted with the owner. Removing a user from a tenant removes their agents from that tenant too.
  • create_user(email, password, is_superuser=False, is_active=True, is_verified=False, auto_login=False, parent_user_id=None): Creates a new user with specified credentials.
  • parent_user_id (optional): UUID of a parent user. Pass this when creating agent or service users so the parent user automatically receives permissions on any datasets those users create. A parent can only be set this way: the public sign-up body (POST /api/v1/auth/register) has no parent_user_id field, so a self-service sign-up cannot attach itself to a parent. Registration responses still return parent_user_id, which is null for users created that way.
  • is_active, is_verified, and is_superuser: Account-state and privilege flags stored on the user.
  • auto_login: Refreshes the created user record so it is ready for an immediate login flow.
  • tenant_id is stored on the user model, but it is not passed to create_user(...); assign users to tenants through the tenant membership methods instead.
  • Default user behavior: System creates “default_user@example.com” if no user exists.
  • See users for the full Python API reference and examples.
  • DEFAULT_USER_EMAIL: Override default user email (default: “default_user@example.com”)
  • DEFAULT_USER_PASSWORD: Password for the default user (default: unset). Unset means the default user has no password and cannot log in; when set, the API server applies it once at startup to a password-less default user and never changes an existing password. See Default user credentials.
  • ENABLE_BACKEND_ACCESS_CONTROL: Canonical posture switch (default: “true”). true enables multi-tenant mode with per-user/dataset isolated databases and auth required on HTTP endpoints. false switches to single-user mode (shared DB, auth requirement off).
  • REQUIRE_AUTHENTICATION: Optional override for the HTTP auth requirement. When unset, it inherits from ENABLE_BACKEND_ACCESS_CONTROL; when ENABLE_BACKEND_ACCESS_CONTROL=true, auth is always required. See Security & Privacy for the full posture table.
  • FASTAPI_USERS_RESET_PASSWORD_TOKEN_SECRET: Secret for password reset tokens. No default — generated per process when unset, so reset links stop working after a restart. See Security & Privacy.
  • FASTAPI_USERS_VERIFICATION_TOKEN_SECRET: Secret for email verification tokens. No default — generated per process when unset, so verification links stop working after a restart. See Security & Privacy.

User Permissions

Users can receive permissions in four ways:
  1. Direct permissions — Explicitly granted to the user
  2. Tenant permissions — Inherited through tenant membership
  3. Role permissions — Inherited through role memberships
  4. Agent permissions — The direct grants of the agents the user created (users whose parent_user_id points at them)
The system calculates effective permissions by combining all four sources, giving users the union of their direct permissions, their agents’ direct permissions, tenant-level permissions, and role-level permissions. That union is then narrowed to the user’s active tenant, so a grant on a dataset in another tenant does not take effect until the user switches to it.

User Isolation

When ENABLE_BACKEND_ACCESS_CONTROL=true, each user’s data is completely isolated:
  • Database routing is automatic — Databases are configured per request via context variables and with the help of Dataset Database Handlers
  • Filesystem isolation — Each user gets their own database directory
  • No unauthorized access — Users can only access datasets they have explicit permissions for

Superuser Privileges

Users with is_superuser=True have additional privileges:
  • Can write system LLM and vector-database settings (POST /api/v1/settings) — any other authenticated caller receives 403 Forbidden with {"error": "Superuser privileges required to modify settings"}. Reading the settings with GET /api/v1/settings only requires authentication.
  • Can perform administrative operations
Superuser status does not let a user manage a tenant’s members or roles: that takes being the tenant owner or holding the manage_users capability in the tenant. It also does not bypass dataset permissions. Dataset access — including the dataset list the web UI shows — always resolves through explicit grants (direct, tenant, role, or held by an agent the user created), so a superuser sees only datasets they hold read on, like any other user. To give an admin visibility into datasets created by agent or service users, create those users with parent_user_id set to the admin (permissions on new datasets are then inherited automatically), or grant access per dataset — see Permission Snippets. The auto-created default user (default_user@example.com) is a superuser, so single-user and local setups can save settings out of the box. Users created with create_user(...) are not superusers unless you pass is_superuser=True, so integrations and automation that change LLM or vector-DB configuration over HTTP must authenticate as a superuser account.
Production Security — Superuser privileges should be carefully managed in production environments.

Tenants

Learn about organization-level access control

Roles

Understand role-based permissions within tenants