append-only이고 immutable하게 만들고, 각 항목을 이전 항목에 hash로 연결하여 변조가 탐지되게 하며, 오래된 데이터가 저렴하게 소멸하도록 시간으로 파티셔닝하고, 봉인된 partition을 보존 정책과 함께 WORM object storage(write-once)로 아카이브하십시오 — 라이브 레코드에 UPDATE/DELETE를 절대 허용하지 마십시오.
service ──emit event──▶ append-only writer
│ hash = H(prev_hash || payload)
▼
audit_2026_07 (hot partition) ◀── query by actor/time
│ month sealed
▼
WORM object store (S3 Object Lock) ── retention: 7y
│
periodic anchor: publish latest hash externally
감사 로그의 가치 전부는 나중에 그것을 신뢰할 수 있다는 데 있으므로, 스키마는 변경(mutation)을 금지해야 합니다. 앱에 INSERT만 부여하고 — UPDATE/DELETE 없이 — 코드만이 아니라 DB 역할(role) 수준에서 강제하십시오. 그 위에 hash chain을 구축하십시오: 각 row가 hash = SHA256(prev_hash || this_row)를 저장합니다. 히스토리 row 하나를 바꾸면 이후의 모든 hash가 깨지므로, DB 접근 권한이 있는 사람에게조차 변조가 탐지 가능합니다. 주기적으로 최신 hash를 통제할 수 없는 곳(notary, 공개 원장, 서명된 이메일)에 **앵커(anchor)**하여, 전체 chain을 다시 쓰는 관리자조차 앵커된 값과 일치시킬 수 없게 하십시오.
수년치 로그는 무한히 증가하므로 시간으로 파티셔닝하십시오(예: 월별 range partition). 이점: 쿼리가 partition으로 필터링되고, 오래된 데이터 폐기는 메타데이터 DETACH/DROP PARTITION입니다 — 테이블을 부풀리는 거대한 DELETE가 아니라 즉각적입니다. 봉인된 partition은 WORM storage로 이동합니다 — compliance mode의 S3 Object Lock은 보존 날짜까지 삭제를 물리적으로 방지하여 SOX/HIPAA 같은 규정을 충족합니다. 빠른 쿼리를 위해 최근 몇 달은 Postgres에 hot하게 유지하고, 더 오래된 것은 object storage에 cold하게 두어 필요 시 쿼리하십시오.
파고드는 지점은 당신이 "감사 로그"가 단지 "타임스탬프가 있는 테이블"이 아니라 **불변성과 증명 가능성(immutability and provability)**을 의미함을 이해하는지입니다. 좋은 답변: append-only 테이블. 훌륭한 답변: DB 역할로 강제된 append-only, 외부 앵커링을 갖춘 hash chain, 보존을 위한 시간 파티셔닝, 규정 준수를 위한 WORM. 흔한 함정: 감사 row를 같은 가변(mutable) 앱 테이블에 저장하는 것(버그나 악의적 DBA가 히스토리를 조용히 다시 쓸 수 있음) — 감사인이 이를 거부할 것입니다.
주니어부터 시니어까지 상세한 답변이 포함된 IT 면접 질문 라이브러리.
후원하기