> ## 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.

# 감사 로그 조회

<Info>
  **v1 Enterprise API (Coming Soon)**

  이 엔드포인트는 Enterprise 버전에서 제공될 예정입니다.
  현재는 [v0 API](/api-reference/v0/overview)를 사용하세요.
</Info>

감사 로그를 조회합니다. 민감한 데이터 접근, 삭제 작업 등 보안 관련 활동을 확인할 수 있습니다.

<Note>
  감사 로그는 개인정보보호법 및 기업 컴플라이언스 준수를 위해 제공됩니다. 모든 복호화 요청, 삭제 작업이 자동으로 기록됩니다.
</Note>

***

## Query 파라미터

<ParamField query="action" type="string">
  특정 액션으로 필터링합니다. `profile.unmasked`, `fortune.unmasked`, `profile.deleted`, `fortune.deleted` 등입니다.
</ParamField>

<ParamField query="resource_type" type="string">
  리소스 타입으로 필터링합니다. `profile`, `fortune`, `webhook` 중 하나입니다.
</ParamField>

<ParamField query="resource_id" type="string">
  특정 리소스 ID로 필터링합니다.
</ParamField>

<ParamField query="actor_ip" type="string">
  특정 IP 주소로 필터링합니다.
</ParamField>

<ParamField query="start_date" type="string">
  조회 시작 날짜입니다. ISO 8601 형식입니다.
</ParamField>

<ParamField query="end_date" type="string">
  조회 종료 날짜입니다. ISO 8601 형식입니다.
</ParamField>

<ParamField query="limit" type="integer" default="50">
  한 페이지에 반환할 로그 수입니다. 최대 1000입니다.
</ParamField>

<ParamField query="cursor" type="string">
  다음 페이지를 조회하기 위한 커서입니다.
</ParamField>

***

## Response

### 성공

감사 로그 조회에 성공하면 AuditLog 배열이 반환됩니다.

### 실패

| 상태 코드 | 에러 타입                  | 설명              |
| ----- | ---------------------- | --------------- |
| 401   | `authentication_error` | API 키가 유효하지 않음  |
| 403   | `forbidden`            | 감사 로그 조회 권한이 없음 |
| 429   | `rate_limited`         | 요청 한도 초과        |

***

## 요청 예시

<CodeGroup>
  ```bash cURL theme={null}
  # 전체 감사 로그 조회
  curl -X GET "https://api.sajuapi.dev/v1/reports/audit?limit=100" \
    -H "X-API-Key: bs_live_xxx"

  # 복호화 요청만 조회
  curl -X GET "https://api.sajuapi.dev/v1/reports/audit?action=profile.unmasked" \
    -H "X-API-Key: bs_live_xxx"

  # 특정 프로필 관련 로그 조회
  curl -X GET "https://api.sajuapi.dev/v1/reports/audit?resource_id=prf_abc123def456" \
    -H "X-API-Key: bs_live_xxx"
  ```

  ```javascript JavaScript theme={null}
  // 전체 감사 로그 조회
  const response = await fetch(
    'https://api.sajuapi.dev/v1/reports/audit?limit=100',
    {
      headers: {
        'X-API-Key': 'bs_live_xxx'
      }
    }
  );

  const { data, has_more, next_cursor } = await response.json();

  // 복호화 요청만 조회
  const unmaskedLogs = await fetch(
    'https://api.sajuapi.dev/v1/reports/audit?action=profile.unmasked',
    {
      headers: { 'X-API-Key': 'bs_live_xxx' }
    }
  ).then(r => r.json());
  ```

  ```python Python theme={null}
  import requests

  # 전체 감사 로그 조회
  response = requests.get(
      'https://api.sajuapi.dev/v1/reports/audit',
      headers={'X-API-Key': 'bs_live_xxx'},
      params={'limit': 100}
  )

  result = response.json()
  logs = result['data']

  # 복호화 요청만 조회
  unmasked_response = requests.get(
      'https://api.sajuapi.dev/v1/reports/audit',
      headers={'X-API-Key': 'bs_live_xxx'},
      params={'action': 'profile.unmasked'}
  )
  ```
</CodeGroup>

***

## 응답 예시

```json theme={null}
{
  "data": [
    {
      "id": 12345,
      "action": "profile.unmasked",
      "resource_type": "profile",
      "resource_id": "prf_abc123def456",
      "actor_ip": "203.0.113.42",
      "actor_api_key": "bs_live_xxx...",
      "request_id": "req_xyz789",
      "metadata": {
        "user_agent": "Mozilla/5.0 ...",
        "endpoint": "GET /v1/profiles/prf_abc123def456/unmasked"
      },
      "created_at": "2025-01-16T09:30:00Z"
    },
    {
      "id": 12344,
      "action": "fortune.unmasked",
      "resource_type": "fortune",
      "resource_id": "ftn_xyz789abc123",
      "actor_ip": "203.0.113.42",
      "actor_api_key": "bs_live_xxx...",
      "request_id": "req_abc456",
      "metadata": {
        "profile_id": "prf_abc123def456"
      },
      "created_at": "2025-01-16T09:25:00Z"
    },
    {
      "id": 12343,
      "action": "profile.deleted",
      "resource_type": "profile",
      "resource_id": "prf_def456ghi789",
      "actor_ip": "198.51.100.23",
      "actor_api_key": "bs_live_yyy...",
      "request_id": "req_def789",
      "metadata": {
        "fortunes_deleted": 23,
        "cached_calculations_deleted": 5
      },
      "created_at": "2025-01-16T09:15:00Z"
    }
  ],
  "has_more": true,
  "next_cursor": "eyJpZCI6MTIzNDJ9",
  "total_count": 1523
}
```

***

## AuditLog 객체

| 필드              | 타입      | 설명                    |
| --------------- | ------- | --------------------- |
| `id`            | integer | 로그 ID입니다.             |
| `action`        | string  | 액션 유형입니다.             |
| `resource_type` | string  | 리소스 타입입니다.            |
| `resource_id`   | string  | 리소스 ID입니다.            |
| `actor_ip`      | string  | 요청자 IP 주소입니다.         |
| `actor_api_key` | string  | 사용된 API 키 (앞 20자)입니다. |
| `request_id`    | string  | 요청 ID입니다.             |
| `metadata`      | object  | 추가 메타데이터입니다.          |
| `created_at`    | string  | 로그 생성 시간입니다.          |

***

## 액션 유형

| 액션                 | 설명         |
| ------------------ | ---------- |
| `profile.created`  | 프로필 생성     |
| `profile.updated`  | 프로필 수정     |
| `profile.deleted`  | 프로필 삭제     |
| `profile.unmasked` | 프로필 복호화 조회 |
| `fortune.created`  | 운세 생성      |
| `fortune.deleted`  | 운세 삭제      |
| `fortune.unmasked` | 운세 복호화 조회  |
| `webhook.created`  | 웹훅 생성      |
| `webhook.deleted`  | 웹훅 삭제      |

***

## 보안 모니터링

비정상적인 복호화 요청 패턴을 모니터링하여 보안 이슈를 조기에 발견하세요.

```javascript theme={null}
// 특정 IP에서의 복호화 요청 빈도 확인
async function checkUnmaskedRequestFrequency(ip, hours = 24) {
  const startDate = new Date();
  startDate.setHours(startDate.getHours() - hours);

  const response = await fetch(
    `/v1/reports/audit?action=profile.unmasked&actor_ip=${ip}&start_date=${startDate.toISOString()}`,
    { headers: { 'X-API-Key': 'bs_live_xxx' } }
  );

  const { total_count } = await response.json();

  if (total_count > 100) {
    console.warn(`경고: IP ${ip}에서 ${hours}시간 동안 ${total_count}건의 복호화 요청`);
  }

  return total_count;
}
```

<Warning>
  감사 로그는 90일간 보관됩니다. 장기 보관이 필요한 경우 주기적으로 데이터를 백업하세요.
</Warning>
