# 보안 자동화 파이프라인 설계
> 작성일: 2026-03-23 | 작성팀: dev2-team | task-828.1
> PentAGI 분석 기반

## 1. PentAGI에서 배울 수 있는 자동화 패턴

### 1.1 멀티에이전트 자동화 패턴

PentAGI는 Primary Agent가 전문 에이전트에게 작업을 위임하는 계층 구조를 채택한다. 코드 분석 결과 (`backend/pkg/providers/pconfig/config.go`), 다음 에이전트 타입들이 존재한다:

- `primary_agent` — 최상위 오케스트레이터
- `pentester` / `coder` / `installer` / `searcher` / `enricher` — 전문 에이전트
- `adviser` / `reflector` / `generator` / `refiner` — 보조 에이전트

**도구 호출 제한** (`backend/pkg/providers/performer.go`):

```go
const (
    maxGeneralAgentChainIterations = 100  // Primary/Pentester/Coder/Installer
    maxLimitedAgentChainIterations = 20   // Searcher/Enricher 등 제한 에이전트
    maxAgentShutdownIterations     = 3    // 종료 버퍼 (graceful shutdown)
    maxSoftDetectionsBeforeAbort   = 4    // 반복 감지 후 강제 중단 임계값
)
```

- General 에이전트(Primary, Pentester, Coder): 최대 100회 반복
- Limited 에이전트(Searcher, Enricher 등): 최대 20회 반복
- 종료 직전 `maxAgentShutdownIterations` 여유 확보 후 Reflector 호출

**반복 감지기 (Repeating Detector)**:

```go
const RepeatingToolCallThreshold = 3  // 동일 도구 3회 연속 → 경고

// maxSoftDetectionsBeforeAbort(4)회 초과 → 강제 체인 중단
if len(detector.funcCalls) >= RepeatingToolCallThreshold+maxSoftDetectionsBeforeAbort {
    errMsg := fmt.Sprintf("tool '%s' repeated %d times consecutively, aborting chain", ...)
}
```

**Reflector로 우아한 종료**: 반복 한도 도달 전 3회 버퍼 구간에서 Reflector 에이전트가 호출되어 작업 결과를 정리하고 종료한다.

### 1.2 지식 관리 패턴

pgvector 기반 장기 기억 저장소를 운영한다 (`backend/pkg/tools/guide.go`, `memory.go`, `search.go`). 세 가지 문서 타입을 구분하여 저장한다:

| doc_type | 내용 | 저장 시점 |
|---|---|---|
| `guide` | 특정 문제 해결 방법론 (Q&A 형태) | 에이전트가 StoreGuide 도구 호출 시 |
| `memory` | 도구 실행 결과 (터미널, 검색 등) | 허용된 도구 실행 후 자동 저장 |
| `qa` / `code` | 검색 답변 및 코드 스니펫 | 각 도구 핸들러에서 자동 저장 |

**민감 데이터 익명화**: 저장 전 `anonymizer.Replacer`를 통해 IP, 비밀번호, API 키 등을 자동으로 대체한다.

```go
anonymizedGuide    = g.replacer.ReplaceString(guide)
anonymizedQuestion = g.replacer.ReplaceString(action.Question)
```

**벡터 유사도 검색**: 임계값 `0.2` 이상의 유사도를 가진 최대 3개 문서를 반환한다. 특정 필터(task_id, subtask_id)로 결과가 없으면 전역 필터로 자동 폴백한다.

### 1.3 Supervision 패턴

**Execution Monitor** (`backend/pkg/providers/helpers.go`):

```go
type executionMonitor struct {
    sameToolCount  int   // 동일 도구 연속 호출 횟수
    totalCallCount int   // 누적 도구 호출 횟수
    sameThreshold  int   // 동일 도구 임계값 초과 시 멘토 개입
    totalThreshold int   // 전체 호출 임계값 초과 시 멘토 개입
}
```

임계값 초과 시 Adviser 에이전트(`mentor`)를 호출하여 진행 상황을 검토하고 다음 방향을 제안한다.

**Task Planner** (`backend/pkg/providers/performers.go`):
- `performPlanner()` 함수: 작업 실행 전 Adviser 에이전트에게 실행 계획을 요청한다
- 생성된 계획은 원래 작업 지시와 함께 에이전트에 주입된다 (`PromptTypeTaskAssignmentWrapper`)
- Coder, Installer, Pentester 에이전트 실행 전 자동으로 호출된다

**도구 호출 실패 시 자동 인수 수정** (`backend/pkg/providers/performer.go`):

```go
const maxRetriesToCallFunction = 3  // 최대 3회 재시도

// 실패 시 LLM에게 인수 수정 요청
funcArgs, err = fp.fixToolCallArgs(ctx, funcName, funcArgs, funcSchema, funcExecErr)
```

### 1.4 샌드박스 격리 패턴

Docker 클라이언트 (`backend/pkg/docker/client.go`):

```go
const (
    BaseContainerPortsNumber    = 28000  // 포트 할당 기준점
    containerPortsNumber        = 2      // 컨테이너당 포트 수
    limitContainerPortsNumber   = 2000   // 최대 포트 범위
)

// 플로우별 독립적인 포트 자동 계산
func GetPrimaryContainerPorts(flowID int64) []int {
    delta := (int(flowID)*containerPortsNumber + i) % limitContainerPortsNumber
    ports[i] = BaseContainerPortsNumber + delta
}
```

- 각 플로우(침투 테스트 세션)마다 독립 Docker 컨테이너 생성
- `flow-{id}` 네이밍 규칙으로 작업 디렉토리 격리
- 작업 완료 후 `Cleanup()` 자동 호출로 컨테이너 정리
- 기본 이미지: `debian:latest`, 작업에 따라 자동 이미지 선택

---

## 2. 우리 시스템에 도입 가능한 자동 보안 스캔 파이프라인

### 2.1 파이프라인 아키텍처

```
코드 커밋 → Pre-commit Hooks → CI/CD Pipeline → 스테이징 → 프로덕션
     │              │                │              │
     │     시크릿 스캔        정적 분석         동적 분석
     │    (gitleaks)        (ESLint,         (OWASP ZAP,
     │                      Bandit)          nuclei)
     │                        │                │
     └─────────────────────────────────────────┘
                        │
                   보안 보고서 자동 생성
                        │
                   Slack/Discord 알림
```

### 2.2 Pre-commit 단계

1. **시크릿 스캐닝**: gitleaks, truffleHog
   - `.env`, API 키, 비밀번호 하드코딩 탐지
   - 커밋 차단 (hard fail)
2. **코드 포맷팅 보안**: ESLint security plugin

```bash
# .pre-commit-config.yaml 예시
repos:
  - repo: https://github.com/zricethezav/gitleaks
    rev: v8.18.0
    hooks:
      - id: gitleaks
        name: Detect hardcoded secrets
        language: golang
        pass_filenames: false

  - repo: https://github.com/pre-commit/mirrors-eslint
    rev: v8.57.0
    hooks:
      - id: eslint
        files: \.[jt]sx?$
        additional_dependencies:
          - eslint-plugin-security@3.0.0
```

### 2.3 CI/CD 보안 체크 (GitHub Actions)

**Stage 1 — 정적 분석:**

1. **의존성 취약점 스캔**
   - `npm audit --audit-level=high`
   - `pip audit` (아누 서버)
   - Snyk (선택적)
2. **정적 코드 분석 (SAST)**
   - ESLint + security plugin (JavaScript/TypeScript)
   - Bandit (Python)
   - Semgrep (다중 언어)
3. **Firebase Rules 검증**
   - `firebase emulators:exec --only firestore` (rules 테스트)
4. **시크릿 스캐닝**
   - gitleaks (전체 히스토리)
5. **라이선스 검사**
   - license-checker
6. **Docker 이미지 스캔** (해당 시)
   - Trivy

**Stage 2 — 빌드 후 분석:**

1. **보안 헤더 검증**
   - CSP, HSTS, X-Frame-Options 자동 확인
2. **번들 분석**
   - 민감 정보 번들 포함 여부

**Stage 3 — 동적 분석 (스테이징):**

1. **OWASP ZAP 자동 스캔**
   - 패시브 스캔 (자동)
   - 액티브 스캔 (주 1회)
2. **nuclei 템플릿 스캔**
   - 커스텀 보안 규칙 적용
3. **API 엔드포인트 퍼징**
   - 입력 검증 자동 테스트

### 2.4 정기 보안 스캔 자동화

| 주기 | 도구 | 대상 | 알림 |
|---|---|---|---|
| 매 커밋 | gitleaks, ESLint | 변경 코드 | PR 코멘트 |
| 일간 | npm audit, Dependabot | 의존성 | Slack |
| 주간 | OWASP ZAP passive | 스테이징 | Slack |
| 월간 | nuclei full scan | 프로덕션 | 보고서 |
| 분기 | 수동 침투 테스트 (로키) | 전체 | 보고서 |

---

## 3. CI/CD 통합 보안 체크 방안

### 3.1 GitHub Actions 워크플로우 설계

```yaml
# .github/workflows/security-scan.yml 예시 구조
name: Security Scan
on:
  push:
    branches: [main, develop]
  pull_request:
  schedule:
    - cron: '0 6 * * 1'  # 매주 월요일 6시

jobs:
  secret-scan:
    name: Secret Scanning
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0
      - name: Run gitleaks
        uses: gitleaks/gitleaks-action@v2
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

  dependency-scan:
    name: Dependency Vulnerability Scan
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: npm audit
        run: npm audit --audit-level=high
      - name: pip audit
        run: |
          pip install pip-audit
          pip-audit --requirement requirements.txt

  sast:
    name: Static Analysis (SAST)
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: ESLint security
        run: npx eslint --plugin security src/
      - name: Bandit (Python)
        run: |
          pip install bandit
          bandit -r . -ll
      - name: Semgrep
        uses: semgrep/semgrep-action@v1
        with:
          config: >-
            p/javascript
            p/typescript
            p/python
            p/firebase

  firebase-rules-test:
    name: Firebase Rules Test
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Install Firebase CLI
        run: npm install -g firebase-tools
      - name: Run Firestore Rules Tests
        run: firebase emulators:exec --only firestore "npm run test:rules"

  security-headers:
    name: Security Headers Check
    needs: [build]
    runs-on: ubuntu-latest
    steps:
      - name: Check security headers
        run: |
          curl -I ${{ env.STAGING_URL }} | grep -E "Content-Security-Policy|Strict-Transport-Security|X-Frame-Options"

  dast:
    name: Dynamic Analysis (DAST)
    needs: [deploy-staging]
    runs-on: ubuntu-latest
    if: github.ref == 'refs/heads/main'
    steps:
      - name: OWASP ZAP Passive Scan
        uses: zaproxy/action-baseline@v0.10.0
        with:
          target: ${{ env.STAGING_URL }}
          rules_file_name: '.zap/rules.tsv'
          cmd_options: '-a'

  report:
    name: Security Report
    needs: [secret-scan, dependency-scan, sast, firebase-rules-test, security-headers]
    if: always()
    runs-on: ubuntu-latest
    steps:
      - name: Aggregate results
        run: echo "보안 스캔 결과 통합"
      - name: Notify Slack
        if: failure()
        uses: slackapi/slack-github-action@v1.26.0
        with:
          payload: |
            {
              "text": "보안 스캔 실패: ${{ github.repository }} - ${{ github.workflow }}"
            }
        env:
          SLACK_WEBHOOK_URL: ${{ secrets.SLACK_SECURITY_WEBHOOK }}
```

### 3.2 Vercel 배포 연동

```json
// vercel.json — 보안 헤더 자동 적용
{
  "headers": [
    {
      "source": "/(.*)",
      "headers": [
        {
          "key": "Strict-Transport-Security",
          "value": "max-age=63072000; includeSubDomains; preload"
        },
        {
          "key": "X-Frame-Options",
          "value": "DENY"
        },
        {
          "key": "X-Content-Type-Options",
          "value": "nosniff"
        },
        {
          "key": "Referrer-Policy",
          "value": "strict-origin-when-cross-origin"
        },
        {
          "key": "Content-Security-Policy",
          "value": "default-src 'self'; script-src 'self' 'unsafe-inline' https://apis.google.com; connect-src 'self' https://*.firebaseio.com https://*.googleapis.com; frame-src 'none';"
        }
      ]
    }
  ]
}
```

- Vercel Preview 배포 시 자동 보안 스캔
- Production 배포 전 보안 게이트 (scan 통과 필수)
- `vercel.json`으로 보안 헤더 자동 적용

### 3.3 Firebase 연동

```bash
# Firebase Rules 테스트 자동화 예시
# package.json scripts 추가
"test:rules": "firebase emulators:exec --only firestore 'jest tests/firestore.rules.test.js'"
"test:auth-rules": "firebase emulators:exec --only auth 'jest tests/auth.rules.test.js'"
```

- Firebase Rules 변경 시 자동 시뮬레이터 테스트
- Firebase Auth 설정 변경 감지
- Firestore 인덱스 보안 검토

---

## 4. 도구별 상세 설정 가이드

### 4.1 gitleaks 설정

```toml
# .gitleaks.toml
title = "dev2-team gitleaks config"

[extend]
useDefault = true

[[allowlist]]
description = "Global allowlist"
regexTarget = "line"
regexes = [
  # 테스트 파일의 더미 데이터 허용
  '''EXAMPLE_API_KEY''',
  '''YOUR_API_KEY_HERE''',
]
paths = [
  # 테스트 파일 제외
  '''.*_test\.(js|ts|py)$''',
  '''.*\.test\.(js|ts)$''',
  '''.*\.spec\.(js|ts)$''',
]

[[rules]]
id = "firebase-api-key"
description = "Firebase API Key"
regex = '''AIza[0-9A-Za-z-_]{35}'''
tags = ["firebase", "api-key"]

[[rules]]
id = "vercel-token"
description = "Vercel Token"
regex = '''(?i)(vercel[_-]?(token|api[_-]?key|secret))[^\w]*(=|:)\s*['"]?([a-zA-Z0-9_-]{20,})'''
tags = ["vercel", "token"]
```

### 4.2 OWASP ZAP 설정

```yaml
# .zap/rules.tsv — 커스텀 규칙 (Firebase/Vercel 특화)
# rule_id  action  parameter
10202      IGNORE  # Firebase Storage CORS 관련 오탐 제외
10096      IGNORE  # Vercel Edge Function 헤더 관련 오탐 제외
40014      WARN    # SQL Injection: WARN으로 하향 (NoSQL 환경)
```

```bash
# ZAP 자동화 API 사용 예시
#!/bin/bash
ZAP_API_KEY="your-api-key"
TARGET_URL="https://staging.example.com"

# 패시브 스캔 시작
curl -s "http://localhost:8080/JSON/spider/action/scan/?apikey=${ZAP_API_KEY}&url=${TARGET_URL}"

# 스캔 완료 대기
while [ "$(curl -s 'http://localhost:8080/JSON/spider/view/status/?apikey=${ZAP_API_KEY}' | jq -r '.status')" != "100" ]; do
  sleep 5
done

# 리포트 생성
curl -s "http://localhost:8080/OTHER/core/other/htmlreport/?apikey=${ZAP_API_KEY}" > zap-report.html
```

### 4.3 nuclei 설정

```yaml
# nuclei/templates/custom/firebase-misconfiguration.yaml
id: firebase-public-database

info:
  name: Firebase Public Database
  author: dev2-team
  severity: high
  description: Firebase Realtime Database is publicly accessible
  tags: firebase,misconfiguration

requests:
  - method: GET
    path:
      - "{{BaseURL}}/.json"
    matchers-condition: and
    matchers:
      - type: status
        status:
          - 200
      - type: word
        words:
          - '"rules"'
        negative: true
```

```bash
# nuclei CI 연동 스크립트
#!/bin/bash
nuclei \
  -u "${TARGET_URL}" \
  -t nuclei/templates/custom/ \
  -t nuclei-templates/exposures/ \
  -t nuclei-templates/misconfiguration/ \
  -severity medium,high,critical \
  -o nuclei-report.json \
  -json \
  -silent
```

### 4.4 Semgrep 규칙

```yaml
# semgrep/rules/nextjs-security.yml
rules:
  - id: nextjs-dangerouslySetInnerHTML
    patterns:
      - pattern: dangerouslySetInnerHTML={{ __html: $X }}
    message: |
      dangerouslySetInnerHTML 사용 감지. XSS 위험. 사용자 입력을 직접 전달하지 마세요.
    languages: [javascript, typescript]
    severity: WARNING

  - id: firebase-client-side-auth-bypass
    patterns:
      - pattern: |
          getDoc($DOC).then(($SNAP) => {
            ...
            $SNAP.data().$FIELD
            ...
          })
    message: |
      Firestore 클라이언트에서 보안 규칙 없이 데이터 접근 패턴 감지.
      Security Rules로 서버사이드 검증 필요.
    languages: [javascript, typescript]
    severity: WARNING

  - id: env-var-exposure-in-client
    patterns:
      - pattern: process.env.$VAR
      - metavariable-regex:
          metavariable: $VAR
          regex: "^(?!NEXT_PUBLIC_).*"
    message: |
      서버 전용 환경 변수가 클라이언트 코드에서 참조됨. 민감 정보 노출 위험.
    paths:
      include:
        - "src/components/**"
        - "src/pages/**"
        - "src/app/**"
    languages: [javascript, typescript]
    severity: ERROR
```

### 4.5 npm audit 자동화

```json
// .nsprc — npm audit 예외 관리
{
  "exceptions": [
    {
      "id": 1098765,
      "reason": "개발 의존성 전용, 프로덕션 번들 미포함 확인",
      "expires": "2026-06-01"
    }
  ]
}
```

```yaml
# Dependabot 설정 (.github/dependabot.yml)
version: 2
updates:
  - package-ecosystem: "npm"
    directory: "/"
    schedule:
      interval: "daily"
      time: "06:00"
      timezone: "Asia/Seoul"
    open-pull-requests-limit: 10
    reviewers:
      - "dev2-team"
    labels:
      - "security"
      - "dependencies"
    ignore:
      # major 버전 업데이트는 수동으로
      - dependency-name: "*"
        update-types: ["version-update:semver-major"]

  - package-ecosystem: "pip"
    directory: "/anu-server"
    schedule:
      interval: "daily"
    reviewers:
      - "dev2-team"
```

---

## 5. 보안 보고서 자동 생성

### 5.1 보고서 포맷

```json
// security-report-template.json
{
  "report": {
    "generated_at": "2026-03-23T06:00:00+09:00",
    "scan_target": {
      "repository": "dev2-team/project",
      "branch": "main",
      "commit": "abc1234"
    },
    "summary": {
      "critical": 0,
      "high": 2,
      "medium": 5,
      "low": 12,
      "info": 30
    },
    "findings": [
      {
        "id": "ZAP-10202",
        "severity": "HIGH",
        "tool": "OWASP ZAP",
        "title": "Missing Content Security Policy",
        "description": "...",
        "affected_url": "https://staging.example.com/login",
        "recommendation": "vercel.json에 CSP 헤더 추가",
        "cwe": "CWE-693",
        "first_seen": "2026-03-23",
        "status": "open"
      }
    ],
    "comparison": {
      "previous_scan": "2026-03-16T06:00:00+09:00",
      "new_findings": 1,
      "resolved_findings": 3,
      "unchanged_findings": 14
    }
  }
}
```

### 5.2 알림 체계

```python
# 심각도별 알림 로직 (Python 예시)
import json
import requests

def send_security_alert(findings: list, webhook_url: str, email_list: list):
    critical = [f for f in findings if f["severity"] == "CRITICAL"]
    high = [f for f in findings if f["severity"] == "HIGH"]
    medium = [f for f in findings if f["severity"] == "MEDIUM"]
    low = [f for f in findings if f["severity"] == "LOW"]

    # Critical: 즉시 Slack 알림 + 이메일
    if critical:
        send_slack_immediate(critical, webhook_url)
        send_email_alert(critical, email_list, priority="urgent")

    # High: Slack 알림
    if high:
        send_slack_notification(high, webhook_url)

    # Medium: 주간 보고서에 포함 (일간 실행 시 누적)
    if medium:
        append_to_weekly_report(medium)

    # Low: 월간 보고서에 포함
    if low:
        append_to_monthly_report(low)

def send_slack_immediate(findings: list, webhook_url: str):
    payload = {
        "text": f":rotating_light: *CRITICAL 보안 취약점 발견* :rotating_light:",
        "attachments": [
            {
                "color": "danger",
                "fields": [
                    {"title": f["title"], "value": f["description"], "short": False}
                    for f in findings
                ]
            }
        ]
    }
    requests.post(webhook_url, json=payload)
```

---

## 6. 모니터링 대시보드

### 6.1 보안 메트릭

PentAGI의 관측가능성 스택(`docker-compose-observability.yml`)을 참고하여 보안 메트릭 수집 체계를 구성한다:

| 메트릭 | 설명 | 수집 도구 |
|---|---|---|
| `security_open_vulns_total` | 열린 취약점 수 (심각도별 레이블) | Custom exporter |
| `security_mttr_seconds` | 평균 취약점 수정 시간 (MTTR) | Custom exporter |
| `security_dependency_vulns` | 의존성 취약점 추이 | npm audit JSON 파싱 |
| `security_scan_pass_rate` | 보안 스캔 통과율 | GitHub Actions 결과 |
| `security_secret_leaks_total` | 감지된 시크릿 누출 수 | gitleaks 결과 |

### 6.2 Grafana 대시보드 (PentAGI 참고)

PentAGI는 다음 스택을 사용한다 (`docker-compose-observability.yml`):
- **VictoriaMetrics** (`v1.108.1`): 메트릭 장기 저장
- **Loki** (`v3.3.2`): 로그 집계
- **Jaeger** (`v1.56.0`, ClickHouse 백엔드): 분산 추적
- **OpenTelemetry Collector** (`v0.116.1`): 데이터 수집 허브
- **Grafana** (`v11.4.0`): 시각화

우리 시스템에 적용할 보안 대시보드 패널:

```yaml
# grafana-security-dashboard.json 구조 (간략화)
panels:
  - title: "취약점 현황 (심각도별)"
    type: "piechart"
    datasource: "VictoriaMetrics"
    query: 'sum by (severity) (security_open_vulns_total)'

  - title: "취약점 추이 (30일)"
    type: "timeseries"
    datasource: "VictoriaMetrics"
    query: 'security_open_vulns_total{severity=~"critical|high"}'

  - title: "보안 스캔 로그"
    type: "logs"
    datasource: "Loki"
    query: '{job="security-scanner"} |= "FAIL"'

  - title: "평균 수정 시간 (MTTR)"
    type: "stat"
    datasource: "VictoriaMetrics"
    query: 'avg(security_mttr_seconds) / 3600'
    unit: "hours"
```

---

## 7. 구현 로드맵

### Phase 1 — 즉시 (1주 이내)

- [ ] pre-commit hook (gitleaks) 설치 — `pip install pre-commit && pre-commit install`
- [ ] `.gitleaks.toml` 설정 파일 작성
- [ ] `npm audit --audit-level=high` CI 스텝 추가
- [ ] Firebase Rules 단위 테스트 최소 10개 작성
- [ ] `vercel.json` 보안 헤더 추가 (HSTS, X-Frame-Options, CSP)

```bash
# Phase 1 빠른 시작 스크립트
#!/bin/bash
set -e

echo "=== Phase 1: 즉시 보안 설정 ==="

# 1. pre-commit 설치
pip install pre-commit
cat > .pre-commit-config.yaml << 'EOF'
repos:
  - repo: https://github.com/zricethezav/gitleaks
    rev: v8.18.0
    hooks:
      - id: gitleaks
EOF
pre-commit install
echo "[OK] pre-commit hook 설치 완료"

# 2. npm audit 테스트
npm audit --audit-level=high || echo "[WARN] npm audit 취약점 발견"

# 3. 현재 보안 헤더 확인
if [ -n "$VERCEL_URL" ]; then
  curl -I "$VERCEL_URL" | grep -i "security\|frame\|content-type"
fi

echo "=== Phase 1 완료 ==="
```

### Phase 2 — 1개월 이내

- [ ] GitHub Actions `security-scan.yml` 워크플로우 전체 구축
- [ ] OWASP ZAP 자동 스캔 스테이징 환경 연동
- [ ] Semgrep 규칙 파일 작성 (Next.js, Firebase 특화)
- [ ] 보안 보고서 자동 생성 스크립트 작성
- [ ] Slack `#security-alerts` 채널 연동

### Phase 3 — 3개월 이내

- [ ] nuclei 커스텀 템플릿 작성 (Firebase 특화 5개 이상)
- [ ] 보안 메트릭 수집기 구현 및 Grafana 대시보드 구축
- [ ] 정기 스캔 자동화 완성 (cron 기반 일간/주간/월간)
- [ ] 취약점 추적 DB 구축 (PostgreSQL 또는 GitHub Issues 연동)
- [ ] MTTR 지표 추적 시작

### Phase 4 — 6개월 이내

- [ ] AI 기반 보안 테스트 도입 검토 — PentAGI 패턴 적용
  - Adviser 에이전트 패턴으로 취약점 우선순위 자동 분류
  - pgvector 기반 보안 지식 베이스 구축 (과거 취약점 DB)
  - 반복 감지기 패턴으로 중복 보고서 필터링
- [ ] 보안 지식 베이스 구축 (팀 내 발견 취약점 가이드 누적)
- [ ] 전체 파이프라인 성숙도 평가 (OWASP SAMM 기준)
- [ ] 외부 침투 테스트 업체 연계 검토

---

## 참고 자료

- PentAGI 소스코드: `/home/jay/.cokacdir/workspace/214D5DB3/pentagi`
  - 에이전트 반복 제어: `backend/pkg/providers/performer.go`
  - 반복 감지기: `backend/pkg/providers/helpers.go`
  - pgvector 메모리: `backend/pkg/tools/memory.go`, `guide.go`
  - Docker 샌드박스: `backend/pkg/docker/client.go`
  - 관측가능성 스택: `docker-compose-observability.yml`
- OWASP SAMM (Software Assurance Maturity Model): https://owaspsamm.org
- Semgrep 규칙 레지스트리: https://semgrep.dev/r
- nuclei 템플릿: https://github.com/projectdiscovery/nuclei-templates
