Skip to Content
Software ArchitectureAudit Event 설계: 3단계 진화와 데이터 설계
🏗️ Software Architecture2025년 9월 15일

Audit Event 설계: 3단계 진화와 데이터 설계

#identity-platform#audit-event#architecture#data-design#domain-modeling
Identity Platform · Series 3 · Audit Event Architecture8 / 15Software Architecture
3개 PR, 약 +8,000/-2,800줄 — 데이터 설계를 정의하고, 감사 이벤트를 쌓고, 연결하고, 정리한 6개월.
NSP3는 사내 managed Kafka 플랫폼이다. 각 팀이 Kafka 클러스터를 직접 운영하지 않고, 토픽 생성과 접근 제어를 플랫폼 차원에서 관리해 준다. 이 프로젝트에서는 감사 이벤트의 전송 채널로 활용했다.

왜 한 번에 완성하지 않고 3단계로 나눴나

관리 플랫폼에서 관리자가 수행하는 모든 작업 — 사용자 생성, 역할 할당, 권한 변경, 계정 비활성화 — 은 감사 추적이 필요하다. 하지만 NSP3 연동 방식 자체가 프로젝트 기간 중에 진화했기 때문에 3단계로 나뉘게 되었다.

줄여 말하면, 쌓고(build up), 연결하고(integrate), 정리했다(clean up).

Phase 1이 가장 오래 걸린 이유

Phase 1의 목표는 감사 이벤트의 데이터 모델을 정의하고, 애플리케이션 코드에서 감사 이벤트를 생성하는 구조를 잡는 것이었다. 3단계 중 가장 오래 걸린 것도 이 단계다.

코드를 작성하는 시간보다 필드명과 구조를 정하는 데 걸린 시간이 훨씬 길었다. 이 이벤트 데이터는 사내 보안 플랫폼의 표준 스키마에 맞춰야 했고, 향후 다른 서비스에서도 같은 포맷으로 이벤트를 발행할 수 있도록 확장성을 고려해야 했다. 결국 외부 팀에도 공유될 예정이었기 때문에, 한번 정해진 필드명이나 구조를 나중에 바꾸기가 매우 어렵다.

필드 표준은 한 번 정의되면 변경하기 어렵다. 이미 발행된 이벤트를 소비하는 시스템들이 이 표준에 의존하고 있기 때문이다.

데이터 설계: 누가, 무엇을, 어떻게

감사 이벤트의 핵심 질문은 “누가(Actor), 무엇을(Target), 어떻게(Action) 했는가”이다. 이 세 요소를 표준화하지 않으면 같은 행위를 다른 서비스에서 다르게 기록하는 문제가 발생한다.

이 표준은 이전 글에서 정리한 Role & Access Management 모델 위에서 설계됐다. 도메인 구조를 먼저 이해해야 어떤 행위가 감사 대상인지 정의할 수 있기 때문이다.

ActionType: DOMAIN_ACTION 네이밍 패턴

ActionType은 DOMAIN_ACTION 패턴을 따른다. 예를 들어 ACCOUNT_PASSWORD_RESET에서 ACCOUNT는 도메인이고 PASSWORD_RESET은 행위다.

도메인대표 ActionType 예시
계정ACCOUNT_CREATE, ACCOUNT_DEACTIVATE, ACCOUNT_PASSWORD_RESET
역할ROLE_CREATE, ROLE_UPDATE, ROLE_ASSIGNMENT_CHANGE
접근ACCESS_GRANT, ACCESS_REVOKE
인증AUTH_LOGIN, AUTH_FIRST_LOGIN

단순 CRUD로 분류하지 않은 이유: UPDATE라는 ActionType만으로는 “무엇이 업데이트되었는지” 알 수 없다. ACCOUNT_PASSWORD_RESET은 “사용자의 비밀번호가 초기화되었다”를 즉시 전달한다.

TargetType: 대상 유형 분리

TargetType의미분리 이유
ACCOUNT개별 사용자 계정계정 단위 행위와 조직 단위 행위를 구분
ORGANIZATION소속 조직조직 전체 접근 변경은 영향 범위가 다름
ROLE역할 정의역할 변경은 할당된 모든 사용자에게 영향
ROLE_ASSIGNMENT사용자-역할 매핑특정 사용자에게만 영향
APP_PERMISSION앱별 권한애플리케이션 단위 권한 관리
SETTINGS시스템 설정전역 설정 변경 추적

ActorType: 행위 주체 구분

ActorType설명
INTERNAL_USER사내 직원 (내부 도메인 이메일)
EXTERNAL_USER외부 파트너 사용자
SYSTEM시스템/배치 액터

관리자 행위와 시스템 자동 행위를 구분하는 것은 감사 관점에서 필수다. 보안 감사관이 “시스템이 자동으로 한 것”과 “사람이 직접 한 것”을 구분할 수 있어야 한다.

Phase 2와 3: 연결하고 정리하다

데이터 설계가 정해진 뒤, Phase 2에서는 NSP3에 HTTP로 직접 전송하는 NspHttpPublisher를 구현했다. 이 단계에서 AuditEventPublisher 인터페이스를 분리하는 pluggable architecture가 도입됐다.

Phase 3에서는 HTTP 직접 호출을 AWS SNS 기반 비동기 파이프라인으로 교체했다. 인터페이스가 동일하기 때문에 비즈니스 코드는 한 줄도 수정할 필요가 없었다. 이 두 단계의 상세한 설계 결정은 다음 글에서 다룬다.

기준Phase 1Phase 2Phase 3
우선순위데이터 모델 확립구현 속도재사용성 + 안정성
전송 방식Splunk 검색HTTP IngressSNS 파이프라인
비즈니스 코드 변경이벤트 생성 코드 추가변경 없음변경 없음

핵심 설계 결정: 도메인 이벤트 패턴

비즈니스 로직이 감사 이벤트를 직접 전송하지 않고, 이벤트를 생성하면 별도 계층이 이를 처리했다. 이 분리 덕분에 Phase 2와 3에서 전송 방식이 바뀌어도 비즈니스 코드는 그대로였다.

이벤트 구조: Actor(누가) + Action(무엇을) + Target(대상) + Timestamp(언제) + Context(추가 정보). 이 구조는 이후에도 유지됐다.

필드 표준 설계는 기술적 문제이자 도메인 모델링 문제다. 관리 플랫폼에서 관리자가 수행할 수 있는 모든 행위를 열거하고, 감사 관점에서 어떤 구분이 필요한지 결정하는 과정이 이 데이터 설계의 핵심이었다. ActionType이 늘어나면 소비자 측 매핑도 함께 갱신해야 하고, 도메인 경계가 모호한 행위는 분류가 어려울 수 있으며, 이벤트 스키마 진화 전략(backward compatibility)을 별도로 관리해야 한다.

3개 PR, 약 +8,000 / -2,800줄의 변경이었다. 리뷰 부담이 적지 않았지만, 이 3단계 진화의 핵심은 “감사 이벤트를 어떻게 보내느냐”가 아니라 “전송 방식이 바뀌어도 비즈니스 코드가 흔들리지 않는 구조를 어떻게 만드느냐”에 있었다.

다음 글에서는 pluggable publisher 설계가 실제 아키텍처 전환에서 어떻게 작동했고, 최종적으로 공유 파이프라인으로 어떻게 도달했는지 이어서 본다.

Last updated on