Reference

Authentication and access

Memory Layer defaults to single_user, preserving existing local installs. Set auth.mode = "multi_user" to use Authentik for browser identity and scoped Memory Layer service tokens for CLI, TUI, watchers, relays, and HTTP MCP.

Identity split

ActorAuthenticationSecret location
Browser userAuthentik OIDC Authorization Code + PKCEHttpOnly Memory Layer session cookie
CLI, TUI, watcher, agentMemory Layer mlt_... service tokenProcess environment or secret manager
HTTP MCPMemory Layer service token; cookies ignoredMCP client secret configuration
RelayOriginal caller credential forwarded to primaryNo privilege substitution

Authentik authenticates people. OpenBao is recommended for distributing machine secrets, but Memory Layer does not call OpenBao at runtime.

Roles

Roles are cumulative: reader < writer < operator < admin.

RoleTypical capability
readerQuery, inspect memories, resources, status, and project data.
writerReader access plus capture and workspace activity.
operatorWriter access plus curation, validation, and loop operations.
adminAccess administration and installation-wide controls.

A global role applies to every project. Explicit memberships and Authentik group mappings apply to named projects.

Authentik setup

  1. In Authentik, create an application with an OAuth2/OIDC provider.
  2. Use a confidential client and select a signing key.
  3. Add the strict redirect URI https://memory.example.com/v1/auth/callback.
  4. Include the openid, profile, and email scope mappings. Authentik's default profile scope includes group membership.
  5. Record the application slug, issuer URL, client ID, and client secret.

Authentik documents the current provider workflow in Create an OAuth2 provider and the issuer/scope behavior in OAuth 2.0 provider.

Service configuration

[auth]
mode = "multi_user"
public_base_url = "https://memory.example.com"
session_ttl = "12h"
multi_user_legacy_token_enabled = false

[auth.oidc]
issuer_url = "https://auth.example.com/application/o/memory/"
client_id = "memory-layer"
client_secret_env = "MEMORY_LAYER_OIDC_CLIENT_SECRET"
scopes = ["openid", "profile", "email"]
groups_claim = "groups"

[[auth.group_mappings.rules]]
group = "memory-admins"
role = "admin"
global = true

[[auth.group_mappings.rules]]
group = "memory-writers"
role = "writer"
project = "memory"

Put the client secret in the adjacent environment file:

MEMORY_LAYER_OIDC_CLIENT_SECRET=replace-with-authentik-client-secret

public_base_url must be the browser-visible URL, including the HTTPS scheme. Memory Layer uses it for the callback URI and exact Origin checks.

Service principals

memory auth whoami

memory auth token create \
  --name hermes \
  --project memory \
  --role writer \
  --ttl 30d

export MEMORY_LAYER_CLIENT_TOKEN='mlt_...'
memory auth whoami --json

The raw token is displayed once. Memory Layer stores only its SHA-256 hash. Store it in OpenBao or another secret manager before closing the output.

Grant the same principal another project:

memory auth membership grant \
  --principal <principal-uuid> \
  --project another-project \
  --role reader

Global admins can perform the same work from the web UI's Access tab.

Migration

  1. Configure Authentik and at least one global-admin group while still in single_user mode.
  2. Set the OIDC secret environment variable and restart the service.
  3. Switch to multi_user and verify a browser admin can sign in.
  4. Issue project-scoped service tokens for every non-browser workload.
  5. Disable multi_user_legacy_token_enabled after migration.

Returning to single_user is a config rollback. Do not reverse the auth migration; retaining the rows preserves the audit trail.

Troubleshooting

SymptomMeaningAction
401Credential missing, invalid, expired, or revokedSet MEMORY_LAYER_CLIENT_TOKEN, sign in again, or rotate the token.
403Identity is valid but role/project access is insufficientCheck group mapping or explicit membership.
Login returns 503Authentik discovery or client secret unavailableCheck issuer URL, provider health, and client_secret_env.
Browser write returns 403Origin or CSRF check failedVerify public_base_url, HTTPS proxy headers, and cookies.
MCP rejects browser sessionExpected: HTTP MCP is cookie-blindConfigure a scoped service token in the MCP client.

Existing browser sessions and service tokens keep working during an Authentik outage; only new browser logins depend on provider discovery.

© 2026 Olivier Van Acker (3vilM33pl3). Memory Layer is AGPL-3.0-or-later with commercial licensing available.

On this page