Audit logs API
Document Management SDK의 Audit Logs는 Document Governance SDK 연동 구조로 파일·사용자·관리 활동을 수집·저장하고 조회하도록 구현한 사례입니다. Storage와 Editor의 활동을 하나의 증적 기록으로 연결하는 구조는 Governance Integration에서 확인할 수 있습니다.
tenant의 감사 기록을 조회하는 읽기 전용 endpoint 두 개를 제공합니다. 하나는 페이지 단위로 조회하고, 다른 하나는 지정한 기간 전체를 CSV 파일로 내보냅니다.
Base URL과 접근 권한
/api/external/v1/admins/audit-logs
이 endpoint를 호출하려면 ADMIN 역할의 계정으로 발급된 API Key가 필요합니다. 접근 권한은 역할로만 결정되며 키의
scope는 검사하지 않습니다. 두 endpoint 모두 읽기 전용이므로 api:read만 부여된 키와 api:write가 부여된 키의
동작은 같습니다.
조회할 tenant는 호출한 키를 기준으로 서버가 결정하며, 다른 tenant를 지정하는 요청 파라미터는 없습니다. tenant는
요청한 host로 판단하므로 키를 발급받은 tenant의 도메인으로 호출해야 합니다. 다른 도메인으로 호출하면
API_KEY_004로 실패합니다.
governance.audit.enabled=false로 설정된 환경에서는 이 endpoint가 등록되지 않으므로 모든 요청이 404로 응답합니다.
이 경우 404는 경로가 잘못되었다는 뜻이 아니라 감사 기능이 꺼져 있다는 뜻입니다.
데이터 저장 위치
감사 이벤트는 Drive 데이터베이스가 아니라 거버넌스 서버에 저장되며, Drive가 거버넌스 서버의 조회 API로 요청을 전달합니다. 거버넌스 서버 인증은 Drive 서버에서 처리하므로 호출하는 쪽에서는 Drive API Key만 있으면 됩니다.
이 구조 때문에 거버넌스 서버가 지원하지 않는 필터 값을 보내면 400이 아니라 500으로 응답합니다. 거버넌스 서버는 해당
요청을 400으로 거부하지만 Drive가 이를 RESPONSE_001로 반환합니다. 필터에는 아래에 나열된 값만 사용하세요.
필터 값
eventCategory
| 값 | 포함 범위 |
|---|---|
LOGIN | 로그인, 로그아웃, 계정 잠금 상태 |
FILE_FOLDER | 파일과 폴더 작업 |
SHARE | 공유 |
USER_MANAGEMENT | 사용자와 관리자 계정 관리 |
SETTING | 환경 설정 변경 |
eventCategory에는 값을 하나만 지정두 개 이상 지정하면 오류 없이 200과 함께 0건을 반환하므로, 해당 이벤트가 없는 경우와 구분할 수 없습니다. 예를 들어
eventCategory=LOGIN&eventCategory=SHARE로 요청하면 totalCount가 0으로 반환됩니다. 여러 카테고리를 함께
조회하려면 각 카테고리에 속한 이벤트 종류를 eventTypes로 지정하세요.
channel
| 값 | 포함 범위 |
|---|---|
WEB | 웹 화면 |
API | 외부 API |
MCP | MCP |
SYSTEM | 사용자 요청 없이 시스템에서 발생한 이벤트 |
outcomeStatus
| 값 | 포함 범위 |
|---|---|
SUCCESS | 작업 성공 |
FAIL | 작업 실패 |
eventType
41개 값이 있으며, 각 값은 하나의 카테고리에 속합니다.
| 카테고리 | 종류 |
|---|---|
LOGIN | LOGIN, LOGOUT, ACCOUNT_LOCKED_STATUS_CHANGE |
FILE_FOLDER | FILE_CREATE, FILE_UPLOAD, FILE_DOWNLOAD, FILE_PREVIEW, FILE_OPEN, FILE_EDIT, FILE_DELETE, FILE_PERMANENT_DELETE, FILE_RESTORE, FILE_RENAME, FILE_MOVE, FILE_COPY, FOLDER_CREATE, FOLDER_DOWNLOAD, FOLDER_DELETE, FOLDER_PERMANENT_DELETE, FOLDER_RESTORE, FOLDER_RENAME |
SHARE | SHARE_CREATE, SHARE_PERMISSION_CHANGE, SHARE_REMOVE |
USER_MANAGEMENT | USER_CREATE, USER_DELETE, USER_PERMANENT_DELETE, USER_RESTORE, USER_INFO_UPDATE, USER_TWOFACTOR_RESET, USER_PASSWORD_CHANGE, USER_STATUS_CHANGE, ADMIN_CREATE, ADMIN_DELETE, ADMIN_PERMANENT_DELETE, ADMIN_RESTORE, ADMIN_INFO_UPDATE, ADMIN_PASSWORD_CHANGE, ADMIN_STATUS_CHANGE |
SETTING | SETTING_UPDATE, SETTING_ALLOWED_IP_CHANGE |
로그인 성공과 실패는 모두 LOGIN으로 기록되며, outcomeStatus로 구분합니다. 로그아웃은 별도의 LOGOUT으로
기록됩니다. 따라서 LOGIN으로 필터링하면 성공과 실패가 함께 조회됩니다.
날짜
요청의 날짜 형식은 yyyy-MM-dd입니다. 조회 기간은 from 당일 00:00부터 to 다음 날 00:00 전까지이므로 종료일도
결과에 포함됩니다. 응답의 시각은 Asia/Seoul 기준 yyyy-MM-dd HH:mm:ss.SSS 형식입니다.
감사 이벤트 목록 조회
GET /api/external/v1/admins/audit-logs
호출한 키가 속한 tenant의 감사 이벤트를 페이지 번호 방식으로 조회합니다. 결과는 항상 occurredAt 내림차순으로
정렬되며, 정렬 파라미터는 없습니다.
| 파라미터 | 타입 | 필수 | 설명 |
|---|---|---|---|
pi | integer | Yes | 페이지 번호, 1부터 |
ps | integer | Yes | 페이지 크기, 1~200. 200보다 큰 값은 200으로 적용됨 |
actorEmail | string | No | 작업한 사용자의 이메일. 정확히 일치하는 값만 조회하며 부분 검색은 지원하지 않음 |
from | string | No | 시작일, 당일 포함 |
to | string | No | 종료일, 당일 포함 |
eventCategory | string | No | 카테고리 값 하나 |
eventTypes | string[] | No | 이벤트 종류. 값마다 파라미터를 반복해서 전송 |
channel | string | No | WEB, API, MCP, SYSTEM 중 하나 |
outcomeStatus | string | No | SUCCESS 또는 FAIL |
eventTypes는 쉼표로 연결하지 않고 eventTypes=FILE_RENAME&eventTypes=FILE_MOVE처럼 반복해서 보냅니다. 개수 제한은
없지만 요청 URL 길이의 제한을 받으며, 기본 웹 서버 설정에서는 8 KB입니다.
curl -X GET "https://drive.example.com/api/external/v1/admins/audit-logs?pi=1&ps=20&from=2026-09-01&to=2026-09-14&eventCategory=FILE_FOLDER&eventTypes=FILE_RENAME&eventTypes=FILE_MOVE" \
-H "Authorization: Bearer replace-with-your-TENANTADMIN-API-KEY" \
-H "Content-Type: application/json"
{
"result": true,
"code": 200,
"data": [
{
"eventId": "019b2f58-7f3a-7c21-8e90-4c1f2f2e7840",
"occurredAt": "2026-09-14 14:11:03.510",
"eventType": "FILE_RENAME",
"eventCategory": "FILE_FOLDER",
"actorType": "HUMAN",
"actorName": "First user",
"actorEmail": "user1@example.com",
"objectType": "FILE",
"objectName": "Proposal.pptx",
"objectEmail": null,
"objectPath": "MY/Sales/2026",
"outcomeStatus": "SUCCESS",
"outcomeCode": null,
"channel": "WEB",
"clientIp": "198.51.100.20",
"tenantSeq": "3",
"tenantName": "Example tenant",
"change": {
"before": "Proposal_draft.pptx",
"after": "Proposal.pptx"
},
"targets": null
}
],
"totalCount": 1234,
"pageIndex": 1,
"pageSize": 20
}
목록 응답에는 message가 없습니다. 페이지 정보는 totalCount, pageIndex, pageSize로 반환됩니다.
| 필드 | 타입 | 설명 |
|---|---|---|
eventId | string | 거버넌스 서버가 발급한 이벤트 식별자 |
occurredAt | string | 발생 시각 |
eventType | string | 이벤트 종류. eventTypes 필터에 사용하는 값 |
eventCategory | string | 이벤트 종류가 속한 카테고리 |
actorType | string | 작업 주체 유형. HUMAN |
actorName | string | 작업한 사용자의 표시 이름 |
actorEmail | string | 작업한 사용자의 이메일. Drive 계정 id와 같은 값 |
objectType | string | 대상 유형: FILE, FOLDER, USER, SETTING |
objectName | string | 대상 이름 - 파일·폴더 이름, 계정 이름 등 |
objectEmail | string | 대상 계정의 이메일. 대상이 계정일 때만 값이 있고, 그 외에는 null |
objectPath | string | 부모 폴더 기준 대상 경로. 첫 번째 항목은 위치 코드이며 MY는 내 드라이브, SHARE는 공유 문서함 |
outcomeStatus | string | SUCCESS 또는 FAIL |
outcomeCode | string | 실패 사유 코드. 실패한 이벤트에만 값이 있고, 그 외에는 null |
channel | string | 요청 경로 |
clientIp | string | 요청한 클라이언트의 IP |
tenantSeq | string | tenant 식별자. 거버넌스 서버의 scope id |
tenantName | string | tenant 이름. 거버넌스 서버의 scope 이름 |
change | object | 변경 전후 값을 담은 {before, after, summary}. 값이 변경되는 이벤트에만 포함 |
targets | object[] | 공유 대상 등 대상 목록. 해당하는 이벤트에만 포함 |
{
"result": false,
"code": 400,
"errorCode": "REQUEST_001",
"message": "[{msg=must not be null, field=pi}]"
}
감사 이벤트 CSV 내보내기
GET /api/external/v1/admins/audit-logs/export
조건에 맞는 기간 전체의 감사 이벤트를 CSV 파일로 내려받습니다. 목록 조회와 같은 필터를 사용하지만 페이지 파라미터는 받지 않으며, 응답 본문은 JSON 공통 구조가 없는 CSV입니다.
| 파라미터 | 타입 | 필수 | 설명 |
|---|---|---|---|
from | string | No | 시작일, 당일 포함. 생략하면 to의 92일 전 |
to | string | No | 종료일, 당일 포함. 생략하면 현재 시각 |
actorEmail | string | No | 작업한 사용자의 이메일. 정확히 일치하는 값만 조회 |
eventCategory | string | No | 카테고리 값 하나 |
eventTypes | string[] | No | 이벤트 종류. 값마다 파라미터를 반복해서 전송 |
channel | string | No | WEB, API, MCP, SYSTEM 중 하나 |
outcomeStatus | string | No | SUCCESS 또는 FAIL |
한 번에 조회할 수 있는 기간은 최대 92일입니다. 두 날짜를 모두 생략하면 최근 92일을 조회하며, 92일보다 긴 기간은 400으로 거부됩니다. 한 분기는 89~92일이므로 어떤 3개월 기간이든 한 번에 조회할 수 있습니다. 더 긴 기간이 필요하면 기간을 나누어 여러 번 호출하세요.
이 endpoint는 pi와 ps를 사용하지 않으며, 보내도 무시합니다. 응답에는 한 페이지가 아니라 지정한 기간 전체가
포함됩니다.
curl -X GET "https://drive.example.com/api/external/v1/admins/audit-logs/export?from=2026-06-01&to=2026-09-01&eventCategory=SHARE" \
-H "Authorization: Bearer replace-with-your-TENANTADMIN-API-KEY" \
-o audit-events.csv
| 응답 헤더 | 값 |
|---|---|
Content-Type | text/csv |
Content-Disposition | attachment; filename*=UTF-8''audit-events_20260601-20260901.csv |
Content-Length | 없음 - 본문을 나누어 전송하므로 전체 크기를 미리 알 수 없음 |
파일 이름은 audit-events_{from}-{to}.csv 형식입니다.
schemaVersion,eventId,eventType,sourceEventType,occurredAt,origin.system,…,observedIp,ingestKeyId
1.0,019b2f58-7f3a-7c21-8e90-4c1f2f2e7840,FILE_RENAME,FILE_RENAME,2026-07-16T05:11:03.510Z,TFD,…,198.51.100.20,key-acme-01
파일 형식은 거버넌스 서버가 생성한 형식을 그대로 따릅니다. BOM이 포함된 UTF-8, CRLF 줄바꿈, RFC 4180 따옴표 규칙을 사용하며, 열은 44개이고 열 순서도 고정되어 있습니다. 수식으로 해석될 수 있는 값 앞에는 작은따옴표를 붙입니다. 목록 조회 응답보다 열이 많습니다.
{
"result": false,
"code": 400,
"message": "감사 로그 내보내기 기간은 최대 92일입니다."
}
내보내기 실패 응답은 공통 실패 구조를 사용하지만 errorCode가 없습니다.
응답은 여러 부분으로 나누어 전송됩니다. 첫 부분을 전송할 때 이미 200을 반환했으므로, 이후에 발생한 실패는 응답이 중간에 끊기는 형태로만 나타납니다. HTTP 규격을 따르는 클라이언트는 마지막 부분을 받지 못하면 오류로 처리하고 잘린 파일을 사용하지 않습니다. 다만 받은 파일이 완전한지는 클라이언트에서 확인해야 합니다.
긴 기간을 내보낼 때는 응답을 스트리밍 방식으로 파일에 저장하세요. 한 행은 약 1,450바이트이므로 10만 행이면 약
138 MB입니다. 브라우저 Blob이나 문자열 변환처럼 응답 전체를 메모리에 올리는 방식은 기간이 길면 실패할 수 있습니다.
curl -o나 스트림 복사로 파일에 바로 저장하는 방식을 권장합니다.
동시에 실행할 수 있는 내보내기는 서버 인스턴스당 10건이며, tenant와 관계없이 합산합니다. 11번째 요청부터 429를 반환하며, 목록 조회에는 영향을 주지 않습니다. 429를 받으면 안전하게 다시 요청할 수 있습니다.
{
"result": false,
"code": 429,
"message": "다른 내보내기가 진행 중입니다. 잠시 뒤 다시 시도해 주세요."
}
오류
| 코드 | 상태 | 의미 |
|---|---|---|
API_KEY_004 | 401 | 인증 실패 - 헤더 누락, 등록되지 않은 값, 비활성화되거나 만료된 키, 비활성화된 계정, 다른 tenant의 도메인 |
AUTH_009 | 403 | 호출한 키가 ADMIN 역할이 아님 |
REQUEST_001 | 400 | 검증 실패. message에 검증에 실패한 필드가 포함됨. pi나 ps 누락, 1 미만의 값 등 |
RESPONSE_001 | 500 | 감사 이벤트 조회 실패. 지원하지 않는 필터 값을 보낸 경우 포함 |
API가 반환하는 전체 오류 코드는 Errors를 참고하세요.