Multi-user support was the reason for half the infrastructure work that came before it — the PostgreSQL migration, RLS policies, role separation, contact registry, user_id scoping. All of it was groundwork for this.

Phase 0 laid the foundation: database schema for users, authentication module, role-based access guards. Phase 1 was the big one — JWT authentication, per-user trust levels, and multi-user routing so requests from different users get isolated sessions and isolated permissions.

Phase 2 was the proof. A two-user isolation end-to-end test that creates two users, sends requests from both, and verifies that neither can see the other’s sessions, episodic records, memory chunks, or provenance chains. If user A’s data appears in user B’s context, the test fails. It passed.

Phase 3 added per-user encrypted credentials. Each user’s API keys and tokens are encrypted at rest with a user-specific key. The system can hold credentials for multiple users without any cross-contamination. Signal tokens, email passwords, calendar credentials — all scoped and encrypted per user.

The trust level isolation was particularly important. User A might be at TL4 (autonomous execution) while user B is at TL0 (full approval required). The system enforces each user’s trust level independently. A new user starts restricted regardless of what existing users are allowed to do.

The RLS policies that seemed like overkill when I built them proved essential here. Every database query is automatically filtered by the authenticated user’s ID. The application code doesn’t even need to remember to filter — the database enforces it.