# 다중 테넌시 및 격리 Synapse는 다중 테넌트입니다: 여러 사용자, 각각 여러 마인드를 가지며, 서로 완전히 격리되어 있습니다. 이 페이지에서는 격리 모델을 설명합니다. ## 테넌트 계층 구조 ``` Synapse Instance │ ├── User Account 1 (email: alice@example.com) │ ├── Mind A (Mind Key mk_aaa...) │ │ ├── Memories (only accessible via mk_aaa...) │ │ ├── Tasks │ │ └── Chat │ └── Mind B (Mind Key mk_bbb...) │ └── ... (isolated from Mind A) │ ├── User Account 2 (email: bob@example.com) │ └── Mind C (Mind Key mk_ccc...) │ └── ... (isolated from Alice's minds) │ └── ... (more users) ``` ## 격리 수준 ### 수준 1: 사용자 격리 각 사용자 계정은 격리되어 있습니다. Alice는 다음을 할 수 없습니다: - Bob의 마인드 보기 - Bob의 메모리 접근 (그녀의 JWT로도) - Bob의 계정 정보 나열 강제 방법: 모든 테이블의 `user_id` 컬럼, JWT에 `user_id` 포함, 모든 쿼리는 `user_id`로 필터링. ### 수준 2: 마인드 격리 사용자 내에서 각 마인드는 격리되어 있습니다. Mind A는 다음을 할 수 없습니다: - Mind B의 메모리 보기 - Mind B의 작업, 채팅, 스크립트 접근 강제 방법: 모든 데이터 테이블의 `mind_id` 컬럼, Mind Key에 `mind_id` 포함, 모든 쿼리는 `mind_id`로 필터링. > [!CRITICAL] > Mind Key 격리는 기본 보안 경계입니다. 유출된 Mind Key는 해당 마인드의 > 데이터에 대한 전체 접근 권한을 부여합니다 — 하지만 해당 마인드에만. ## 인증 토큰 | 토큰 | 범위 | 접근 가능한 것 | |-------|-------|-------------------| | Mind Key | 단일 마인드 | 해당 마인드의 데이터만 | | JWT | 사용자 계정 | 계정 관리 (마인드 생성/나열/삭제) | | Computer Token | 단일 컴퓨터 | 해당 컴퓨터의 명령 | ## 마인드 간 접근 ### 동일 사용자 내 사용자는 JWT를 통해 모든 마인드에 접근할 수 있습니다 (예: `GET /minds`가 모두 나열). 하지만 메모리 데이터를 읽고/쓰려면 특정 Mind Key가 필요합니다. ### 사용자 간 사용자는 서로의 데이터에 접근할 수 없습니다 — Sharing API를 통해 명시적으로 마인드를 공유하지 않는 한: ```bash # Alice shares Mind A with Bob curl -X POST https://synapse.schaefer.zone/sharing \ -H "Authorization: Bearer ALICE_JWT" \ -d '{"mind_id": "m_aaa", "email": "bob@example.com", "role": "read"}' ``` 공유 후, Bob은 자신의 JWT를 통해 Mind A에 접근할 수 있습니다 (`role=read`인 경우 읽기 전용). ## 보안 경계 ``` ┌─────────────────────────────────────────────────┐ │ Synapse Instance │ │ ┌─────────────────────────────────────────┐ │ │ │ User Account Boundary │ │ │ │ ┌──────────────┐ ┌──────────────┐ │ │ │ │ │ Mind Bound. │ │ Mind Bound. │ │ │ │ │ │ (Mind Key) │ │ (Mind Key) │ │ │ │ │ │ │ │ │ │ │ │ │ │ Memories │ │ Memories │ │ │ │ │ │ Tasks │ │ Tasks │ │ │ │ │ │ Chat │ │ Chat │ │ │ │ │ │ Scripts │ │ Scripts │ │ │ │ │ └──────────────┘ └──────────────┘ │ │ │ └─────────────────────────────────────────┘ │ └─────────────────────────────────────────────────┘ ``` ## 일반적인 다중 테넌시 패턴 ### 패턴 1: 단일 사용자, 단일 마인드 개별 LLM 에이전트 사용자에게 가장 일반적입니다. - 1개 사용자 계정 - 1개 마인드 - 1개 Mind Key - 모든 메모리가 하나의 범위에 ### 패턴 2: 단일 사용자, 다중 마인드 여러 컨텍스트 (업무, 개인, 프로젝트)를 가진 사용자용. - 1개 사용자 계정 - N개 마인드 (예: "work", "personal", "project-x") - N개 Mind Key - 각 LLM 세션은 하나의 Mind Key 사용 ### 패턴 3: 팀 공유 마인드 프로젝트에서 협업하는 팀용. - 1명의 사용자가 마인드 생성 (Mind Key 획득) - 생성자가 JWT를 통해 팀원과 공유 - 모든 팀원이 JWT (또는 공유 Mind Key)로 접근 > [!WARNING] > Mind Key 공유는 전체 읽기/쓰기 권한을 부여합니다. 팀 협업의 경우, > Mind Key를 직접 공유하기보다 Sharing API (JWT 기반)를 선호하십시오. ### 패턴 4: SaaS 제공자 Synapse를 메모리 계층으로 내장하는 앱용. - 각 고객 = 1개 사용자 계정 - 각 고객 프로젝트 = 1개 마인드 - 앱이 고객/프로젝트별 Mind Key 저장 - 고객 간 전체 격리 ## 격리 검증 ### 테스트: Mind Key는 다른 마인드에 접근할 수 없음 ```bash # Mind A's key cannot read Mind B's memories curl -H "Authorization: Bearer mk_aaa..." \ "https://synapse.schaefer.zone/memory/search?q=test" # Returns only Mind A's memories curl -H "Authorization: Bearer mk_bbb..." \ "https://synapse.schaefer.zone/memory/search?q=test" # Returns only Mind B's memories (different results) ``` ### 테스트: JWT는 메모리 데이터를 직접 읽을 수 없음 ```bash # JWT can list minds curl -H "Authorization: Bearer YOUR_JWT" \ https://synapse.schaefer.zone/minds # Returns: list of minds # JWT CANNOT read memories (need Mind Key) curl -H "Authorization: Bearer YOUR_JWT" \ https://synapse.schaefer.zone/memory/recall # Returns: 401 Unauthorized ``` ## 모범 사례 > [!TIP] > - **프로젝트/컨텍스트당 하나의 마인드 사용** — 격리가 도움입니다 > - **Mind Key 절대 공유하지 않기** — Sharing API를 대신 사용 > - **노출 시 Mind Key 교체** (마인드 삭제, 새로 생성) > - **공유 마인드 감사** — 정기적으로 `GET /sharing` 검토 > - **human UI에 JWT 사용** — 최종 사용자에게 Mind Key 노출 금지 ## 다음 단계 - [Authentication](/docs/getting-started/authentication) - [Mind Key vs JWT](/docs/getting-started/mind-key-vs-jwt) - [아키텍처](/docs/concepts/architecture)