# 03. Security Policy

## 외부 LLM API 차단 정책

MVP 기본 모드는 외부 LLM API를 사용하지 않는다.

```text
ALLOW_REMOTE_LLM_API=false
ALLOW_DEEPSEEK_API=false
ALLOW_OPENAI_API=false
ALLOW_ANTHROPIC_API=false
```

DeepSeek 계열은 API가 아니라 local DeepSeek-R1-Distill 모델만 선택적으로 지원한다.

## LLM Provider Router 보안

Local Agent는 내부에 Provider Router를 둘 수 있다. Router는 provider 프로파일을 정의하지만, MVP 기본 모드에서는 외부 API provider를 allowed 상태로 만들지 않는다.

- `deepseek-api`: 정의 가능, 기본 차단
- `hyperclova-think-local`: local OpenAI-compatible endpoint
- `hyperclova-vision-local`: local OpenAI-compatible endpoint
- `ollama-compatible`: local OpenAI-compatible endpoint

SaaS 서버는 Local Agent provider로 proxy 요청하지 않는다. 연결 테스트와 모델 호출은 브라우저 또는 Local Agent 내부에서 처리한다. 외부 provider 활성화는 개인정보, 원본 이미지, OCR 텍스트 전송 정책 검토와 운영 승인이 있기 전까지 금지한다.

## Local Agent 보안

- Authorization Bearer token 필수
- CORS 허용 origin 설정 가능
- `LOCAL_ONLY_MODE=true`
- 원본 이미지와 OCR 텍스트 외부 전송 금지
- 브라우저가 Local Agent로 직접 연결
- Flownco 서버는 사용자 입력 IP로 proxy 요청하지 않음

## 시험지 파일 전송 경로

시험지 업로드 시 SaaS 서버에는 법적/관리자 조회 요구사항에 맞춰 원본 파일과 메타데이터를 저장한다. 처리용 파일 전송은 브라우저가 사용자가 입력한 Local Agent IP/Port로 직접 수행한다.

```text
사용자 브라우저
  -> Flownco SaaS API: 프로젝트/파일/결과 저장
  -> Local Agent IP:Port: 시험지 파일 처리 요청
```

SaaS 서버는 Local Agent 주소로 중계 요청을 만들지 않는다. 이는 SSRF 위험을 줄이기 위한 기본 정책이다. Agent Token 평문은 서버 API 응답에 포함하지 않으며, 업로드 직후 직접 호출에 필요한 token은 현재 브라우저 세션에서만 사용한다.

## Token 암호화

Agent Token은 서버에서 AES-256-GCM으로 암호화 저장한다. 관리자 API와 UI는 token을 마스킹 표시하고 평문을 반환하지 않는다.

## 관리자 접근권한

운영 인증이 없으므로 MVP는 임시 관리자 보호 로직을 둔다. 운영 전 실제 인증/세션/JWT와 `PermissionService`를 연결해야 한다.

## 데이터 저장 정책

- SaaS 요청과 상태 변경은 AuditLog에 저장
- 민감정보는 암호화 또는 마스킹
- 업로드 파일 hash 저장
- storageMode 기본값: `DEV_LOCAL`
- 모든 상태 변경은 beforeJson, afterJson 저장

## ExportGuard

PDF 출력 전 다음 조건을 확인한다.

- unresolved UnreadableArea 없음
- DRAFT/REVIEW_REQUIRED Annotation 없음
- 최종 PDF에는 APPROVED Annotation만 포함
