# How to Configure ai-memory for Multi-User Shared Server Deployments with Authentication

> Configure ai-memory for multi-user shared servers. Enable tiered authentication via config.toml and manage users with the CLI for secure deployments.

- Repository: [Fabio Akita/ai-memory](https://github.com/akitaonrails/ai-memory)
- Tags: how-to-guide
- Published: 2026-08-20

---

**Enable the `[auth]` section in [`config.toml`](https://github.com/akitaonrails/ai-memory/blob/main/config.toml) to activate ai-memory's tiered authentication system, then create database users via the CLI while reserving the root bearer token for administrative operations.**

ai-memory transforms from a single-tenant wiki into a secure, multi-operator system by implementing a tiered authentication model. Configuring ai-memory for multi-user shared server deployments with authentication requires adding an `[auth]` block to your server configuration and managing user tokens through the command-line interface. This setup ensures every write is attributed to a specific operator while restricting administrative endpoints to root-level access.

## Understanding the Authentication Tier System

ai-memory implements a "rung" system that determines request privileges and identity attribution. The middleware in [`crates/ai-memory-mcp/src/auth.rs`](https://github.com/akitaonrails/ai-memory/blob/main/crates/ai-memory-mcp/src/auth.rs) evaluates every request and inserts an `AuthLevel` based on the presented credentials.

The five authentication tiers operate as follows:

- **Rung 0 — Anonymous**: No `bearer_token` configured. Requests are allowed but carry no identity, suitable for single-user deployments.
- **Rung 1 — Root**: Bearer matches `[auth].bearer_token`. Grants full administrative rights; writes may be attributed to `root_username` if configured.
- **Rung 1b — Proxy-asserted User**: Bearer matches `[auth].actor_proxy_bearer_token`. Identity is extracted from `X-Memory-Actor-*` headers, enabling SSO proxy integration.
- **Rung 2 — DB User**: Bearer hashes to a row in the `users` table using the `token_pepper`. Grants normal read/write rights, but admin endpoints return `403 Forbidden`.
- **Rung 3 — Rejected**: Bearer present but matches none of the above. Returns `401 Unauthorized`.

## Step 1: Configure the `[auth]` Section

Add the `[auth]` block to your [`config.toml`](https://github.com/akitaonrails/ai-memory/blob/main/config.toml). According to the template in [`crates/ai-memory-cli/templates/config.default.toml`](https://github.com/akitaonrails/ai-memory/blob/main/crates/ai-memory-cli/templates/config.default.toml), this section must be the last in the configuration file.

```toml
[auth]
bearer_token = "c4a5e1…root-token"
actor_proxy_bearer_token = "d9f3b2…proxy-token"
token_pepper = "e7f2a1c3d4b5…"
secure_cookie = true
root_issuer = "https://sso.example"
root_subject = "root-subject-123"

```

**Critical configuration fields:**

- **`bearer_token`**: The root administrative token. Store this securely; it bypasses database authentication.
- **`token_pepper`**: A random string generated by `ai-memory init` that salts user token hashes. **Never change this** after creating users, or all existing database tokens will become invalid.
- **`actor_proxy_bearer_token`**: Optional token for reverse proxies performing SSO termination.
- **`secure_cookie`**: Enable only when the `/web` endpoint sits behind a TLS-terminating reverse proxy.

## Step 2: Initialize the Server and Create Users

Run `ai-memory init` to generate the `token_pepper` and initialize the database schema.

Create the first user (the root operator) using the root bearer token:

```bash
AI_MEMORY_AUTH_TOKEN=c4a5e1…root-token \
ai-memory user add --username alice --email alice@example.com --name "Alice Smith"

```

The CLI prints a one-time token that never persists to disk. This plaintext token must be distributed securely to the user. The server stores only the SHA‑256 hash of the concatenation `token + ":" + token_pepper` in the `users` table, as implemented in [`crates/ai-memory-store/src/users.rs`](https://github.com/akitaonrails/ai-memory/blob/main/crates/ai-memory-store/src/users.rs).

To create additional users, reuse the root token with the same command structure. Each user receives unique credentials tied to their `author_id` in the database.

## Step 3: Configure Client Authentication

Users authenticate by exporting their token to the environment:

```bash
export AI_MEMORY_AUTH_TOKEN="XyZ9…user-token"
ai-memory page write --path notes/todo.md --content "Buy milk"

```

For automated hooks or agents, specify the token inline:

```bash
AI_MEMORY_AUTH_TOKEN=$(cat ~/.config/ai-memory/bob.token) \
ai-memory install-hooks --apply --agent claude-code --as-user bob

```

### Proxy-Asserted Identity for SSO

When terminating authentication at a reverse proxy (such as nginx or Traefik with OIDC), configure the proxy to send the `actor_proxy_bearer_token` and replace any incoming `X-Memory-Actor-*` headers with values from the identity provider:

```nginx

# Example nginx configuration

proxy_set_header Authorization "Bearer d9f3b2…proxy-token";
proxy_set_header X-Memory-Actor-Id "user-uuid";
proxy_set_header X-Memory-Actor-Username "bob";

```

**Security warning**: The proxy must sanitize incoming headers. If a client sends `X-Memory-Actor-*` headers and the proxy appends rather than replaces them, ai-memory rejects the request (see the "Trusted proxy identity" section in [`docs/users.md`](https://github.com/akitaonrails/ai-memory/blob/main/docs/users.md)).

## Security Considerations for Shared Deployments

### Root-Only Administrative Endpoints

Once a database user exists, all `/admin/*` routes require the root `bearer_token`. Database users (Rung 2) attempting to access these endpoints receive `403 Forbidden`. This ensures that user management, token rotation, and system configuration remain restricted to the root operator.

### Cookie and Header Security

Enable `secure_cookie = true` only when the server operates behind HTTPS. Without TLS termination, browsers refuse to transmit the authentication cookie, breaking web UI sessions.

### Token Storage Architecture

The system uses a peppered hash mechanism to protect stored credentials. As defined in [`crates/ai-memory-store/src/users.rs`](https://github.com/akitaonrails/ai-memory/blob/main/crates/ai-memory-store/src/users.rs), the stored value is `SHA-256(token || ":" || token_pepper)`. This design ensures that even if the database is compromised, tokens remain unusable without the `token_pepper` stored exclusively in [`config.toml`](https://github.com/akitaonrails/ai-memory/blob/main/config.toml).

## Summary

- Add the `[auth]` block to [`config.toml`](https://github.com/akitaonrails/ai-memory/blob/main/config.toml) (last section) with `bearer_token`, `token_pepper`, and optional proxy settings.
- Initialize the server with `ai-memory init` to generate the required pepper value.
- Create users via `ai-memory user add` using the `AI_MEMORY_AUTH_TOKEN` environment variable set to the root token.
- Distribute user tokens securely; the server stores only hashed values combined with the pepper.
- Configure reverse proxies to replace `X-Memory-Actor-*` headers when using SSO integration.
- Reserve root token usage for administrative commands and `/admin/*` endpoints.

## Frequently Asked Questions

### What happens if I change the `token_pepper` after creating users?

All existing database user tokens will become invalid. The `token_pepper` in [`crates/ai-memory-store/src/users.rs`](https://github.com/akitaonrails/ai-memory/blob/main/crates/ai-memory-store/src/users.rs) acts as a site-wide salt; changing it breaks the hash verification for stored tokens. You must regenerate and redistribute tokens to all users if the pepper is rotated.

### Can I use ai-memory without any authentication?

Yes. Omitting the `[auth]` section entirely places the server in **Rung 0 — Anonymous** mode. The wiki functions as a single-tenant application without user attribution. This mode is suitable for personal local deployments but should never be used for shared server environments.

### How do I revoke a user's access?

Administrators can expire a user's token using the root bearer token:

```bash
AI_MEMORY_AUTH_TOKEN=<root-token> ai-memory user expire --username bob

```

This command invalidates the current token in the database. Because the system validates tokens against the peppered hash in [`crates/ai-memory-store/src/users.rs`](https://github.com/akitaonrails/ai-memory/blob/main/crates/ai-memory-store/src/users.rs), simply removing the token from your client configuration is insufficient for revocation; you must use the server-side expire command.

### Where does ai-memory check the proxy headers?

The authentication middleware in [`crates/ai-memory-mcp/src/auth.rs`](https://github.com/akitaonrails/ai-memory/blob/main/crates/ai-memory-mcp/src/auth.rs) examines the `Authorization` header for the `actor_proxy_bearer_token`, then extracts identity from `X-Memory-Actor-Id`, `X-Memory-Actor-Username`, and related headers. If the proxy token matches but the headers are malformed or conflicting, the request resolves to `AuthLevel::Rejected` with a 401 response.