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

---
title: 도메인 · DNS
description: Cloudflare zone, 1-level subdomain 결정, customer 도메인 매핑.
---

# 도메인 · DNS

## 두 개의 zone

| Zone | 용도 | 상태 |
|---|---|---|
| `axelabs.ai` | **플랫폼** (이 docs, 모든 customer 서비스) | 2026-05-14 등록 |
| `axellc.com` | **corporate** (회사 이메일, 기업 홈페이지) | 기존 |

플랫폼 트래픽은 `axelabs.ai` 만 거치고, `axellc.com` 은 corporate 용도로 분리됩니다.

## URL 컨벤션

```
{customer}.axelabs.ai            ← apex, blueprint
{customer}.axelabs.ai/frame      ← frame MCP
{customer}.axelabs.ai/frame/mcp  ← MCP endpoint (canonical resource URI)
{customer}.axelabs.ai/vault      ← Vaultwarden
{customer}.axelabs.ai/index      ← (예정)

admin.axelabs.ai                 ← 운영자 콘솔 (Microsoft SSO)
docs.axelabs.ai                  ← 본 docs
```

## 왜 1-level subdomain + path?

선택지 비교:

| 옵션 | SSL | URL 모양 | 운영 부담 |
|---|---|---|---|
| 1-level + path | ✓ 무료 (Cloudflare Universal SSL) | `axe.axelabs.ai/frame` | cloudflared path-aware 라우팅 |
| 2-level subdomain | ❌ 유료 ($10/cert/월) | `frame.axe.axelabs.ai` | 일관 wildcard 필요 |
| Service-only domain | △ | `frame.axelabs.ai` | customer 격리 불가 |

→ 1-level + path 채택. cloudflared ingress 의 `path` 매칭으로 service 분기.

## 함정 — Universal SSL wildcard 의 1-level 한계 (D-ops-39)

무료 Universal SSL 의 wildcard cert (`*.axelabs.ai`) 는 **1단 서브도메인만 cover**. 2단 (e.g. `ssh.axe.axelabs.ai`, `<x>.axe.axelabs.ai`) 은 cert SAN 미일치 → edge 가 default cert 로 fallback → 클라이언트에서 `tls: handshake failure` / `SEC_E_ILLEGAL_MESSAGE` / `sslv3 alert handshake failure`.

**규칙**: HTTPS 노출되는 모든 hostname 은 `{name}.axelabs.ai` 의 **1단** 이어야 함. service 또는 sub-context 가 필요하면:

- ✅ **flat hostname** — `ssh-axe.axelabs.ai`, `docs-axe.axelabs.ai`
- ✅ **path under apex** — `axe.axelabs.ai/frame`
- ❌ **2단 subdomain** — `ssh.axe.axelabs.ai`, `frame.axe.axelabs.ai`

**증상이 보이면**: 클라이언트의 `cloudflared --version` 이 최신이고 시간 동기화도 정상인데 handshake failure 가 모든 클라이언트에서 일관되면 서버측 cert 문제. zone DNS records 에서 hostname dot count 확인. 함정 사례 → [/ops/known-gaps#cloudflare-universal-ssl-1-level](/ops/known-gaps#cloudflare-universal-ssl-1-level).

**유료 회피 옵션 평가**: Advanced Certificate Manager ($10/cert/월) 또는 zone delegation (`axe.axelabs.ai` 별도 zone) 모두 미채택. 무료 plan + flat-hostname 으로 충분.

## 현재 customer 별 할당

| customer | apex 도메인 | corporate 도메인 (이메일) |
|---|---|---|
| axe | `axe.axelabs.ai` | `axellc.com` |
| realchoice | `realchoice.axelabs.ai` | `realchoice.co.kr` |

## DNS records

axelabs.ai zone (Cloudflare):

```
CNAME  axe              <tunnel-id>.cfargotunnel.com   ; orange-cloud ON (axelabs tunnel)
CNAME  realchoice       <tunnel-id>.cfargotunnel.com   ; orange-cloud ON (realchoice tunnel)
CNAME  admin            <tunnel-id>.cfargotunnel.com   ; orange-cloud ON
CNAME  docs             <tunnel-id>.cfargotunnel.com   ; orange-cloud ON
CNAME  ssh-axe          <tunnel-id>.cfargotunnel.com   ; orange-cloud ON (operator SSH)
CNAME  www              axelabs.ai
TXT    axe              "MS=ms10433167"                ; Microsoft Entra domain verify
```

> `ssh-axe.axelabs.ai` 는 운영자/엔지니어가 macmini 에 SSH 진입하기 위한 Cloudflare Access 보호 endpoint. 클라이언트는 `cloudflared access ssh --hostname ssh-axe.axelabs.ai ...` 또는 `ssh user@ssh-axe.axelabs.ai` (ProxyCommand 설정 시).
> 이전 hostname `ssh.axe.axelabs.ai` 는 [위 함정](#함정--universal-ssl-wildcard-의-1-level-한계-d-ops-39) 으로 폐기 (D-ops-39, 2026-05-26). DNS record 와 `*.axe.axelabs.ai` 와일드카드 는 backlog 에서 일괄 정리.

Microsoft 도메인 검증 TXT 는 Application ID URI 에 `https://axe.axelabs.ai/frame/mcp` 같은 형식을 등록하기 위해 필요. 자세히는 [인증 · 권한](/architecture/auth#azure-app-id-uri).

## Customer 추가 시

1. `customers.yaml` 에 새 entry (예: `realchoice`)
2. Cloudflare zone 에 `A {customer}` record 추가 (proxy ON)
3. cloudflared config 에 ingress 규칙 추가
4. cloudflared 재시작 (1회만, ingress 안정 후 추가 변경 없음)

상세 절차는 [신규 customer onboarding](/ops/runbook/customer-onboarding).
