# KINTEX 보안 제약 (불변)

> GUARDiA 보안 제약(`CLAUDE.md` / `_framework/GUARDIA_STANDARD_FRAMEWORK.md §6`)을 킨텍스 관점으로 정리한 단일 참조.
> 아래 규칙은 어떤 상황에서도 위반 불가. API 계약(`API_GUIDE.md §5`)·개발 표준(`DEVELOPMENT_GUIDE.md §5`)과 함께 강제된다.

---

## 1. 외부 API 호출 정책

| 대상 | 정책 | 근거 |
|------|------|------|
| **온프레미스 Ollama** | 허용(기본) | 표준 온프레미스 우선 |
| **Anthropic Claude** (`api.anthropic.com`) | **승인된 단일 예외** — 키는 `ANTHROPIC_API_KEY` env only, 실패 시 Ollama 자동 폴백 | 소유자 승인(2026-07-03) |
| **Gemini 나노바나나** (이미지 생성) | **킨텍스 고유 승인 예외(G1 게이트)** — 키는 `GEMINI_API_KEY` **워커 env only**(백엔드 미취급), 미승인 시 목/degraded | PLANNING R12·G1 |
| 그 외 모든 외부 API | **금지** | 표준 불변 |

- Claude/Gemini 키는 **DB·코드·커밋·로그·API 응답에 절대 기록 금지**. env 에서만 로드.
- Gemini 는 **나노바나나 Python 워커에서만** 로드한다. Spring 백엔드는 큐 발행/콜백 수신만 하고 키를 취급하지 않는다.

## 2. 자격증명·민감정보 보호

- **응답 완전 제외**: 내부 IP·SSH 계정·비밀번호·비밀번호 해시·`GEMINI_API_KEY`·`ANTHROPIC_API_KEY`·내부 식별자·워커 토큰. (`ServerOut`류 스키마에서 제외 — API_GUIDE §5.)
- 사용자·업체 표시는 **비민감 필드만**.
- 로그·에러 메시지·메신저 알림에도 자격증명 노출 금지.
- 운영 스크립트(`scripts/push_kintex.py`·`tools/test/kintex_smoke_test.py`)는 **시크릿 하드코딩 0** — 전부 환경변수에서만 읽고, 조립한 인증 URL 조차 출력하지 않는다(마스킹).

## 3. 암호화 저장 (AES-256-GCM)

- admin 비밀번호: env `ADMIN_PASSWORD_ENC`(AES-256-GCM 암호문) + `ADMIN_KEY_FILE`(별도 키파일, root 600) → 기동 시 BCrypt 재시드. 하드코딩 `admin123`/`1111` 시드 금지.
- 저장이 필요한 외부 자격증명(SMTP 등)은 암호화 컬럼에만. 평문 저장 금지.
- JWT 시크릿(`KINTEX_JWT_SECRET`)·DB 비번(`KINTEX_DB_PASSWORD`)은 env/`application.yml` 프로퍼티 주입, `.env`·`*.key` 는 gitignore.

## 4. 인증·권한 (JWT + 2FA + 행사 RBAC)

- JWT(HS256) + **2차 인증(OTP/EMAIL 코드)** 2단계 로그인 + **로그인 실패 잠금**(관리자 해제).
- **행사 단위 RBAC**: 열람=행사 멤버 or 홀매니저 / 편집·액션=엔드포인트별 역할(`ORGANIZER·EXHIBITOR·CONTRACTOR·HALL_MANAGER`).
- **미등록 장치업체 차단**: 초대·응찰은 등록업체 검증(`NOT_REGISTERED_COMPANY` 403).
- `/api/admin/**` = ADMIN 역할 게이트. `/api/internal/**` = 워커 공유 시크릿(`X-Worker-Token`)만.

## 5. AI 생성 이미지 워터마크 (킨텍스 고유 불변)

- M5 나노바나나 결과 이미지 응답은 **항상** `watermarkRequired:true` + `watermarkText` + `notice`(계약·심사 서류 사용 금지 안내)를 포함한다.
- AI 생성 시각화는 **참고용**이며 계약·인허가 서류로 사용 불가 — UI·응답·PDF 어디서나 워터마크/고지 강제.

## 6. 오류 응답 (스택트레이스 미노출)

- 모든 오류는 `ApiResponse.error`(코드 + 사람이 읽는 요약 메시지)만 반환. **스택트레이스·relation/컬럼명·내부 경로 미노출**(서버 로그에만).
- DB 오류(DataAccessException)는 `@RestControllerAdvice` 로 `INTERNAL` 요약 매핑 → 테이블/컬럼명 누출 차단.
- 워커 실패 `errorMessage` 는 요약만 통과(스택트레이스 유입 차단).
- 오류 코드→HTTP 매핑은 `API_GUIDE.md §3` 고정 표를 따른다.

## 7. 감사 추적

- 관리자·인증·권한 변경 등 민감 액션은 감사 로그(`common/audit`, `TB_AUDIT_LOG` 계열)에 기록. 감사 로그에도 비밀값 미기재.

## 8. 서버 접속 (root 예외)

- 관리 대상 서버는 opsagent 전용, root SSH 금지가 표준. **예외**: GUARDiA 자체 인프라 `101.79.17.164`(kintex 개발 호스트 포함)에 한해 운영 작업용 root SSH 허용(소유자 승인 2026-06-18). 운영 배포는 소유자 승인 필수.

---

## 체크리스트 (배포·리뷰 전)

- [ ] 응답/로그/커밋에 IP·SSH·비번·해시·API키·워커토큰 노출 0 (grep)
- [ ] Gemini/Claude 키는 env only — 코드·DB·커밋 미포함
- [ ] admin 비번 하드코딩 시드 없음(env 재시드)
- [ ] M5 이미지 응답 `watermarkRequired:true` 포함
- [ ] DB/서버 오류 → 요약 메시지(스택·relation 명 미노출)
- [ ] 운영 스크립트 시크릿 하드코딩 0(env-only, 마스킹)
- [ ] `/api/admin/**` ADMIN 게이트·행사 RBAC·미등록업체 차단 동작
