# 보안 즉시 보강 Phase 1 (3개 항목)

## 배경
AI 앱 보안 30계명과 우리 시스템 비교 분석 결과, 즉시 보강이 필요한 3가지 항목.
보안 로드맵: `/home/jay/workspace/memory/specs/security-roadmap.md`

---

## 작업 1-1: 시크릿 로테이션 정책 + 인벤토리 시스템

### 파일 1: `memory/security/secret-inventory.json` (신규)
시크릿 인벤토리. 아래 구조로 생성:

```json
{
  "version": "1.0",
  "last_checked": null,
  "rotation_policy_days": 90,
  "secrets": [
    {
      "name": "COKACDIR_KEY_ANU",
      "source_file": ".env.keys",
      "owner": "jay",
      "created_date": "2026-03-01",
      "last_rotated": "2026-03-01",
      "expires_date": "2026-05-30",
      "category": "telegram_bot",
      "rotation_notes": "cokacdir 봇 설정에서 재생성"
    }
  ]
}
```

아래 시크릿 목록을 모두 등록 (created_date는 2026-03-01로 초기화, expires_date는 +90일):
- `COKACDIR_KEY_ANU` — category: telegram_bot
- `COKACDIR_KEY_DEV1` — category: telegram_bot
- `COKACDIR_KEY_DEV2` — category: telegram_bot
- `COKACDIR_KEY_DEV3` — category: telegram_bot
- `GLM_API_KEY` — category: ai_api
- `VERCEL_TOKEN` — category: deployment
- `NAVER_SEARCHAD_API_KEY` — category: external_api
- `NAVER_SEARCHAD_SECRET_KEY` — category: external_api
- `NAVER_SEARCHAD_CUSTOMER_ID` — category: external_api
- `INFORKEYWORD_API_KEY` — category: internal_api
- `GROUP_CHAT_BOT_TOKEN` — category: telegram_bot
- `OPENAI_API_KEY` — category: ai_api
- `AI_ENCRYPTION_KEY` — category: encryption (InsuWiki BYOK)
- `FIREBASE_SERVICE_ACCOUNT_KEY` — category: cloud_service (InsuWiki)
- `DRIVE_CLIENT_ID` — category: cloud_service
- `DRIVE_CLIENT_SECRET` — category: cloud_service
- `DRIVE_REFRESH_TOKEN` — category: cloud_service
- `GOOGLE_DRIVE_CREDENTIALS_PATH` — category: cloud_service (InfoKeyword GCS)

### 파일 2: `scripts/secret-rotation-check.py` (신규)
시크릿 만료 체크 스크립트.

기능:
1. `secret-inventory.json` 로드
2. 각 시크릿의 `expires_date`와 현재 날짜 비교
3. 출력 분류:
   - EXPIRED: 만료일 지남
   - WARNING: 14일 이내 만료 예정
   - OK: 정상
4. `--json` 플래그로 JSON 출력 지원
5. `--update-checked` 플래그로 `last_checked` 타임스탬프 갱신
6. EXPIRED 또는 WARNING 하나라도 있으면 exit code 1
7. 실행 결과를 stdout으로 출력

CLI 사용법:
```bash
python3 scripts/secret-rotation-check.py              # 콘솔 출력
python3 scripts/secret-rotation-check.py --json        # JSON 출력
python3 scripts/secret-rotation-check.py --update-checked  # 체크 시각 갱신
```

### 파일 3: 테스트 `tests/test_secret_rotation_check.py` (신규)
- test_all_ok: 모든 시크릿 정상일 때 exit code 0
- test_expired_detected: 만료된 시크릿 감지
- test_warning_14days: 14일 이내 만료 경고
- test_json_output: --json 출력 형식 검증
- test_update_checked: last_checked 갱신 확인

---

## 작업 1-2: npm audit CI 자동화

### 파일: `scripts/npm-audit.sh` (신규)
```bash
#!/bin/bash
# npm audit 자동화 - 프론트엔드 프로젝트 대상
# exit code: 0=클린, 1=취약점 발견

PROJECTS=(
  "/home/jay/projects/insuwiki/nextapp"
  "/home/jay/projects/InfoKeyword"
)

FAIL=0
for proj in "${PROJECTS[@]}"; do
  if [ -f "$proj/package-lock.json" ]; then
    echo "=== Auditing: $proj ==="
    cd "$proj"
    npm audit --audit-level=high 2>&1
    if [ $? -ne 0 ]; then
      echo "❌ HIGH+ 취약점 발견: $proj"
      FAIL=1
    else
      echo "✅ 클린: $proj"
    fi
  else
    echo "⚠️ package-lock.json 없음: $proj"
  fi
done

exit $FAIL
```

### `scripts/ci.sh` 수정
기존 6단계 CI에 7단계 추가:
```bash
# 7. npm audit
bash scripts/npm-audit.sh
```

---

## 작업 1-3: AI API 비용 하드 리밋

### InsuWiki: `nextapp/src/app/api/ai/vector-search/route.ts` 수정
- `/home/jay/projects/insuwiki/nextapp/src/app/api/ai/vector-search/route.ts`

기존 rate limiting 이후, 일일 쿼리 하드 리밋 추가:
```typescript
// 환경변수: MAX_DAILY_QUERIES (기본 5000)
const MAX_DAILY_QUERIES = parseInt(process.env.MAX_DAILY_QUERIES || '5000');

// costMonitor에서 오늘 쿼리 수 확인
const dailyUsage = await getDailyUsage();  // api_usage_daily에서 조회
if (dailyUsage.totalQueries >= MAX_DAILY_QUERIES) {
  return NextResponse.json(
    { error: '일일 API 사용량 한도를 초과했습니다. 내일 다시 시도해주세요.' },
    { status: 429 }
  );
}
```

### InsuWiki: `nextapp/src/lib/monitoring/costMonitor.ts` 수정
- `getDailyUsage()` export 함수 추가 (기존 내부 로직 활용)
- `MAX_DAILY_COST_USD` 환경변수 추가 (기본 $5)
- 비용 한도 초과 시 `isOverBudget: true` 반환

## QC 기준
- 시크릿 체크 스크립트 5개 테스트 통과
- npm audit 스크립트 실행 가능 (exit code 정상)
- InsuWiki 기존 테스트 깨지지 않음
- pyright 0 errors (Python 부분)
- 새 기능 모두 환경변수 기반 설정
