보안 사고 대응에서 가장 먼저 던지는 질문은 거의 언제나 같습니다. "누가 이걸 했고, 언제 했는가?" 애플리케이션 로그만으로는 이 질문에 답하기 어렵습니다. 클라우드 환경에서는 IAM 사용자·역할·서비스가 수많은 AWS API를 직접 호출하면서 리소스 자체가 변형되기 때문입니다.
AWS는 이 간극을 메우기 위해 CloudTrail이라는 별도 로그 계층을 둡니다. IAM 권한이 "누가 무엇을 할 수 있는가"를 정의한다면, CloudTrail은 "실제로 무엇을 했는가"를 기록합니다. CloudTrail이 충분히 켜져 있지 않으면 유출된 액세스 키의 이동 경로, 느슨해진 버킷 정책, 권한 상승 경로를 추적할 수 없습니다. 사고가 터진 뒤 "로그가 없다"는 결론만 얻는다면, 그 시점부터 할 수 있는 일은 추측뿐입니다.
CloudTrail의 뼈대는 세 가지 이벤트 타입과 Trail이라는 파이프라인입니다.
Management Events는 리소스 생성·삭제·권한 변경 같은 컨트롤 플레인(Control Plane) 행위를 기록합니다.
ConsoleLogin이나 AttachRolePolicy가 여기 해당하며, 기본 ON입니다.
Read-only·Write-only를 분리할 수 있고, 호출량이 폭발하기 쉬운 KMS와 RDS Data API 이벤트는 선택적으로 제외할 수 있습니다.
Data Events는 S3 객체의 GetObject·PutObject, Lambda 함수의 Invoke 같은 데이터 플레인(Data Plane) 행위를 기록합니다.
공식 문서는 "trails와 event data stores는 기본적으로 management events만 기록하고 data·Insights events는 기록하지 않는다"고 명시합니다.
즉 "그 민감한 파일을 누가 읽어 갔는가"라는 질문은 Data Events 없이는 답할 수 없습니다. 그런데 이것이 기본 OFF이므로, 리소스 타입별로 명시적으로 등록해야 비로소 기록이 시작됩니다. 과금 대상이기 때문에 비용과 커버리지 사이의 절충이 실무의 고민입니다.
Insights Events는 API 호출률·오류율이 평소 패턴과 크게 달라질 때 자동으로 남는 보조 이벤트입니다. 기본 OFF이며 사후 분석 보조용입니다.
이 이벤트들을 받아 S3로 흘려보내는 파이프라인이 Trail입니다. 단일 리전, 멀티 리전, 그리고 가장 중요한 Organization Trail이 있습니다.
Organization Trail은 AWS Organizations 관리 계정이나 위임 관리자만 생성·변경할 수 있고, 멤버 계정은 이를 삭제하거나 로깅을 끌 수 없습니다. 다계정 환경에서 무결한 단일 감사 출처를 만들 때 이 특성이 핵심입니다.
실무에서는 네 가지 결정이 보안 수준을 좌우합니다.
첫째, Data Events의 선별 활성화입니다.
기본 OFF이므로 민감한 S3 버킷과 Lambda에 명시적으로 켜야 "누가 어떤 객체를 읽었는가"가 기록됩니다. 모든 리소스에 켜면 비용이 빠르게 누적되므로, advanced event selectors로 리소스 ARN 범위를 좁히고 민감도·규제 대상·외부 공개 여부를 기준으로 선별합니다. Read/Write를 분리해 Write부터 먼저 켜는 점진적 전략도 유효합니다.
둘째, 저장과 보존 설계입니다.
콘솔의 Event history는 과거 90일의 Management Events만 조회할 수 있고, Data·Insights·Network activity events는 포함되지 않습니다. 계정 생성 시 Trail이 자동으로 만들어지지도 않습니다. 장기 보존이 필요하면 Trail을 명시적으로 만들어 S3로 영속 저장하고, 수명 주기 정책으로 비용을 제어합니다.
셋째, 다계정 거버넌스입니다.
계정별로 Trail을 따로 켜면 수집·검색이 분산됩니다. Organization Trail 하나로 중앙 수집을 구성하고, 로그 저장 전용 계정에 S3 버킷을 두어 보안 계정에는 읽기 권한만 부여하는 구조가 모범 사례입니다. 버킷 정책에는 aws:SourceArn 조건으로 특정 Trail ARN만 쓰도록 제한하고, AWSCloudTrail_FullAccess 같은 강한 권한은 최소한의 관리자에게만 남깁니다.
넷째, 검색 방법의 현실입니다.
실제 조사에서는 Event history 콘솔이 아니라, S3에 쌓인 JSON 로그를 쿼리 엔진으로 분석하는 구조가 일반적입니다.
첫째, 지연 시간입니다.
공식 문서는 "CloudTrail은 일반적으로 API 호출 후 평균 약 5분 이내에 로그를 전달하지만 이 시간은 보장되지 않는다"고 명시합니다. Insights Events는 이상 감지 후 약 30분 내에 전달되며, 최초 활성화 시 첫 Insights Events까지 최대 36시간이 걸릴 수 있습니다. CloudTrail은 본질적으로 사후 조사 도구입니다.
둘째, 기록되지 않는 영역입니다.
공식 근거가 명확한 것은 세 가지입니다.
(1) Data Events가 기본 OFF이므로 명시적으로 켜지 않은 리소스의 데이터 플레인 호출은 아예 남지 않습니다.
(2) preview 상태거나 public API가 없는 CloudTrail 미지원 서비스가 존재합니다.
(3) KMS·RDS Data API 이벤트는 의도적으로 제외할 수 있습니다.
핵심: "CloudTrail에 없다"를 "일어나지 않았다"로 해석하지 않는 태도가 중요합니다.
셋째, 비용의 함정입니다.
Management Events는 첫 복사본 1건이 무료지만, Data Events는 전달 건수 기준 대략 100,000건당 $0.10 수준이 과금됩니다.
무분별하게 켜면 저장·조회 비용이 빠르게 누적됩니다. 정확한 단가는 공식 pricing 페이지에서 확인해야 합니다.
넷째, 무결성 보장의 구조입니다.
Log file integrity validation은 SHA-256 해시와 SHA-256 with RSA 디지털 서명으로 매 시간 digest file을 만들고, 각 digest가 이전 digest의 서명을 포함하는 해시 체인으로 연결됩니다. 중간 로그 파일을 바꾸면 체인이 깨져 변조가 탐지되므로, 컴플라이언스 환경에서는 이 옵션을 반드시 켭니다.
결국 CloudTrail의 본질은 로그를 켜는 일이 아니라, 사고 시점에 답할 수 있는 질문의 범위를 미리 설계하는 일입니다.