> ## Documentation Index
> Fetch the complete documentation index at: https://docs.sajuapi.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# 감사 로그

> 모든 API 접근 기록 추적 및 컴플라이언스

## 개요

감사 로그는 API에 대한 모든 접근과 작업을 기록합니다.
보안 감사, 규정 준수, 문제 해결에 필수적인 기능입니다.

<Note>
  감사 로그는 Pro 플랜 이상에서 사용 가능합니다.
  Enterprise 플랜에서는 무제한 보관됩니다.
</Note>

***

## 기록되는 이벤트

### 프로필 이벤트

| 액션                 | 설명         | 트리거                            |
| ------------------ | ---------- | ------------------------------ |
| `profile.created`  | 프로필 생성     | POST /v1/profiles              |
| `profile.read`     | 프로필 조회     | GET /v1/profiles/{id}          |
| `profile.updated`  | 프로필 수정     | PUT /v1/profiles/{id}          |
| `profile.deleted`  | 프로필 삭제     | DELETE /v1/profiles/{id}       |
| `profile.unmasked` | 프로필 복호화 조회 | GET /v1/profiles/{id}/unmasked |

### 운세 이벤트

| 액션                  | 설명        | 트리거                            |
| ------------------- | --------- | ------------------------------ |
| `fortune.generated` | 운세 생성     | POST /v1/fortunes              |
| `fortune.read`      | 운세 조회     | GET /v1/fortunes/{id}          |
| `fortune.deleted`   | 운세 삭제     | DELETE /v1/fortunes/{id}       |
| `fortune.unmasked`  | 운세 복호화 조회 | GET /v1/fortunes/{id}/unmasked |
| `fortune.batch`     | 배치 운세 생성  | POST /v1/fortunes/batch        |

### 시스템 이벤트

| 액션                    | 설명       | 트리거                      |
| --------------------- | -------- | ------------------------ |
| `webhook.created`     | 웹훅 등록    | POST /v1/webhooks        |
| `webhook.deleted`     | 웹훅 삭제    | DELETE /v1/webhooks/{id} |
| `api_key.created`     | API 키 생성 | 대시보드                     |
| `api_key.revoked`     | API 키 폐기 | 대시보드                     |
| `rate_limit.exceeded` | 요청 한도 초과 | 429 응답 시                 |

***

## 로그 구조

```json theme={null}
{
  "id": "log_abc123def456",
  "action": "profile.unmasked",
  "resource_type": "profile",
  "resource_id": "prf_xyz789",
  "actor": {
    "type": "api_key",
    "id": "key_abc123",
    "name": "Production API Key",
    "masked_key": "bs_live_xxx..."
  },
  "request": {
    "id": "req_abc123",
    "method": "GET",
    "path": "/v1/profiles/prf_xyz789/unmasked",
    "ip": "203.0.113.42",
    "user_agent": "Mozilla/5.0...",
    "country": "KR"
  },
  "response": {
    "status": 200,
    "latency_ms": 45
  },
  "metadata": {
    "reason": "고객 문의 대응",
    "ticket_id": "SUPPORT-1234"
  },
  "created_at": "2025-01-15T09:30:00Z"
}
```

***

## 로그 조회

### 기본 조회

```bash theme={null}
curl "https://api.sajuapi.dev/v1/reports/audit" \
  -H "X-API-Key: bs_live_xxx"
```

### 필터링

```bash theme={null}
# 특정 액션만 조회
curl "https://api.sajuapi.dev/v1/reports/audit?action=profile.unmasked"

# 특정 리소스 조회
curl "https://api.sajuapi.dev/v1/reports/audit?resource_id=prf_abc123"

# 특정 IP 조회
curl "https://api.sajuapi.dev/v1/reports/audit?actor_ip=203.0.113.42"

# 날짜 범위 조회
curl "https://api.sajuapi.dev/v1/reports/audit?date_from=2025-01-01&date_to=2025-01-15"

# 복합 필터
curl "https://api.sajuapi.dev/v1/reports/audit?action=profile.unmasked&date_from=2025-01-15"
```

### 응답 예시

```json theme={null}
{
  "data": [
    {
      "id": "log_abc123",
      "action": "profile.unmasked",
      "resource_type": "profile",
      "resource_id": "prf_xyz789",
      "actor": {
        "masked_key": "bs_live_xxx...",
        "ip": "203.0.113.42"
      },
      "created_at": "2025-01-15T09:30:00Z"
    }
  ],
  "pagination": {
    "next_cursor": "eyJpZCI6ImxvZ19hYmMxMjMifQ",
    "has_more": true
  },
  "summary": {
    "total_in_period": 1250,
    "by_action": {
      "profile.unmasked": 150,
      "fortune.unmasked": 100,
      "profile.created": 500,
      "fortune.generated": 500
    }
  }
}
```

***

## 실시간 모니터링

### Server-Sent Events (SSE)

실시간으로 감사 로그를 수신할 수 있습니다:

```javascript theme={null}
const eventSource = new EventSource(
  'https://api.sajuapi.dev/v1/events?type=audit',
  {
    headers: { 'X-API-Key': API_KEY }
  }
);

eventSource.addEventListener('audit', (event) => {
  const log = JSON.parse(event.data);
  console.log('새 감사 로그:', log);

  // 복호화 접근 알림
  if (log.action.includes('unmasked')) {
    sendAlert(`복호화 접근: ${log.resource_id} by ${log.actor.ip}`);
  }
});
```

### 웹훅 알림

특정 감사 이벤트를 웹훅으로 받을 수 있습니다:

```bash theme={null}
curl -X POST https://api.sajuapi.dev/v1/webhooks \
  -H "X-API-Key: bs_live_xxx" \
  -d '{
    "url": "https://your-app.com/webhooks/audit",
    "events": ["unmasked.accessed"]
  }'
```

***

## 데이터 내보내기

### CSV 내보내기

```bash theme={null}
curl "https://api.sajuapi.dev/v1/reports/audit?format=csv&date_from=2025-01-01" \
  -H "X-API-Key: bs_live_xxx" \
  -o audit_logs.csv
```

### JSON Lines 내보내기

대용량 데이터의 경우 JSON Lines 형식을 권장합니다:

```bash theme={null}
curl "https://api.sajuapi.dev/v1/reports/audit?format=jsonl" \
  -H "X-API-Key: bs_live_xxx" \
  -o audit_logs.jsonl
```

***

## 보관 정책

| 플랜         | 보관 기간 | 내보내기             |
| ---------- | ----- | ---------------- |
| Pro        | 30일   | CSV, JSON        |
| Enterprise | 무제한   | CSV, JSON, JSONL |

<Note>
  보관 기간이 지난 로그는 자동으로 삭제됩니다.
  규정 준수를 위해 정기적으로 내보내기를 수행하세요.
</Note>

***

## 분석 대시보드 구축

### 일별 접근 통계

```sql theme={null}
-- 감사 로그 분석 쿼리 예시
SELECT
  DATE(created_at) as date,
  action,
  COUNT(*) as count
FROM audit_logs
WHERE created_at >= NOW() - INTERVAL '30 days'
GROUP BY DATE(created_at), action
ORDER BY date DESC, count DESC;
```

### 이상 징후 탐지

```python theme={null}
import pandas as pd
from datetime import datetime, timedelta

def detect_anomalies(logs):
    """비정상적인 복호화 접근 패턴 탐지"""

    df = pd.DataFrame(logs)

    # 시간당 복호화 요청 수
    df['hour'] = pd.to_datetime(df['created_at']).dt.hour
    hourly_counts = df[df['action'].str.contains('unmasked')].groupby('hour').size()

    # 평균 대비 3배 이상이면 알림
    mean = hourly_counts.mean()
    anomalies = hourly_counts[hourly_counts > mean * 3]

    return anomalies

# 알림 전송
anomalies = detect_anomalies(audit_logs)
if not anomalies.empty:
    send_alert(f"비정상 접근 패턴 감지: {anomalies.to_dict()}")
```

***

## 규정 준수 리포트

### 정기 감사 리포트 생성

```bash theme={null}
# 월간 복호화 접근 리포트
curl "https://api.sajuapi.dev/v1/reports/audit/summary?period=month&action=unmasked" \
  -H "X-API-Key: bs_live_xxx"
```

### 응답 예시

```json theme={null}
{
  "period": "2025-01",
  "summary": {
    "total_unmasked_requests": 250,
    "unique_resources_accessed": 180,
    "unique_actors": 5,
    "by_actor": {
      "bs_live_xxx...": 150,
      "bs_live_yyy...": 80,
      "bs_live_zzz...": 20
    },
    "by_resource_type": {
      "profile": 150,
      "fortune": 100
    },
    "top_accessed_resources": [
      { "id": "prf_abc123", "count": 15 },
      { "id": "prf_def456", "count": 12 }
    ]
  }
}
```

***

## FAQ

<Accordion title="감사 로그가 성능에 영향을 주나요?">
  아니요, 감사 로그는 비동기로 기록되어 API 응답 시간에 영향을 주지 않습니다.
</Accordion>

<Accordion title="로그를 수정하거나 삭제할 수 있나요?">
  아니요, 감사 로그는 불변(immutable)입니다. 무결성 보장을 위해 수정이나 삭제가 불가능합니다.
</Accordion>

<Accordion title="로그에 민감한 데이터가 포함되나요?">
  아니요, 감사 로그에는 요청/응답 본문이 포함되지 않습니다.
  리소스 ID와 메타데이터만 기록됩니다.
</Accordion>
