Skip to main content

개요

감사 로그는 API에 대한 모든 접근과 작업을 기록합니다. 보안 감사, 규정 준수, 문제 해결에 필수적인 기능입니다.
감사 로그는 Pro 플랜 이상에서 사용 가능합니다. Enterprise 플랜에서는 무제한 보관됩니다.

기록되는 이벤트

프로필 이벤트

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

운세 이벤트

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

시스템 이벤트

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

로그 구조

{
  "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"
}

로그 조회

기본 조회

curl "https://api.sajuapi.dev/v1/reports/audit" \
  -H "X-API-Key: bs_live_xxx"

필터링

# 특정 액션만 조회
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"

응답 예시

{
  "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)

실시간으로 감사 로그를 수신할 수 있습니다:
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}`);
  }
});

웹훅 알림

특정 감사 이벤트를 웹훅으로 받을 수 있습니다:
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 내보내기

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 형식을 권장합니다:
curl "https://api.sajuapi.dev/v1/reports/audit?format=jsonl" \
  -H "X-API-Key: bs_live_xxx" \
  -o audit_logs.jsonl

보관 정책

플랜보관 기간내보내기
Pro30일CSV, JSON
Enterprise무제한CSV, JSON, JSONL
보관 기간이 지난 로그는 자동으로 삭제됩니다. 규정 준수를 위해 정기적으로 내보내기를 수행하세요.

분석 대시보드 구축

일별 접근 통계

-- 감사 로그 분석 쿼리 예시
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;

이상 징후 탐지

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()}")

규정 준수 리포트

정기 감사 리포트 생성

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

응답 예시

{
  "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

아니요, 감사 로그는 비동기로 기록되어 API 응답 시간에 영향을 주지 않습니다.
아니요, 감사 로그는 불변(immutable)입니다. 무결성 보장을 위해 수정이나 삭제가 불가능합니다.
아니요, 감사 로그에는 요청/응답 본문이 포함되지 않습니다. 리소스 ID와 메타데이터만 기록됩니다.