19 KiB
title, source_type, status, branch, related_projects, tags, created, target_merge, status_label, id, kind, project, work_item, inherits, refines, overrides, depends_on, contract_packet, parent_branch, contract_packet_sha256
| title | source_type | status | branch | related_projects | tags | created | target_merge | status_label | id | kind | project | work_item | inherits | refines | overrides | depends_on | contract_packet | parent_branch | contract_packet_sha256 | |||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| branch / feature-data-retention-privacy-contract | branch-note | raw | feature-data-retention-privacy-contract |
|
|
2026-05-22 | in-progress | BR-CA-SKELETON-OPERATIONAL-CONTRACT-032 | project-work-item | ca-skeleton-operational-contract | WI-CA-SKELETON-OPERATIONAL-CONTRACT-032 |
|
1 | ff83e470a0a30de5fc6591d73f5d7f1ed8cd3501c171a4361e1d206642d9be66 |
branch: feature-data-retention-privacy-contract
Layer:
raw/branch-notes/— 로그, audit/security event, sample data, backup/restore의 보존과 개인정보 노출 기준을 정의합니다.
부모 (필수)
- Parent project (canonical SSOT): raw/project-notes/ca-skeleton-operational-contract
ca-skeleton 은 별도 root branch 없이 project-note 가 SSOT 역할. 본 feature branch 는 project-note 의 운영 계약 중 해당 영역 (§<관련 섹션>) 의 결정/근거/금지 사항을 정제한다.
브랜치 계약 패킷
- 생성 시 프로젝트 개정:
1 - 패킷 스키마:
contract_packet: 1 - 완료 조건: retention·deletion·masking contract test가 통과한다
상속한 프로젝트 결정
| Decision Ref | Project Summary | Branch Application | Source |
|---|---|---|---|
DEC-CA-SKELETON-OPERATIONAL-CONTRACT-MODULE-LAYOUT-001@1 |
Gradle multi-module에서 domain-core·application-core·adapter-*·shared-contract·app-bootstrap·sample-portfolio 책임을 분리한다 | Work Item 완료 조건에 적용 | raw/project-notes/ca-skeleton-operational-contract |
브랜치 지역 결정
기존 branch-local 결정은 아래
## Decision Evidence Map / 결정-근거 매핑의 D-row가 소유하며 이 packet에서 복제하지 않는다.
| Decision ID | Decision | Relation | Supporting Claims | Status |
|---|
선언한 예외
| Override ID | Overrides | Reason | Approval | Status |
|---|
목표
도메인이 없어도 skeleton은 개인정보와 운영 로그를 다룹니다. PII, token, request body, audit/security event 보존 기준이 없으면 운영 로그 자체가 리스크가 됩니다.
- 이슈:
- PR:
범위
포함 범위
- log category별 retention 기준.
- PII/secrets/token redaction 기준.
- pseudonymization 기준.
- audit/security event 보존 기준.
- sample data와 real data 구분 기준.
- backup/restore 책임 경계.
제외 범위
- 특정 법률 준수 문서.
- 실제 DLP product 연동.
- business data retention policy.
TODO
TODO drained 2026-05-22 — 결정은 아래 "결정 사항" / "Retention by Profile" / "DSR Contract" / "Retention Defaults" 참조. application·security·audit retention / PII·token redaction / pseudonymization / sample-vs-real / backup·restore boundary / privacy contract test 기준 모두 결정 라인 또는 표로 반영됨. 잔존 TODO 없음.
Work Item Contract
각 TODO는 아래 판정 단위로 재작성되어야 canonical 승급 가능합니다. TODO가 단순히 기준 작성으로 남아 있으면 이 branch는 완료로 보지 않습니다.
| field | required | rule |
|---|---|---|
| Decision | yes | 구현자가 선택해야 하는 기본값 |
| Allowed | yes | 허용되는 예외와 조건 |
| Forbidden | yes | 절대 금지되는 구현/문서 상태 |
| Required registry update | conditional | error/env/header/log/metric/capability 변경 시 필수 |
| Required contract test | yes | 계약 위반 시 실패해야 하는 테스트 |
| Failure condition | yes | review/build에서 실패로 판정할 상태 |
| Canonical extraction target | yes | wiki/projects 승급 위치 |
결정 사항
- 2026-05-22: skeleton 기본 로그에는 PII, token, raw body를 남기지 않음.
- 2026-05-22: security event log의 principal은 최소 식별 또는 pseudonymized identifier 기준으로 둠.
- 2026-05-22: DSR(delete/export) 절차는 이 branch가 owner. skeleton core는 business data 삭제를 구현하지 않지만 intake, identity verification, scope classification, audit evidence contract는 제공.
- 2026-05-22: retention 기본값은 application log 30일, security event 180일, audit log 1년. 조직/법률 요구가 있으면 override 가능.
- 2026-05-22: backup/restore는 persistence branch와 연결하되 privacy 관점의 retention/erasure evidence를 이 branch가 소유.
- 2026-05-22: redaction layer SSOT는 log-management branch의 Logback masking converter. 본 branch는 PII field allowlist 표만 owns.
- 2026-05-22: pseudonymization key = HMAC-SHA-256 with rotating salt. salt rotation interval = 90일. rotation 시 old salt 90일 retain (lookup 가능). collision rate < 1e-9 가정.
- 2026-05-22: sample data 표시 메커니즘 = (1) entity flag column
is_sample BOOLEAN DEFAULT false+ (2) Spring profilesample활성 시만 seed. prod profile에서 is_sample=true row 발견 시 fail (cleanup migration 의무). - 2026-05-22: DSR delete request 처리 SLA = 30일, export 14일. principal 식별은 pseudonymized id ↔ original id 변환 표(privacy branch가 owns).
- 2026-05-22: backup encryption-at-rest 의무. backup retention default = 30일 daily + 6개월 monthly. restore drill 분기 1회 의무.
- 2026-05-22: 본 branch가 모든 log type(application/security/audit)의 retention SSOT. log-management-contract는 형식만 owns. retention 수치는 본 branch의 Retention by Profile 표가 단일 source.
- 2026-05-22: backup에 PII 포함 시 per-principal envelope key (또는 tenant-level CMK) 구조 적용. HMAC + salt rotation 90d는 "forward security only" 명시. 구체 패턴(per-principal vs tenant-level vs hybrid) 선택은 Phase C2 보류. (status: needs-confirmation)
Retention by Profile
| log type | dev | staging | prod |
|---|---|---|---|
| application | 7일 | 14일 | 30일 |
| security | 30일 | 90일 | 180일 |
| audit | 90일 | 365일 | 365일 (또는 도메인별 override) |
DSR Contract
| step | default |
|---|---|
| intake | authenticated request or verified support workflow |
| identity verification | principal proof before export/delete |
| export | machine-readable JSON/CSV package with audit event |
| delete | domain owner policy, tombstone/pseudonymization allowed |
| evidence | audit event without raw PII payload |
Retention Defaults
| data | default retention |
|---|---|
| application log | 30 days |
| security event log | 180 days |
| audit log | 1 year |
| sample data | never seeded in prod |
| backup | project-specific, restore evidence required |
테스트 계약
- token/password/authorization header가 log capture에 남으면 실패.
- raw request/response body logging이 prod profile에서 가능하면 실패.
- sample data가 production profile에서 seed되면 실패.
- DSR delete/export 절차 owner와 audit evidence가 없으면 실패.
- retention 일수가
0또는 미정이면 실패.
근거 (필수, 최소 1개+)
본 branch의 결정 근거. 상세 비교는 §외부 근거 / 대안 조사 (있다면) 참조.
| Source | 정당화하는 결정 |
|---|---|
| raw/official-docs/privacy-gdpr-article-25-design | GDPR Privacy by design/default (retention "as short as possible" + pseudonymization 권장; ca-tmpl 채택 legal basis |
| raw/company-tech-blogs/privacy-pseudonymization-hmac-vs-tokenization-iapp | HMAC-SHA-256 + 90d salt rotation 선택 근거 (ENISA/IAPP 인정 |
| raw/official-docs/privacy-cryptographic-erasure-nist-sp800-88 | NIST 정식 인정; backup의 GDPR Art |
| raw/official-docs/gdpr-cryptographic-erasure-envelope-key-pattern | 참조 |
외부 근거 / 대안 조사 (2026-05-22 — Group G-J: Data Retention / Privacy)
본 branch의 30/180/365d retention by profile + HMAC-SHA-256 salt rotation 90d + DSR SLA 30d delete / 14d export + is_sample column 결정에 대한 외부 source.
- 채택 결정 (legal basis: GDPR Art.25 + HMAC pseudonymization + retention by category):
- raw/official-docs/privacy-gdpr-article-25-design — GDPR Privacy by design/default (retention "as short as possible" + pseudonymization 권장; ca-tmpl 채택 legal basis)
- raw/company-tech-blogs/privacy-pseudonymization-hmac-vs-tokenization-iapp — HMAC-SHA-256 + 90d salt rotation 선택 근거 (ENISA/IAPP 인정)
- 검토한 대안:
- 대안 1: Tokenization service —
privacy-pseudonymization-hmac-vs-tokenization-iapp동일 source 안에서 비교 (brute-force 가능 input space에서 HMAC보다 우위) - 대안 2: Cryptographic erasure (delete encryption key vs delete data) — raw/official-docs/privacy-cryptographic-erasure-nist-sp800-88 (NIST 정식 인정; backup의 GDPR Art.17 erasure 정합; per-principal envelope key 구조 필요 — ca-tmpl 미결정 보강 후보)
- 대안 3: PII detection SaaS (AWS Macie / OneTrust / TrustArc) — vendor 종속, ca-tmpl scope 외
- 대안 1: Tokenization service —
- 비교 핵심: ca-tmpl HMAC-SHA-256 + 90d salt rotation은 ENISA 인정 패턴이나 brute-force 가능 input space(예: 한국 휴대폰 11자리)에서 tokenization 우위. Cryptographic erase는 backup PII delete의 NIST 정식 방법 — per-principal envelope key 구조 도입 검토 필요(ca-tmpl 미결정). GDPR Art.25가 ca-tmpl retention/pseudonymization 결정의 legal basis.
후속 보강 (2026-05-22): GDPR Art.17 backup erasure 정합을 위한 per-principal envelope key 패턴 필요. HMAC + salt만으로는 forward security만 제공. raw/official-docs/gdpr-cryptographic-erasure-envelope-key-pattern 참조.
결정-근거 매핑
본 branch 의 각 결정이 어떤 raw source claim 으로 뒷받침되는지 명시한다. Decision ID 는 안정적으로 유지한다. company-tech-blog 출처는
company-case-study로 표기하며 공식 best practice 로 일반화하지 않는다.
| Decision ID | Decision | Supporting Claims | Evidence Strength | Open Risk |
|---|---|---|---|---|
| D1 | skeleton 기본 로그에 PII, token, raw body 미기록 | raw/official-docs/privacy-gdpr-article-25-design.md#GDPR-A25-C1 (pseudonymisation as appropriate technical measure), raw/official-docs/privacy-gdpr-article-25-design.md#GDPR-A25-C2 (default: only necessary data processed) |
official-standard (GDPR Art.25) |
Art.25 는 "necessary for purpose" 의 정량 기준을 지정하지 않음 — 도메인별 justification 필요 |
| D2 | security event log principal = 최소 식별 또는 pseudonymized identifier | raw/official-docs/privacy-gdpr-article-25-design.md#GDPR-A25-C1 (pseudonymisation 예시), raw/company-tech-blogs/privacy-pseudonymization-hmac-vs-tokenization-iapp.md#ENISA-PSE-C1 ~ C4 |
official-standard (Art.25) + company-case-study (IAPP/ENISA mapping — 일반화 금지) |
ENISA 가이드는 EU agency document 이나 본 raw 는 IAPP company-case-study 로 분류됨. Art.25 자체는 알고리즘 강도를 지정하지 않음 |
| D3 | DSR (delete/export) 절차 owner = 본 branch | raw/official-docs/privacy-gdpr-article-25-design.md#GDPR-A25-C3 (저장 기간 + 접근성이 default 의무 4축에 포함) |
official-standard |
Art.25 는 DSR SLA 수치 미지정 — Art.12(3) "without undue delay and in any event within one month" 와 결합 해석 필요 (별도 raw 미확보) |
| D4 | retention 기본값 = application 30d / security 180d / audit 1y | raw/official-docs/privacy-gdpr-article-25-design.md#GDPR-A25-C2, raw/official-docs/privacy-gdpr-article-25-design.md#GDPR-A25-C3 (저장 기간 default 의무) |
official-standard (수치 자체는 official 가 아니라 운영 default) |
Art.25 는 정확한 수치 미지정. 30/180/365d 는 ca-tmpl 의 운영적 기본값일 뿐 법적 강제값 아님 |
| D5 | backup/restore = persistence branch 연결, retention/erasure evidence 는 본 branch 소유 | raw/official-docs/gdpr-cryptographic-erasure-envelope-key-pattern.md#GDPR-CE-ENV-C1 ~ C4 (CE + Art.17 의 통합) |
official-standard (NIST SP 800-88 + GDPR Art.17) |
per-principal envelope key 패턴이 EU regulator (DPA) 가 명시 수용한 권장 방식이라는 보장은 없음 |
| D6 | redaction layer SSOT = log-management branch Logback masking converter; 본 branch 는 PII field allowlist 표만 소유 | UNSUPPORTED_DECISION — 책임 경계 분리는 branch 자체 정합성 규칙 | none | Logback masking converter 자체의 공식 spec raw 미확보 |
| D7 | pseudonymization key = HMAC-SHA-256 + rotating salt 90d, collision rate < 1e-9 가정 | raw/company-tech-blogs/privacy-pseudonymization-hmac-vs-tokenization-iapp.md#ENISA-PSE-C1 ~ C4, raw/official-docs/privacy-gdpr-article-25-design.md#GDPR-A25-C1 |
company-case-study (IAPP/ENISA mapping) + official-standard (Art.25 pseudonymisation principle) |
brute-force 가능한 input space (예: 휴대폰 11자리) 에서 tokenization 우위. 90d rotation cadence 의 EDPB 권장값은 별도 미검증 |
| D8 | sample data 표시 = is_sample BOOLEAN column + Spring profile sample 활성 시만 seed (prod 발견 시 fail) |
raw/official-docs/privacy-gdpr-article-25-design.md#GDPR-A25-C2 (data minimization default) |
official-standard |
Art.25 는 is_sample column 메커니즘을 명시하지 않음 — ca-tmpl 운영 구현 선택 |
| D9 | DSR delete SLA = 30d, export = 14d | UNSUPPORTED_DECISION — Art.12(3) "within one month" raw 미확보. 30d 는 ca-tmpl 운영 default | none | Art.12(3) raw 등록 시 보강 가능 |
| D10 | backup encryption-at-rest 의무 + retention 30d daily + 6m monthly + restore drill 분기 1회 | UNSUPPORTED_DECISION — backup retention 수치는 ca-tmpl 운영 default. NIST SP 800-88 은 sanitization 만 정의, retention 수치 미지정 | none | 운영 default 합리성은 별도 |
| D11 | 모든 log type retention SSOT = 본 branch (log-management 는 형식만 소유) | UNSUPPORTED_DECISION — 책임 경계 분리는 branch 자체 정합성 규칙 | none | branch 간 책임 경계의 외부 official 근거 없음 |
| D12 | backup PII = per-principal envelope key (or tenant-level CMK) — 구체 패턴 (a/b/c) Phase C2 보류 | raw/official-docs/gdpr-cryptographic-erasure-envelope-key-pattern.md#GDPR-CE-ENV-C1 ~ C5, raw/official-docs/privacy-cryptographic-erasure-nist-sp800-88.md#NIST-CE-C1 ~ C4 |
official-standard (NIST SP 800-88) + official-vendor-doc (AWS KMS envelope structure) |
(a)/(b)/(c) 중 채택안 미결정. Per-principal CMK 비용 폭증 risk, DEK store 메타-erasure 책임 등 결정 미확정 — status needs-confirmation 유지 |
검증해야 할 주장
| Claim | Why uncertain | How to verify | Status |
|---|---|---|---|
| 30/180/365d retention 이 "necessary for each specific purpose" justification 을 만족 | Art.25 는 정량 기준 미지정 | 도메인별 (application / security / audit) justification 문서화 + DPIA 형식 작성 | needs-confirmation |
| HMAC-SHA-256 + 90d salt rotation 이 EDPB 권장 cadence 와 일치 | EDPB Guidelines 4/2019 "periodic re-pseudonymisation" 의 정확한 cadence 미확인 | EDPB Guidelines 4/2019 또는 ENISA 가이드 raw 추가 + 90d cadence 의 권장 범위 확인 | needs-confirmation |
| brute-force 가능 input space (예: 한국 휴대폰 11자리) 에서 HMAC + salt 의 re-identification risk 가 허용 수준 | input space 특성에 따라 HMAC 우위가 깨질 가능성 | 도메인 별 input space 크기 측정 + tokenization 도입 trigger 결정 | needs-confirmation |
| backup PII 의 GDPR Art.17 단건 erasure 가 per-principal envelope key 패턴으로 충족 | EU regulator 의 명시 수용 의견서 미확인 | DPA 가이드 또는 case law raw 추가 + 패턴 채택 후 통합 테스트 | needs-confirmation |
is_sample BOOLEAN column 메커니즘이 prod 누출 차단에 충분 |
prod profile + is_sample=true row 발견 시 fail 의 구현 미확인 | startup migration 또는 contract test 구현 + prod profile + is_sample=true seed 시 fail verify | planned |
| sensitive log redaction (token / password / authorization header) 가 모든 log capture 경로에서 동작 | Logback masking converter (log-management branch SSOT) 구현 미완 | LogMaskingContractTest 구현 + token/password/auth header injection 시 redaction verify |
planned |
| Art.12(3) "within one month" 와 ca-tmpl DSR SLA 30d / 14d 가 정합 | Art.12(3) raw 미확보 | Art.12 raw 추가 + SLA 비교 | needs-confirmation |
| backup restore drill 분기 1회 가 GDPR 요건 충족 | 외부 official 근거 없음 (ca-tmpl 운영 default) | 분기별 restore drill 실행 evidence (audit log) 보존 + 외부 audit 시 제출 | planned |
| per-principal CMK 의 KMS API cost 가 ca-tmpl 규모에서 운영 가능 | AWS KMS pricing 시점/region 별 변동 + cost 정량 미측정 | Phase C2 에서 (a)/(b)/(c) 중 채택안 + 1 년 운영 비용 시뮬레이션 | needs-confirmation |
| DEK store (DynamoDB / Postgres) 자체의 erasure 책임 경계 | wrapped DEK record 의 backup 정책 미정 | (b) per-principal DEK + master CMK 채택 시 DEK store backup 정책 + replication 정책 추가 결정 | needs-confirmation |
완료 후 wiki 추출 대상
wiki/projects/ca-skeleton-operational-contract.md의 data retention/privacy canonical section.
마주친 문제
- 아직 없음(문서 단계).
묶음
- raw/company-tech-blogs/privacy-pseudonymization-hmac-vs-tokenization-iapp
- raw/official-docs/gdpr-cryptographic-erasure-envelope-key-pattern
- raw/official-docs/privacy-cryptographic-erasure-nist-sp800-88
- raw/official-docs/privacy-gdpr-article-25-design
본 feature branch 는 leaf — 자식 자료 없음. Phase C2 실 코드 작성 단계에서 errors / interview prep / lectures 가 누적되면 본 섹션에서 그룹화.
오류 기록 (본 feature 작업 중 발생)
- (없음 — 현재 documented-only 단계)
면접 준비 (이 작업에서 나올 수 있는 면접 질문)
- (없음 — Phase C2 실 구현 단계에 누적)
진행 중 메모
- retention profile·DSR·기본값의 결정 상태는 위 표와 TODO에서 추적한다.
구현 가이드
- 데이터 분류별 retention 기간과 삭제 주체를 registry로 관리하고 job은 registry를 소비한다.
- DSR 삭제·익명화·legal hold를 서로 다른 상태 전이로 처리하며 감사 로그에는 원문 PII를 남기지 않는다.
- dry-run과 실제 삭제를 분리하고 fixture clock으로 경계 시각을 검증한다.
엣지·실패·의존
- 부분 삭제·재시도 중복·legal hold 무시는 복구가 어려운 데이터 손실 또는 규제 위험으로 이어진다.
- persistence auditing·scheduler lock·tenant context 계약과 함께 검증해야 한다.
관련 일일 노트
- 별도 일일 노트 없음.
완료 후 정리
머지/종료 시점에 채움.
- PR 링크:
- 리뷰 메모:
- 머지 결과 / 배포 환경:
- wiki 추출 대상 (verified만,
wiki/projects/로만 추출):actually-implemented항목:locally-verified항목:prod-verified항목:
- 추출하지 않을 항목 (planned / documented-only / abandoned):