"접속기록은 2년 보관이라던데요?" — 이 한 문장이 만드는 두 가지 실패
개인정보 로그 이야기를 꺼내면 실무에서 거의 항상 두 갈래로 갈립니다.
- 과잉 설계형: "안전하게 가자"며 전 시스템 접속기록을 2년 보관 → 로그 테이블이 수억 건으로 불어나고, 백업·스토리지 비용과 쿼리 성능이 동시에 무너집니다.
- 미달형: 관행적으로 1년만 보관 → 점검·심사에서 "이 시스템은 2년 대상"이라는 지적을 받고 뒤늦게 소급 불가 상태를 확인합니다.
둘 다 원인은 같습니다. "우리 시스템이 어느 칸에 해당하는지"를 판정하지 않은 채 시작한 것.
이 글은 조문 해설이 아니라 판정 → 스키마 → 위·변조 방지 → 월 1회 점검 자동화 → 실패 분기로 이어지는 실행 순서를 다룹니다. 오늘 자사 접속기록 테이블을 열어놓고 읽으면서 미비 항목을 바로 찾아낼 수 있게 구성했습니다.
적용 범위 및 기준 시점: 본문은 2026년 7월 기준 「개인정보의 안전성 확보조치 기준」(개인정보보호위원회 고시) 제8조(접속기록의 보관 및 점검) 해석을 전제로 합니다. 고시는 개정될 수 있고, 개별 사업의 특수성(전자금융, 의료, 통신 등)에 따라 별도 규제가 중첩될 수 있으므로 최종 판단은 고시 원문과 사내 개인정보보호 담당 부서·법률 자문 확인이 필요합니다. ISMS-P 인증 전반은 2026 ISMS-P 인증 준비 체크리스트에서 별도로 다룹니다.
1년인가 2년인가 — 보관기간 판정 의사결정표
먼저 결론부터. 접속기록 보관기간의 기본선은 1년 이상이고, 아래 조건 중 하나라도 해당하면 2년 이상입니다.
판정 질문 4개
| # | 질문 | Yes면 |
|---|---|---|
| Q1 | 해당 시스템이 5만 명 이상 정보주체의 개인정보를 처리하는가? | 2년 |
| Q2 | 고유식별정보(주민등록번호·여권번호·운전면허번호·외국인등록번호)를 처리하는가? | 2년 |
| Q3 | 민감정보(건강, 사상·신념, 노조 가입, 유전정보, 범죄경력 등)를 처리하는가? | 2년 |
| Q4 | 기간통신사업자에 해당하는가? | 2년 |
| — | 전부 No | 1년(기본) |
가장 많이 놓치는 포인트: 판정 단위는 "회사"가 아니라 "시스템"
여기서 실무자가 가장 자주 틀립니다. 판정 대상은 개인정보처리시스템 단위입니다. 같은 회사 안에서도 이렇게 갈립니다.
(주)예시커머스
├─ 회원/주문 시스템 → 회원 12만 명 → Q1 Yes → 2년
├─ 사내 인사(HR) 시스템 → 임직원 300명, 주민번호 보유 → Q2 Yes → 2년
└─ 마케팅 이벤트 DB → 응모자 8천 명, 이름·연락처만 → 전부 No → 1년"우리 회사는 2년이야"라고 뭉뚱그려 전 시스템에 2년을 적용하면 마케팅 DB 로그까지 불필요하게 2배로 쌓입니다. 반대로 "우리는 소규모라 1년"이라고 뭉뚱그리면 HR 시스템에서 지적을 받습니다.
서비스 유형별 판정 사례 4종
| 서비스 유형 | 상황 | 판정 | 판정 근거 |
|---|---|---|---|
| 쇼핑몰 | 회원 12만 명, 이름·연락처·주소, 고유식별정보 없음 | 2년 | Q1 — 정보주체 5만 명 이상 |
| B2B SaaS | 최종 사용자 8천 명, 민감·고유식별정보 없음 | 1년 | Q1~Q4 전부 No (단, 고객사 개인정보를 위탁받아 처리하면 고객사 정보주체 수 합산으로 재판정) |
| 병원 예약 서비스 | 예약자 4천 명, 진료과·증상 등 건강정보 처리 | 2년 | Q3 — 규모와 무관하게 민감정보 처리 |
| 핀테크 | 주민등록번호·계좌 실명확인 정보 처리 | 2년 | Q2 — 고유식별정보 처리 (전자금융 관련 별도 규제와 중첩되나 본 글은 제8조 범위로 한정) |
경계 사례 처리 원칙
- 5만 명 카운트 시점: 특정 시점 스냅샷이 아니라 연중 최대치 기준으로 보수적 산정하는 편이 안전합니다. 이벤트 시즌에만 넘는 경우도 초과로 보는 게 방어에 유리합니다.
- 휴면·탈퇴 계정: 파기하지 않고 분리 보관 중인 데이터는 여전히 처리 중인 개인정보로 보는 것이 보수적 해석입니다. 완전 파기된 건만 제외하십시오.
- 성장 중 서비스의 소급 문제: 회원 4만 명일 때 1년 설계 → 8개월 뒤 6만 명 돌파 시, 이미 삭제된 로그는 되살릴 수 없습니다. 이때 남는 건 "이 시점부터 2년 적용" 근거 문서뿐입니다.
- ✅ 실무 결론: 1~2년 내 5만 명 돌파가 예상되는 서비스는 처음부터 2년 설계가 총비용상 유리합니다. 로그 저장 비용보다 재설계·소명 비용이 큽니다.
지금 해야 할 것: 시스템 목록 표를 만들어 시스템명 / 정보주체 수 / 고유식별·민감정보 여부 / 판정 결과 / 근거 5열로 문서화하십시오. 점검에서 "보관기간 산정 근거 문서 부재"는 단골 지적 사항입니다.
로그 스키마 매핑: 다섯 항목을 실제 테이블로
접속기록 필수 항목은 다섯 가지입니다: 계정 / 접속일시 / 접속지 정보 / 처리한 정보주체 정보 / 수행업무.
PostgreSQL DDL 예제
CREATE TABLE access_log (
id BIGSERIAL PRIMARY KEY,
-- ① 계정: 개인정보취급자 식별자 (공용계정 금지)
actor_account VARCHAR(64) NOT NULL,
actor_emp_no VARCHAR(32), -- 퇴사 후에도 인사번호로 추적
-- ② 접속일시: UTC 저장 + 표시 시 KST 변환 (혼용 금지)
accessed_at TIMESTAMPTZ NOT NULL DEFAULT now(),
-- ③ 접속지 정보
src_ip INET NOT NULL,
user_agent TEXT,
session_id VARCHAR(64),
-- ④ 처리한 정보주체 정보 (원문 대신 내부 ID/해시)
subject_ref VARCHAR(128), -- 예: user:830112 또는 sha256 해시
subject_type VARCHAR(32), -- member / patient / applicant
-- ⑤ 수행업무
action VARCHAR(24) NOT NULL, -- READ/UPDATE/DELETE/EXPORT/PRINT
resource VARCHAR(128) NOT NULL, -- 예: /admin/members/detail
target_count INTEGER NOT NULL DEFAULT 1, -- 대량조회 탐지 핵심
result VARCHAR(16) NOT NULL DEFAULT 'SUCCESS',
detail JSONB
) PARTITION BY RANGE (accessed_at);
CREATE TABLE access_log_2026_07 PARTITION OF access_log
FOR VALUES FROM ('2026-07-01') TO ('2026-08-01');
CREATE INDEX idx_access_log_actor ON access_log (actor_account, accessed_at DESC);
CREATE INDEX idx_access_log_subject ON access_log (subject_ref, accessed_at DESC);
CREATE INDEX idx_access_log_action ON access_log (action, accessed_at DESC);MySQL 8.0을 쓴다면 TIMESTAMPTZ → DATETIME(3)(UTC 저장), INET → VARBINARY(16) + INET6_ATON(), JSONB → JSON, 파티셔닝은 PARTITION BY RANGE (TO_DAYS(accessed_at))으로 대응합니다.
애플리케이션 감사 로그 JSON 예제
{
"ts": "2026-07-28T09:14:22.481Z",
"tz_display": "Asia/Seoul",
"actor": { "account": "kim.cs", "emp_no": "E20231045", "role": "CS_AGENT" },
"src": { "ip": "10.20.5.31", "xff": "203.0.113.44", "session": "s_9f2a..." },
"action": "EXPORT",
"resource": "/admin/members/export",
"subject": { "type": "member", "refs": ["m_10023", "m_10024"], "count": 2 },
"target_count": 2,
"result": "SUCCESS",
"reason": "CS-2026-4412 환불 민원 처리"
}항목별 설계 포인트
| 컬럼 | 주의점 |
|---|---|
actor_account | 공용계정(admin, operator) 금지. 행위자 특정이 불가하면 로그 전체의 소명력이 사라집니다. 퇴사자 계정 재사용도 금지 — actor_emp_no를 함께 남깁니다. |
accessed_at | UTC 저장 + KST 표시가 안전합니다. 서버별 타임존이 섞이면 대조 자체가 불가능해집니다. |
src_ip | ALB/Nginx 뒤라면 프록시 IP가 아닌 원 클라이언트 IP를 남겨야 합니다. X-Forwarded-For의 가장 왼쪽 신뢰 가능한 값을 신뢰 프록시 목록 기반으로 추출하십시오. |
subject_ref | 원문 개인정보(이름, 전화번호)를 넣지 마십시오. 로그 자체가 또 하나의 개인정보 저장소가 되어 파기·암호화 의무가 따라붙습니다. 내부 ID 또는 해시를 사용합니다. |
action | 조회/수정/삭제와 다운로드·출력을 반드시 분리합니다. 유출은 대부분 EXPORT/PRINT에서 발생합니다. |
target_count | 대량조회 탐지의 유일한 근거입니다. 목록 조회 API에서 반환 건수를 반드시 기록하십시오. |
흔한 미비 사례 Before / After
① 정보주체 식별자 누락 — 사고 시 영향 범위 산정 불가
# Before
log.info(f"{user.id} viewed member detail page")
# After
audit.write(
actor_account=user.account, action="READ",
resource="/admin/members/detail",
subject_type="member", subject_refs=[member.id], target_count=1,
)지적 사유: 유출 의심 시 "누구의 정보가 조회되었는가"를 특정할 수 없어 통지 대상 산정이 불가능합니다.
② IP와 시각만 기록 — 웹 액세스 로그를 접속기록으로 착각
# Before (Nginx access.log — 접속기록이 아님)
203.0.113.44 - - [28/Jul/2026:09:14:22 +0900] "GET /admin/members?page=3 HTTP/1.1" 200
# After (수행업무 + 정보주체 + 건수 포함)
{"ts":"...","actor":"kim.cs","action":"READ","resource":"/admin/members",
"subject":{"type":"member","count":50},"target_count":50}지적 사유: 계정·수행업무·정보주체 정보가 없어 필수 항목 미충족입니다. 웹 서버 로그는 보조 자료일 뿐입니다.
③ 조회 건수 미기록 — 대량조회 탐지 불가
# Before
rows = repo.search(keyword) # 12,000건 반환, 로그엔 "search" 한 줄
# After
rows = repo.search(keyword)
audit.write(action="READ", resource="/admin/members/search",
target_count=len(rows), detail={"keyword_hash": h(keyword)})지적 사유: 내부자가 전체 회원을 훑어도 1건 조회와 구분되지 않아 이상징후 점검이 형식적으로 흐릅니다.
위·변조 방지: 구현 옵션 4종 비교
접속기록은 위·변조되지 않도록 안전하게 보관해야 합니다. 취급자가 자기 흔적을 지울 수 있다면 로그는 증거가 아닙니다.
| 옵션 | 초기 구축비 | 월 운영비 | 운영 난이도 | 점검 시 소명력 | 단독 사용 |
|---|---|---|---|---|---|
| 접근권한 분리 (로그 DB/테이블에 대한 개발자 UPDATE·DELETE 권한 회수, INSERT-only 계정) | 낮음 | 없음 | 낮음 | 중 | △ (최소 기본선) |
| 별도 로그 서버 전송 (rsyslog / Fluent Bit → 분리된 수집 서버) | 중 | 중 | 중 | 상 | ○ |
| 오브젝트 스토리지 WORM (S3 Object Lock Compliance 모드 등) | 중 | 중~높음 | 중 | 최상 | ○ |
| 해시체인 · 체크섬 (일 단위 무결성 해시 + 이전 해시 연결) | 높음 | 낮음 | 높음 | 상 (구현 품질 의존) | △ |
실무 권장선: 접근권한 분리 + 별도 저장소 전송을 기본으로 두고, 고유식별·민감정보를 다루는 고위험 시스템에만 WORM 또는 해시체인을 추가합니다. 처음부터 해시체인을 직접 구현하다 운영 부담으로 무너지는 사례가 많습니다.
INSERT-only 권한 분리 예시:
-- 애플리케이션 계정은 삽입만 가능
REVOKE ALL ON access_log FROM app_user;
GRANT INSERT ON access_log TO app_user;
GRANT USAGE, SELECT ON SEQUENCE access_log_id_seq TO app_user;
-- 점검자는 읽기만
CREATE ROLE auditor LOGIN PASSWORD '...';
GRANT SELECT ON access_log TO auditor;일 단위 무결성 체크섬(간단 버전):
#!/usr/bin/env bash
# /usr/local/bin/log-checksum.sh — 전일 로그 해시를 append-only 파일에 기록
set -euo pipefail
DAY=$(date -d 'yesterday' +%F)
OUT=/var/log/audit/chain.log
PREV=$(tail -n1 "$OUT" 2>/dev/null | awk '{print $3}' || echo "GENESIS")
HASH=$(psql -qAt -c "SELECT md5(string_agg(id::text||actor_account||action, '|' ORDER BY id))
FROM access_log WHERE accessed_at::date = '$DAY'")
echo "$DAY $PREV ${PREV:0:8}$HASH" >> "$OUT"
chattr +a "$OUT" 2>/dev/null || true # append-only 속성예상 정상 결과:
chain.log에 하루 한 줄이 추가되고, 기존 줄은 수정 시도 시Operation not permitted가 발생합니다. 이 메시지가 나지 않으면chattr +a가 적용되지 않은 것이므로 파일시스템(ext4/xfs) 지원 여부와 실행 권한을 확인하십시오.
월 1회 점검 자동화: 이상징후 탐지 SQL 3종
접속기록은 보관만으로 끝나지 않습니다. 월 1회 이상 점검이 함께 요구됩니다. 아래 3종을 기본 세트로 삼으십시오.
(a) 다운로드·출력 행위 추출
SELECT actor_account, accessed_at, resource, target_count, src_ip
FROM access_log
WHERE accessed_at >= date_trunc('month', now() - interval '1 month')
AND accessed_at < date_trunc('month', now())
AND action IN ('EXPORT', 'PRINT', 'DOWNLOAD')
ORDER BY target_count DESC, accessed_at;이 결과는 전 건 소명 대상으로 보는 것이 안전합니다. 건수가 수백 건이면 업무 프로세스 자체를 재검토해야 합니다(불필요한 엑셀 다운로드 관행).
(b) 임계치 초과 대량조회
WITH baseline AS (
SELECT actor_account, AVG(daily_cnt) AS avg_cnt
FROM (SELECT actor_account, accessed_at::date d, SUM(target_count) daily_cnt
FROM access_log
WHERE accessed_at >= now() - interval '90 days'
GROUP BY 1,2) t
GROUP BY 1
)
SELECT l.actor_account, l.accessed_at::date AS d,
SUM(l.target_count) AS today_cnt, ROUND(b.avg_cnt) AS avg_cnt
FROM access_log l JOIN baseline b USING (actor_account)
WHERE l.accessed_at >= date_trunc('month', now() - interval '1 month')
AND l.accessed_at < date_trunc('month', now())
GROUP BY 1,2,4
HAVING SUM(l.target_count) > GREATEST(500, b.avg_cnt * 3)
ORDER BY today_cnt DESC;임계치는
1회 500건 초과또는본인 90일 일평균의 3배중 큰 값. 조직 규모에 맞게 조정하되 기준값을 문서에 명시해야 "임의 판단"이라는 지적을 피합니다.
(c) 비업무시간 · 비인가 IP 대역 접근
SELECT actor_account, accessed_at, src_ip, action, resource, target_count
FROM access_log
WHERE accessed_at >= date_trunc('month', now() - interval '1 month')
AND accessed_at < date_trunc('month', now())
AND (
EXTRACT(hour FROM accessed_at AT TIME ZONE 'Asia/Seoul') NOT BETWEEN 8 AND 20
OR EXTRACT(dow FROM accessed_at AT TIME ZONE 'Asia/Seoul') IN (0, 6)
OR NOT (src_ip << ANY (ARRAY['10.0.0.0/8'::inet, '172.16.0.0/12'::inet]))
)
ORDER BY accessed_at;cron 스케줄 골격
# /etc/cron.d/privacy-audit — 매월 1일 07:00 전월 점검 리포트 생성·발송
0 7 1 * * auditor /usr/local/bin/monthly_audit.sh >> /var/log/audit/cron.log 2>&1#!/usr/bin/env bash
# monthly_audit.sh
set -euo pipefail
PERIOD=$(date -d 'last month' +%Y-%m)
OUT="/var/log/audit/report_${PERIOD}.csv"
for q in export_activity bulk_read offhours_access; do
echo "== ${q} ==" >> "$OUT"
psql -qA -F',' -f "/opt/audit/sql/${q}.sql" >> "$OUT"
done
mail -s "[개인정보] ${PERIOD} 접속기록 점검 결과" -a "$OUT" \
[email protected] < /opt/audit/mail_body.txt예상 정상 결과:
report_2026-06.csv가 생성되고 담당자 메일이 도착합니다. 파일이 0바이트라면auditor계정의 SELECT 권한 또는.pgpass설정을 먼저 확인하십시오. cron 자체 문제 진단은 Cron 작업 스케줄러 실전 가이드, 서비스 실행 실패 로그 추적은 journalctl 완전 활용을 참고하세요.
점검결과 보고서 양식
자동화만 하고 문서를 안 남기면 "점검 이력 부재"로 지적받습니다. 아래 항목을 채운 문서를 월 단위로 남기십시오.
| 항목 | 기재 내용 |
|---|---|
| 점검 기간 | 2026-06-01 ~ 2026-06-30 |
| 점검 대상 시스템 | 회원/주문 시스템, HR 시스템 (보관기간 2년) |
| 점검 방법 | 자동 탐지 쿼리 3종 + 표본 수기 검토 |
| 탐지 건수 | 다운로드 12건 / 대량조회 3건 / 비업무시간 5건 |
| 소명 내용 | 대량조회 3건 중 2건 정기 정산 배치, 1건 CS 일괄 확인(티켓 CS-2026-4412) |
| 조치 결과 | 정산 배치 계정 별도 분리, 취급자 1인 재교육 실시 |
| 점검자 / 확인자 | 보안팀 OOO (서명) / 개인정보 보호책임자 OOO (서명) |
- 이상징후 처리 흐름: 탐지 → 소명 요청(3영업일) → 소명 접수·기록 → 판단(정상/이상) → 조치 → 종결
- 보고서 자체도 사내 기준에 따라 일정 기간 보존하고, 접속기록과 동일하게 임의 수정이 불가한 위치에 보관하는 것이 바람직합니다.
실패 분기 ① 로그 용량 폭증
2년 보관 대상 시스템에서 일 500만 건이 쌓이면 36억 건이 됩니다. 3단계로 대응합니다.
- 월 단위 파티셔닝 — 조회 성능 유지, 만료 파티션 단위 DROP으로 파기 단순화
- 압축 아카이브 — 3개월 경과 파티션은 CSV/Parquet 덤프 후 압축
- 오브젝트 스토리지 이관 — S3 Standard-IA / Glacier Instant Retrieval 등
# 3개월 지난 파티션 아카이브 → S3 이관 → DROP
TBL=access_log_2026_04
psql -c "\copy ${TBL} TO PROGRAM 'gzip > /tmp/${TBL}.csv.gz' CSV HEADER"
aws s3 cp /tmp/${TBL}.csv.gz s3://corp-audit-archive/access_log/ \
--storage-class STANDARD_IA
psql -c "DROP TABLE ${TBL};"⚠️ 핵심 주의점 2가지
- 이관해도 보관기간은 계속 흐릅니다. 콜드 스토리지로 옮긴 순간 "보관 완료"가 아니라, 판정된 1년/2년 동안 계속 살아 있어야 합니다.
- 요청 시 합리적인 시간 내 복원 가능해야 합니다. Glacier Deep Archive는 복원에 수 시간
십수 시간이 걸릴 수 있어, 사고 대응이나 점검 요청 상황에서 부담이 됩니다. 최근 36개월분은 즉시 조회 가능한 계층에 두고, 그 이전만 심층 아카이브로 내리는 2단 구성이 무난합니다.
파기 자동화와 파기 기록: 보관기간 만료분은 자동 삭제하되, "무엇을 언제 파기했는지"는 별도 파기 기록으로 남깁니다. 파기 기록은 접속기록이 아니므로 삭제 대상이 아닙니다.
-- 파기 기록 테이블 (삭제 대상 아님)
CREATE TABLE audit_disposal_log (
id BIGSERIAL PRIMARY KEY,
target_table VARCHAR(64), period_from DATE, period_to DATE,
row_count BIGINT, disposed_at TIMESTAMPTZ DEFAULT now(),
operator VARCHAR(64), method VARCHAR(32) -- DROP PARTITION / S3 DELETE
);실패 분기 ② 클라우드 관리형 DB·서버리스의 감사 사각지대
RDS·Aurora·서버리스 환경에서는 DB 자체 감사 로그가 제한적이거나, 남더라도 수행업무·정보주체 식별자를 담지 못합니다. DB 감사 로그는 "어떤 SQL이 실행됐다"까지만 알려주고, "CS 담당자가 환불 처리를 위해 회원 3명을 조회했다"는 맥락은 담기지 않습니다.
권장 이중 구조
| 계층 | 역할 | 비고 |
|---|---|---|
| 애플리케이션 감사 로그 | 정본(正本) — 5개 필수 항목 전부 기록 | 서비스 경로 접근 전체 커버 |
| DB 감사 로그(pgaudit 등) | 보조 — 애플리케이션 우회 접근 탐지 | 정본과 대조해 누락 확인 |
| 관리 콘솔·SSH·Bastion | 별도 통제 — 접근 승인 + 세션 기록 | 여기가 가장 큰 사각지대 |
- 운영자가 콘솔이나 SQL 클라이언트로 DB에 직접 접속하는 경로는 별도 승인 절차와 세션 기록(터미널 녹화 등)으로 통제하고, 애플리케이션 로그와 대조합니다.
- 서버리스(Lambda 등)는 인스턴스가 사라지므로 로컬 파일 로깅이 무의미합니다. 동기 전송이 아닌 비동기 큐 → 수집기 구조로 유실을 막되, 전송 실패 시 재시도·DLQ를 반드시 설계하십시오.
- 감사 로그를 SIEM으로 통합하는 흐름이 늘고 있지만, SIEM 보존 정책(예: 90일 핫 스토리지)이 법정 보관기간을 대체하지 못합니다. SIEM은 탐지용, 정본 보관은 별도로 유지하는 것이 안전합니다.
점검 시 자주 지적되는 항목 체크리스트
| 지적 항목 | 이번 주 안에 할 수 있는 조치 |
|---|---|
| 보관기간 산정 근거 문서 부재 | 시스템 목록표에 판정 질문 4개 응답과 결론을 1페이지로 정리·결재 |
| 정보주체 식별자 누락 | 감사 로그 미들웨어에 subject_ref·subject_type 필드 추가 후 상위 5개 조회 API부터 적용 |
| 다운로드·출력 행위 미기록 | 엑셀/CSV 내보내기 엔드포인트에 action='EXPORT' + target_count 강제 기록 |
| 조회 건수 미기록 | 목록 API 응답 직후 len(rows)를 로그에 반영 |
| 점검 이력이 문서로 없음 | 위 보고서 양식으로 최근 1~3개월분 소급 작성 + 책임자 서명 |
| 로그 저장소에 취급자 쓰기 권한 보유 | 로그 테이블에 대해 REVOKE UPDATE, DELETE 실행, INSERT-only 계정 분리 |
| 공용 계정으로 행위자 특정 불가 | admin 등 공용 계정 비활성화, 개인별 계정 발급 및 인사번호 매핑 |
| 타임존 혼재로 시각 대조 불가 | 전 서버 UTC 통일 또는 저장 시각 오프셋 명시(+09:00) |
30일 실행 순서 요약
| 주차 | 할 일 | 산출물 |
|---|---|---|
| 1주차 | 시스템 목록 작성 → 판정 질문 4개로 1년/2년 판정 | 보관기간 산정 근거 문서 |
| 2주차 | 현행 로그 스키마 vs 5개 필수 항목 갭 분석 → DDL 수정 | 스키마 변경 PR, 미비 항목 리스트 |
| 3주차 | 권한 분리(INSERT-only) + 별도 저장소 전송 구성 | 위·변조 방지 구성도 |
| 4주차 | 탐지 SQL 3종 + cron 자동화 + 첫 보고서 작성 | 월간 점검결과 보고서 v1 |
순서가 중요합니다. 판정 없이 스키마부터 손대면 다시 갈아엎게 되고, 점검 자동화부터 하면 남길 데이터가 없어 빈 리포트만 나옵니다.
다시 강조하면, 본문의 모든 기준은 2026년 7월 기준 「개인정보의 안전성 확보조치 기준」 제8조 해석을 전제로 합니다. 고시는 개정될 수 있으며 업종별 별도 규제가 중첩될 수 있으니, 개인정보보호위원회 고시 원문과 사내 개인정보 보호책임자·법률 자문의 최종 확인을 반드시 거치시기 바랍니다.
자주 묻는 질문 (FAQ)
Q1. 회원 수가 4만 명인데 곧 5만 명을 넘을 것 같습니다. 지금 1년으로 설계해도 되나요? A. 기준상으로는 현재 1년 대상이지만, 5만 명을 넘긴 뒤에는 이미 삭제된 로그를 복구할 수 없습니다. 1~2년 내 초과가 예상된다면 처음부터 2년 보관으로 설계하는 편이 재설계·소명 비용을 아끼는 길입니다. 다만 판정 시점과 근거는 반드시 문서로 남기십시오.
Q2. Nginx access log와 CloudTrail이 있으면 접속기록 요건을 충족한 건가요? A. 충족하지 못합니다. 접속기록은 계정·접속일시·접속지 정보에 더해 처리한 정보주체 정보와 수행업무까지 담겨야 합니다. 웹 서버 로그에는 "누구의 개인정보를 무슨 업무로 처리했는지"가 없습니다. 애플리케이션 계층 감사 로그를 정본으로 두고, 웹·클라우드 로그는 보조 근거로 활용하십시오.
Q3. 점검을 자동화 스크립트로 매월 돌리고 있는데 별도 문서도 필요한가요? A. 필요합니다. 실무에서 가장 자주 지적되는 유형 중 하나가 "탐지는 돌아가는데 점검 이력이 문서로 남지 않은" 경우입니다. 탐지 건수, 소명 내용, 조치 결과, 점검자·개인정보 보호책임자 확인이 포함된 보고서를 월 단위로 남기고, 접속기록과 마찬가지로 임의 수정이 어려운 위치에 보관하는 것을 권장합니다.
AI 도구는 자료 조사와 초안 작성의 보조 수단으로 사용될 수 있습니다. Nodelog는 공개 전 내용과 출처를 검토하고, 환경(OS·버전)에 따라 결과가 달라질 수 있는 기술 정보는 공식 문서를 함께 확인하도록 안내합니다. 오류를 발견하시면 이메일로 제보해 주세요 — 확인 후 신속히 정정합니다.
댓글
첫 번째 댓글을 남겨보세요.