보안 & 관리¶
API 키 섹션¶
API 키는 라우터 엔드포인트에 대한 클라이언트 접근을 제어합니다. 키는 여러 소스를 통해 설정할 수 있습니다.
인증 모드¶
mode 설정은 API 엔드포인트에 API 인증이 필요한지 제어합니다:
| 모드 | 동작 |
|---|---|
permissive (기본) | API 키 없이 요청 허용. 유효한 API 키가 있는 요청은 인증됨. |
blocking | API 키 인증을 통과한 요청만 처리. 인증되지 않은 요청은 401 수신. |
대상 엔드포인트 (mode가 blocking일 때):
/v1/chat/completions/v1/completions/v1/responses/v1/images/generations/v1/images/edits/v1/images/variations/v1/models
참고: Admin, Files, Metrics 엔드포인트는 별도의 인증 메커니즘이 있으며 이 설정의 영향을 받지 않습니다.
섹션 설정 속성:
| 속성 | 타입 | 필수 | 기본값 | 설명 |
|---|---|---|---|---|
mode | string | 아니오 | permissive | 인증 모드: permissive 또는 blocking |
api_keys | array | 아니오 | [] | 인라인 API 키 정의 |
api_keys_file | string | 아니오 | - | 외부 API 키 파일 경로 |
api_keys:
# 인증 모드: "permissive" (기본) 또는 "blocking"
mode: permissive
# 인라인 API 키 정의
api_keys:
- key: "${API_KEY_1}" # 환경 변수 치환
id: "key-production-1" # 고유 식별자
user_id: "user-admin" # 연결된 사용자
organization_id: "org-main" # 연결된 조직
name: "Production Admin Key" # 사람이 읽을 수 있는 이름
scopes: # 권한
- read
- write
- files
- admin
rate_limit: 1000 # 분당 요청 수 (선택 사항)
enabled: true # 활성 상태
expires_at: "2025-12-31T23:59:59Z" # 선택적 만료 (ISO 8601)
- key: "${API_KEY_2}"
id: "key-service-1"
user_id: "service-bot"
organization_id: "org-main"
name: "Service Account"
scopes: [read, write, files]
rate_limit: 500
enabled: true
# 보안 향상을 위한 외부 키 파일
api_keys_file: "/etc/continuum-router/api-keys.yaml"
키 속성:
| 속성 | 타입 | 필수 | 설명 |
|---|---|---|---|
key | string | 예 | API 키 값 (${ENV_VAR} 치환 지원) |
id | string | 예 | admin 작업을 위한 고유 식별자 |
user_id | string | 예 | 이 키와 연결된 사용자 |
organization_id | string | 예 | 사용자가 속한 조직 |
name | string | 아니오 | 사람이 읽을 수 있는 이름 |
description | string | 아니오 | 키에 대한 메모 |
scopes | array | 예 | 권한: read, write, files, admin |
rate_limit | integer | 아니오 | 분당 최대 요청 수 |
enabled | boolean | 아니오 | 활성 상태 (기본값: true) |
expires_at | string | 아니오 | ISO 8601 만료 타임스탬프 |
외부 키 파일 형식:
# /etc/continuum-router/api-keys.yaml
keys:
- key: "sk-prod-xxxxxxxxxxxxxxxxxxxxx"
id: "key-external-1"
user_id: "external-user"
organization_id: "external-org"
scopes: [read, write, files]
enabled: true
보안 기능:
- 키 마스킹: 전체 키는 로깅되지 않음 (
sk-***last4로 표시) - 만료 적용: 만료된 키는 자동으로 거부
- 핫 리로드: 서버 재시작 없이 키 업데이트
- 감사 로깅: 모든 키 관리 작업 로깅
- 상수 시간 검증: 타이밍 공격 방지
- 최대 키 제한: DoS 방지를 위해 최대 10,000개 키
Admin API 엔드포인트 (admin 인증 필요):
| 엔드포인트 | 메서드 | 설명 |
|---|---|---|
/admin/api-keys | GET | 모든 키 목록 (마스킹됨) |
/admin/api-keys/:id | GET | 키 세부 정보 가져오기 |
/admin/api-keys | POST | 새 키 생성 |
/admin/api-keys/:id | PUT | 키 속성 업데이트 |
/admin/api-keys/:id | DELETE | 키 삭제 |
/admin/api-keys/:id/rotate | POST | 새 키 값 생성 |
/admin/api-keys/:id/enable | POST | 키 활성화 |
/admin/api-keys/:id/disable | POST | 키 비활성화 |
WebUI 섹션¶
선택적 webui 섹션은 내장 브라우저 기반 관리 인터페이스를 제어합니다. WebUI는 바이너리에 컴파일되어 관리자 인증으로 보호되는 정적 에셋으로 제공됩니다.
구성 속성:
| 속성 | 타입 | 기본값 | 설명 |
|---|---|---|---|
enabled | boolean | true | WebUI 활성화 또는 비활성화 |
path_prefix | string | /webui | URL 경로 접두사. /로 시작해야 하며 ..을 포함해서는 안 됩니다. |
webui가 생략되면 기본값이 적용됩니다: WebUI는 /webui에서 활성화됩니다. WebUI를 비활성화하려면:
브라우저 인터페이스 사용에 대한 전체 가이드는 내장 WebUI를 참조하세요.
Admin 섹션¶
admin 섹션은 인증 및 통계 수집을 포함한 Admin REST API를 설정합니다.
인증¶
admin:
auth:
method: bearer_token # 인증 방법: none, bearer_token, basic, api_key
token: "${ADMIN_TOKEN}" # bearer_token 방식의 토큰
모든 인증 옵션에 대해서는 Admin REST API 레퍼런스를 참조하세요.
통계 수집¶
admin.stats 하위 섹션은 요청 메트릭 수집 및 영속화를 제어합니다. 통계 수집은 기본적으로 활성화되어 있습니다.
admin:
stats:
enabled: true # 수집 활성화/비활성화 (기본값: true)
retention_window: 24h # 윈도우 쿼리용 링 버퍼 보존 기간 (기본값: 24h)
token_tracking: true # 응답 본문에서 토큰 사용량 파싱 (기본값: true)
persistence:
enabled: true # 재시작 시 통계 영속 활성화 (기본값: true)
path: ./data/stats.json # 스냅샷 파일 경로 (기본값: ./data/stats.json)
snapshot_interval: 5m # 주기적 스냅샷 간격 (기본값: 5m)
max_age: 7d # 시작 시 이보다 오래된 스냅샷은 폐기 (기본값: 7d)
설정 속성:
| 속성 | 타입 | 기본값 | 설명 |
|---|---|---|---|
enabled | boolean | true | 통계 수집 활성화 또는 비활성화 |
retention_window | string | 24h | 윈도우 쿼리를 위한 링 버퍼 보존 기간 |
token_tracking | boolean | true | 토큰 사용량 추출을 위한 응답 본문 파싱 |
영속화 속성:
| 속성 | 타입 | 기본값 | 설명 |
|---|---|---|---|
persistence.enabled | boolean | true | 재시작 시 통계 영속화 활성화 |
persistence.path | string | ./data/stats.json | 영속화 스냅샷 파일 경로 |
persistence.snapshot_interval | string | 5m | 주기적 스냅샷 간격 |
persistence.max_age | string | 7d | 시작 시 스냅샷 복원 최대 기간 |
영속화가 활성화되면:
- 시작 시 라우터는 스냅샷 파일에서 카운터와 링 버퍼 레코드를 복원합니다. 업타임은 항상 0으로 리셋됩니다.
- 백그라운드 태스크가 설정된 간격으로 원자적(임시 파일 + 이름 변경)으로 스냅샷을 기록합니다.
- 정상 종료(SIGTERM/SIGINT) 시 최종 스냅샷이 저장됩니다.
- 누락, 손상, 또는 오래된 스냅샷은 정상적으로 처리됩니다 — 라우터는 새 카운터로 시작하고 경고를 로깅합니다.
핫 리로드: retention_window와 token_tracking은 즉시 핫 리로드를 지원합니다. 영속화 설정(path, snapshot_interval, max_age)은 재시작이 필요합니다.
지원되는 기간 형식 (retention_window, snapshot_interval, max_age):
| 형식 | 예제 | 의미 |
|---|---|---|
Xs | 30s | 30초 |
Xm | 5m | 5분 |
Xh | 1h | 1시간 |
Xd | 7d | 7일 |
전체 엔드포인트 문서는 Admin REST API 레퍼런스 — 통계 API를 참조하세요.
ACP (Agent Communication Protocol) 섹션¶
acp 섹션은 Agent Communication Protocol 하위 시스템을 설정합니다. ACP는 IDE 및 도구 통합이 stdio를 통한 JSON-RPC 2.0으로 라우터와 통신할 수 있도록 합니다. ACP는 하위 호환성을 위해 기본적으로 비활성화되어 있습니다.
ACP를 사용하려면 --mode stdio로 라우터를 실행하세요.
acp:
enabled: true
transport:
stdio:
enabled: true
agent:
name: "Continuum Router"
version: "1.0.0"
description: "Local LLM inference agent"
capabilities:
load_session: true
image: false
audio: false
embedded_context: false
mcp: true
default_model: "gpt-4o"
system_prompt: "You are a helpful coding assistant."
coding_agent_mode: true
permissions:
default_policy: ask_always
auto_allow:
- read
- search
- think
always_ask:
- edit
- delete
- execute
sessions:
max_concurrent: 10
idle_timeout: "1h"
storage: "memory"
mcp:
max_connections_per_session: 5
allowed_servers: []
server_spawn_timeout: "10s"
최상위 옵션¶
| 속성 | 타입 | 기본값 | 설명 |
|---|---|---|---|
enabled | bool | false | ACP 하위 시스템 활성화/비활성화 |
default_model | string | 없음 | ACP 세션의 모델 선택 재정의 |
system_prompt | string | 없음 | 모든 ACP 요청에 시스템 프롬프트 주입 |
coding_agent_mode | bool | false | 코딩 에이전트 시스템 프롬프트 활성화 |
전송 옵션¶
| 속성 | 타입 | 기본값 | 설명 |
|---|---|---|---|
transport.stdio.enabled | bool | true | stdio 전송 활성화 |
권한 옵션¶
| 속성 | 타입 | 기본값 | 설명 |
|---|---|---|---|
permissions.default_policy | enum | ask_always | 기본 정책: ask_always, allow_read, allow_all |
permissions.auto_allow | list | [read, search, think] | 확인 없이 자동 허용되는 도구 종류 |
permissions.always_ask | list | [edit, delete, execute] | 항상 권한을 요청하는 도구 종류 |
세션 옵션¶
| 속성 | 타입 | 기본값 | 설명 |
|---|---|---|---|
sessions.max_concurrent | int | 10 | 최대 동시 세션 수 |
sessions.idle_timeout | string | "1h" | 세션 정리 전 유휴 타임아웃 |
sessions.storage | string | "memory" | 저장 백엔드: memory 또는 file |
sessions.storage_path | string | 없음 | 파일 기반 저장 경로 |
MCP 브릿지 옵션¶
| 속성 | 타입 | 기본값 | 설명 |
|---|---|---|---|
mcp.max_connections_per_session | int | 5 | 세션당 최대 MCP 연결 수 |
mcp.allowed_servers | list | [] | 허용된 서버 ID (빈 값 = 모두 허용) |
mcp.server_spawn_timeout | string | "10s" | MCP 서버 프로세스 생성 타임아웃 |
프로토콜 세부 사항은 ACP 아키텍처를, 실용 예제는 ACP 사용 가이드를 참조하세요.