<!-- canonical: https://docs.axelabs.ai/architecture -->
<!-- source: content/architecture/index.mdx -->

---
title: 플랫폼 아키텍처
description: AXE Labs 멀티테넌트 SaaS 플랫폼의 토폴로지, 도메인, 인증, 격리 모델.
---

# 플랫폼 아키텍처

AXE Labs 의 아키텍처는 **소규모 운영자(1인) 가 다수의 customer 를 일관된 패턴으로 호스팅** 할 수 있도록 설계되었습니다. 모든 결정은 [DECISIONS](/ops/decisions) 에 누적 기록되며, 본 페이지는 그 결과의 정적 요약입니다.

> 약어가 익숙하지 않으면 [용어 사전](/glossary) 먼저 참조. 핵심: **MCP** (Model Context Protocol, AI 가 외부 도구·데이터에 접근하는 표준), **OIDC** (OpenID Connect, 신원 확인), **PKCE** (Proof Key for Code Exchange, OAuth 코드 가로채기 방지).

## 6 가지 설계 원칙

1. **격리는 OS-level — customer 1개 = macmini 1대.** 다중 customer 가 한 머신을 공유하지 않습니다. SPOF (macmini 자체 장애) 는 cold storage 백업으로 흡수.
2. **테넌트 ID = 이메일 도메인 → `customers.yaml` 매핑.** 사용자가 `ai@axellc.com` 으로 로그인하면 `axellc.com → axe` customer, `realchoice.co.kr → realchoice` customer 로 자동 라우팅.
3. **Path-based 1-level subdomain.** `{customer}.axelabs.ai/{service}` 형식. 2-level wildcard SSL 무료 미지원 → path-based 로 회피.
4. **Tailscale 메시 + SSH key.** 운영자 ↔ customer macmini 간 push 기반 deploy. 자체 mTLS X.
5. **Microsoft Entra ID + customer 별 own tenant.** 각 customer 의 직원은 자기 회사 tenant 로 인증.
6. **GitHub source-of-truth + push deploy.** customer macmini 가 pull-polling 하지 않음.

## High-Level Topology

```
┌────────────────────────────────────────────────────────────────────────┐
│                                                                        │
│   직원 노트북 (Windows / macOS)                                          │
│   ├─ Claude Code 네이티브 앱 + Microsoft Entra ID 로그인                  │
│   └─ claude.ai 측에 Custom Connector 1회 등록                            │
│            │                                                            │
│            ↓  (Anthropic backend OAuth flow)                            │
│                                                                        │
│   Microsoft Entra ID (customer tenant)                                 │
│   - axe:        122fb574-...  (axellc.com)                              │
│   - realchoice: &lt;TBD&gt;          (realchoice.co.kr)                       │
│                                                                        │
│            ↓  (Bearer access_token, aud = MCP URL)                      │
│                                                                        │
│   Cloudflare DNS / Cloudflare Tunnel (axelabs-tunnel)                  │
│            │                                                            │
│            ↓  (host.docker.internal:3712)                               │
│                                                                        │
│   ┌──── customer macmini (axe-macmini / realchoice-macmini) ────┐       │
│   │                                                              │       │
│   │  axe-frame-proxy (Caddy, port 3712)  ← blue/green selector   │       │
│   │         │                                                    │       │
│   │         ├──→ frame-mcp-blue  :3710   (active)                │       │
│   │         └──→ frame-mcp-green :3711   (passive)               │       │
│   │                  │                                           │       │
│   │                  ↓                                           │       │
│   │           frame-postgres :3700                                │       │
│   │                                                              │       │
│   │  blueprint :3100   axe-vaultwarden :443/vault                │       │
│   │  stream :8780      magnet :8770                              │       │
│   │                                                              │       │
│   └──────────────────────────────────────────────────────────────┘       │
│                                                                        │
└────────────────────────────────────────────────────────────────────────┘
```

## 인증 흐름 (간략)

```
1. 직원 → claude.ai Custom Connector → URL https://{customer}.axelabs.ai/frame/mcp
2. claude.ai 백엔드 → frame /mcp (no auth) → 401 + WWW-Authenticate
3. claude.ai → /.well-known/oauth-protected-resource → AS = Microsoft Entra
4. claude.ai → Microsoft authorize 엔드포인트 (PKCE S256 + client_secret)
5. 브라우저 → Microsoft 로그인 → consent → code 발급
6. claude.ai → Microsoft /token → access_token (aud = Application ID URI)
7. claude.ai → frame /mcp with Authorization: Bearer &lt;access_token&gt;
8. frame middleware → Microsoft JWKS RS256 검증 + audience match + entity 매핑
9. frame → MCP session 생성 → tools 호출
```

상세는 [인증 · 권한](/architecture/auth) 참조.

## 다음 단계

- [Topology · 네트워크](/architecture/topology) — Cloudflare Tunnel, Docker network, proxy 패턴 상세
- [도메인 · DNS](/architecture/domains) — Cloudflare zone, 1-level subdomain 결정 근거
- [인증 · 권한](/architecture/auth) — Microsoft Entra ID, JWT, dual-token model
- [데이터 격리 모델](/architecture/data) — schema-per-entity, audit_log, PII 암호화
- [배포 · 무중단](/architecture/deploy) — blue/green frame swap, axe-frame-proxy
- [백업 · DR](/architecture/backup) — restic 3-tier (local / ring P2P / cold SSD)
