Quipu-Log 교과서
파트 1 · 출발점: DB 없이, 파일로

01 · 감사 로그란, 그리고 왜 'DB 없이 파일로'인가

애플리케이션에서 일어나는 일을 기록하는 방법은 많습니다 — syslog, ELK 스택, 관계형 DB. 그런데 Quipu-Log는 데이터베이스도 외부 스택도 아닌, 프로세스 안에 내장된 파일로 감사 로그를 남깁니다. 이 챕터에서는 "왜 하필 파일인가"를 규제·보안·운영 세 가지 관점에서 살펴봅니다.

한 문장 요약

감사 로그는 "누가, 무엇을, 언제 했는가"를 나중에 증명할 수 있어야 한다. 그 요건을 가장 단순하게 충족하는 구현이 바로 외부 의존 없는, 프로세스 내장 append-only 파일이다.

감사 로그 vs 일반 애플리케이션 로그

먼저 용어를 구분합시다. 우리가 보통 말하는 애플리케이션 로그는 디버깅을 위한 것입니다. "쿼리 실행 시간 12ms", "연결 풀 70% 사용 중" — 이런 기록은 문제를 찾고 나면 지워도 됩니다. 몇 주치면 충분하고, 정확히 언제 썼는지 나중에 바뀌어도 큰 문제가 아닙니다.

감사 로그(audit log)는 목적이 다릅니다. "2026-06-14 09:42 UTC, alice가 patient-record #4821을 열람했다." 이 사실은:

  • 6개월 뒤 감사(audit) 때 그대로 남아 있어야 합니다.
  • 누군가 고쳤다면 그 흔적이 보여야 합니다.
  • alice가 "나는 본 적 없다"고 우기더라도 반박할 근거가 되어야 합니다.

이 세 가지 성질을 전문 용어로 tamper-evidence(변조 탐지)·부인 방지(non-repudiation)라고 합니다. 일반 로그에는 없는, 감사 로그만의 핵심 요건입니다.

일반 애플리케이션 로그 목적: 디버깅 / 운영 관찰 보존: 수 주 ~ 수 개월 변조 탐지: 불필요 주 소비자: 개발자·SRE 예) "쿼리 12ms", "연결 끊김" 감사 로그 목적: 규제 준수 / 부인 방지 보존: 수 년 (법정 기간) 변조 탐지: 필수 주 소비자: 감사자·규제기관 예) "alice, #4821 열람, 09:42 UTC"
두 로그는 목적부터 다르다. 감사 로그는 변조 탐지와 장기 보존이 설계 요건이다.

규제가 요구하는 것: HIPAA · SOX · GDPR

감사 로그가 "있으면 좋은 것"이 아니라 법적 의무인 경우가 많습니다.

  • HIPAA(미국 의료정보 보호법) — 환자 데이터에 누가 접근했는지 6년간 보존하고, 기록 무결성을 유지해야 합니다.
  • SOX(기업 회계 투명성법) — 재무 시스템의 변경 이력을 7년간 보존해야 합니다.
  • GDPR(유럽 개인정보보호법) — 개인정보 처리 활동 기록, 접근 로그 보존 의무가 있습니다.

이 규제들의 공통 요건: 기록이 나중에 바뀌지 않았음을 증명할 수 있어야 합니다. 단순히 "기록이 있다"가 아니라, "기록이 처음 쓰인 그대로다"를 보여야 하죠.

왜 이렇게?

Quipu-Log의 tamper-evidence 설계가 바로 이 요건에서 출발합니다. 파트 5(19~23장)에서 다룰 머클 트리는, 기록이 "고치면 티가 나게" 만들어줍니다 — 고치는 걸 막는 게 아니라, 고쳤을 때 흔적이 남게. 이것이 규제가 원하는 것입니다.

왜 DB나 ELK가 아닌가

DB에 감사 로그를 넣는 것, 직관적으로 보입니다. 트랜잭션이 있고, 쿼리가 쉽고, 권한도 있으니까요. 하지만 몇 가지 문제가 있습니다.

방식장점감사 로그에서의 문제
관계형 DB (같은 DB)트랜잭션, SQL 쿼리애플리케이션과 같은 DB면 DBA가 DELETE 가능 — 내부자가 지울 수 있다. 서비스 다운 시 감사 기록도 같이 멈춘다.
외부 DB (별도 인스턴스)분리된 신뢰 경계운영 부담. 감사 로그를 위해 DB를 하나 더 관리해야 한다. 네트워크 장애 시 감사 공백.
ELK / 로그 스택검색·시각화Elasticsearch는 인덱스를 덮어쓴다. 변조 탐지가 본질적으로 어렵다. 비용·운영 부담도 크다.
Quipu-Log (파일, 내장)의존 없음, 단순, 내장OS 파일시스템만 있으면 동작. 서비스 안에서 돌아 네트워크 장애 무관.

핵심은 신뢰 경계입니다. 감사 로그가 서비스와 같은 프로세스·DB에 있으면, 그 서비스를 운영하는 사람(내부자)이 기록을 지울 수 있습니다. Quipu-Log는 이 문제를 두 가지로 다룹니다. 첫째, 파일에 직접 append-only로 씁니다 (코드가 덮어쓰기를 지원하지 않습니다). 둘째, 머클 트리와 외부 앵커링으로 디스크 수준 변조를 탐지합니다.

비유

은행에서 창구 직원이 현금을 다루는 방을 생각해 보세요. 그 방에서 이루어지는 모든 거래는 별도의 잠긴 금고에 기록이 들어갑니다 — 직원도, 지점장도 이미 쓰인 기록을 지울 수 없는 금고. 감사 로그가 "같은 시스템 안에 있지만 고칠 수 없는" 구조여야 한다는 게 이 아이디어입니다.

임베디드 모드: 프로세스 안으로

Quipu-Log는 임베디드(embedded)로 동작합니다. 별도 데몬이나 서비스가 아니라, 여러분의 Rust 서비스 프로세스 안에서 함께 실행됩니다. `quipu-core` 라이브러리를 `cargo add` 하고 `AuditStore::open()`을 호출하면 끝입니다.

README.md — Quick startlet root = std::path::PathBuf::from("/var/lib/myapp/audit");
let cfg = StoreConfig::new(&root)
    .retention(RetentionPolicy::days(90))
    .sync_policy(SyncPolicy::EveryN(32));
let mut store = AuditStore::open(cfg)?;
// 이게 전부 — 데몬도, 별도 DB도 없다.

물론 여러 서비스가 공유하는 중앙 감사 저장소가 필요하다면 quipu-server를 별도 프로세스로 실행하는 서버 모드도 있습니다. 임베디드 모드와 서버 모드, 언제 어떻게 선택하는지는 2장 지도에서 자세히 다룹니다.

DB ↔ 파일시스템

DB에서는 감사 로그도 테이블에 INSERT하는 경우가 많다 — 같은 DB 관리자가 DELETE할 수 있다는 게 약점이다. Quipu-Log에서는 스토리지 엔진 자체가 append-only 파일이고, 코드 수준에서 덮어쓰기 경로가 없다. "막는다"가 아니라 "고치면 티가 난다"는 설계다.

무엇을 기록하나: 이벤트 구조

Quipu-Log의 감사 이벤트는 액터(actor)타깃(target)에 어떤 행동(method, url)을 했는지를 담습니다. 액터는 "누가" — 사용자, 서비스 계정. 타깃은 "무엇에" — 문서, 환자 레코드, 계정. 이 구조 덕분에 "이 문서에 누가 뭘 했나"와 "이 사용자가 뭘 건드렸나" 두 방향으로 같은 기록을 조회할 수 있습니다.

주의

Quipu-Log는 tamper-evidence이지 tamper-prevention이 아닙니다. 디스크에 물리적 접근 권한이 있는 공격자는 파일을 고칠 수 있습니다. Quipu-Log는 그 변조를 탐지합니다. SECURITY.md는 이것을 설계 범위로 명확히 선언합니다: "an attacker with write access to the store changed a record" — 이게 verify_integrity에서 잡히지 않는다면 그건 취약점이지만, 막지 못한다는 자체는 설계다.

스스로 확인

① 감사 로그와 애플리케이션 로그의 결정적 차이 두 가지를 말해보세요.
② "같은 DB에 감사 로그를 넣는 것"의 신뢰 경계 문제는 무엇인가요?
③ tamper-evidence와 tamper-prevention은 어떻게 다른가요? Quipu-Log는 어느 쪽인가요?