> ## Documentation Index
> Fetch the complete documentation index at: https://docs.memoryo.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Authentication

> How tenant API keys, agent API keys, and UUI tokens work in MemoryOS.

MemoryOS has two auth models:

* **Tenant API key** — for `/v1/memories/*` and all workspace APIs
* **Cross-agent dual auth** — for `/v1/universal/*`, which requires both an agent key and a user UUI token

## Tenant API key

```http theme={null}
Authorization: ApiKey mem_...
```

All current keys use the `mem_` prefix. The header format is exact — these all return `AUTH_001`:

```http theme={null}
Authorization: mem_...
Authorization: Bearer mem_...
X-API-Key: mem_...
```

Keep your API key server-side. Never send it to the browser.

## Cross-agent auth

```http theme={null}
Authorization: ApiKey agent_sk_...
X-MemoryOS-UUI: uui_...
```

Both headers are required for every universal memory call. `agent_sk_...` identifies the agent. `uui_...` identifies which Memory Passport user has granted access.

Get your `agent_sk_...` key by registering a global agent:

```http theme={null}
POST /v1/agents/global
Authorization: ApiKey mem_...
```

The response includes `raw_agent_api_key` once. Store it in your backend secret manager — it's never shown again.

If either header is missing or invalid, the API returns `403 UAT_001`. A read-only grant attempting a write returns `403 UAT_002`.

## Identity model

Every tenant-scoped request combines **tenant identity** (from the API key) with **end-user identity** (from `external_user_id` in the request body):

```json theme={null}
{ "external_user_id": "customer-123" }
```

One tenant safely stores memories for many users. Memories are isolated by `(tenant_id, external_user_id)`.

For cross-agent calls, identity is: **agent** (`agent_sk_...`) + **user** (`uui_...`) + **scope** (active `PermissionGrant` categories). The grant must be active and the requested category must be in `categories_allowed`.

Human users manage their Memory Passport through the consent app using email + OTP — not raw `uui_...` tokens.

## Common mistakes

| Mistake                                     | Error                 | Fix                                              |
| ------------------------------------------- | --------------------- | ------------------------------------------------ |
| Raw key without scheme                      | `AUTH_001`            | `Authorization: ApiKey mem_...`                  |
| `Bearer mem_...`                            | `AUTH_001`            | `Authorization: ApiKey mem_...`                  |
| Only one credential on `/v1/universal/*`    | `UAT_001`             | Send both `agent_sk_...` and `uui_...`           |
| Revoked or expired grant                    | Empty retrieve result | Re-run the consent flow                          |
| Missing `external_user_id` on tenant routes | `REQ_422`             | Always include it in write and retrieve requests |
| Key stored in browser code                  | Secret leak           | Keep MemoryOS keys server-side only              |

## Key permissions

| Permission | Use                                         |
| ---------- | ------------------------------------------- |
| `read`     | Retrieve memories and read list/export data |
| `write`    | Add memories and create extraction jobs     |
| `delete`   | Delete memories or run GDPR cleanup         |
| `admin`    | Broad operational control                   |

## Security checklist

* Load keys from environment variables
* Use separate keys for dev, staging, and production
* Rotate immediately if a key is exposed
* Never commit keys to source control
* Never log `uui_...` tokens in analytics or error payloads
* Treat `agent_sk_...` like any other backend secret

## Quick example

<CodeGroup>
  ```python Python theme={null}
  import os
  from memoryos import Memory

  client = Memory(api_key=os.environ["MEMORYOS_API_KEY"])
  ```

  ```ts TypeScript theme={null}
  import { MemoryOS } from "@memoryos/sdk";

  const client = new MemoryOS(process.env.MEMORYOS_API_KEY!);
  ```
</CodeGroup>

## Related pages

* [Memory Passport](/concepts/memory-passport)
* [Cross-agent memory sharing](/guides/cross-agent-sharing)
* [Python SDK reference](/sdk/python)
