PIMS
Personal Information Management System
개인정보보호 관리체계 인증제도. 조직이 개인정보를 체계적으로 보호하고 관리하는지 검증하는 국내 인증으로, 현재 ISMS와 통합된 ISMS-P로 운영됩니다.
Personal Information Management System
개인정보보호 관리체계 인증제도. 조직이 개인정보를 체계적으로 보호하고 관리하는지 검증하는 국내 인증으로, 현재 ISMS와 통합된 ISMS-P로 운영됩니다.
PIMS(Personal Information Management System)는 한국인터넷진흥원(KISA)이 운영하던 개인정보보호 관리체계 인증제도입니다. 2018년 11월부터 정보보호 관리체계(ISMS)와 통합되어 ISMS-P(정보보호 및 개인정보보호 관리체계)로 운영됩니다. PIMS의 핵심 요소들은 ISMS-P의 개인정보 처리 단계별 요구사항으로 계승되었습니다. 개인정보보호법과 정보통신망법의 의무사항을 체계적으로 이행하기 위한 프레임워크입니다.
PIMS/ISMS-P의 개인정보보호 영역은 개인정보 생명주기 전체를 다룹니다. 수집 단계에서는 적법한 동의 획득, 최소 수집 원칙을 검증합니다. 이용/제공 단계에서는 목적 범위 내 처리, 제3자 제공 절차를 확인합니다. 보관/파기 단계에서는 보유기간 관리, 안전한 파기 절차를 평가합니다. 이러한 체계적 관리를 통해 개인정보 침해 사고를 예방합니다.
인증 획득 과정은 서류 심사와 현장 심사로 구성됩니다. 조직은 개인정보보호 정책, 처리 절차, 기술적/물리적 보호조치를 문서화해야 합니다. 심사원이 실제 운영 상태를 현장에서 확인하며, 결함이 발견되면 보완 후 재심사를 받습니다. 인증 유효기간은 3년이며, 매년 사후관리 심사를 통해 지속적인 이행 여부를 검증합니다.
AI 시스템에서 PIMS/ISMS-P는 더욱 중요합니다. ML 모델 학습에 개인정보가 사용되면 수집 동의, 목적 제한, 안전한 처리가 필수입니다. AI 기반 개인화 서비스는 프로파일링 동의와 자동화된 의사결정 고지 의무가 있습니다. EU의 GDPR과 달리 국내법 중심이지만, 해외 진출 시 GDPR, CCPA와의 정합성도 고려해야 합니다.
# PIMS/ISMS-P 준수 개인정보 처리 클래스
import hashlib
import logging
from datetime import datetime, timedelta
from typing import Optional, Dict, Any
from enum import Enum
class ConsentType(Enum):
REQUIRED = "required" # 필수 동의
OPTIONAL = "optional" # 선택 동의
MARKETING = "marketing" # 마케팅 동의
THIRD_PARTY = "third_party" # 제3자 제공 동의
class PIIMSCompliantProcessor:
"""PIMS/ISMS-P 준수 개인정보 처리기"""
def __init__(self, retention_days: int = 365):
self.retention_days = retention_days
self.logger = logging.getLogger("pims_audit")
def collect_personal_info(
self,
data: Dict[str, Any],
consents: Dict[ConsentType, bool],
collection_purpose: str
) -> Optional[Dict[str, Any]]:
"""개인정보 수집 (최소 수집 원칙 적용)"""
# 필수 동의 확인
if not consents.get(ConsentType.REQUIRED, False):
self.logger.warning("필수 동의 없이 수집 시도")
raise ValueError("필수 동의가 필요합니다")
# 최소 수집 원칙 - 목적에 필요한 항목만 수집
required_fields = self._get_required_fields(collection_purpose)
collected_data = {
k: v for k, v in data.items()
if k in required_fields
}
# 수집 이력 로깅 (감사 추적)
self.logger.info(
f"개인정보 수집 | 목적: {collection_purpose} | "
f"항목: {list(collected_data.keys())} | "
f"동의: {[c.value for c, v in consents.items() if v]}"
)
# 보유기간 설정
collected_data["_retention_until"] = (
datetime.now() + timedelta(days=self.retention_days)
).isoformat()
collected_data["_collection_purpose"] = collection_purpose
collected_data["_consents"] = {c.value: v for c, v in consents.items()}
return collected_data
def pseudonymize(self, data: Dict[str, Any], fields: list) -> Dict[str, Any]:
"""가명처리 (식별자 해시화)"""
result = data.copy()
for field in fields:
if field in result:
# SHA-256 + Salt로 가명처리
salt = "pims_salt_2024" # 실제로는 안전하게 관리
original = str(result[field])
result[field] = hashlib.sha256(
(original + salt).encode()
).hexdigest()[:16]
self.logger.info(f"가명처리 완료 | 대상 필드: {fields}")
return result
def check_retention_and_destroy(self, records: list) -> int:
"""보유기간 만료 데이터 파기"""
destroyed_count = 0
now = datetime.now()
for record in records:
retention_until = datetime.fromisoformat(
record.get("_retention_until", "2099-12-31")
)
if now > retention_until:
self._secure_destroy(record)
destroyed_count += 1
self.logger.info(f"개인정보 파기 완료 | 파기 건수: {destroyed_count}")
return destroyed_count
def _secure_destroy(self, record: Dict[str, Any]):
"""안전한 파기 (복구 불가능하게)"""
# 실제 구현에서는 DB에서 삭제 + 백업에서도 삭제
pass
def _get_required_fields(self, purpose: str) -> set:
"""목적별 필요 수집 항목 정의"""
purpose_fields = {
"회원가입": {"email", "password", "name"},
"본인인증": {"name", "phone", "birth_date"},
"배송": {"name", "address", "phone"},
"마케팅": {"email"}, # 최소한만
}
return purpose_fields.get(purpose, set())
# 사용 예시
processor = PIIMSCompliantProcessor(retention_days=365)
user_data = {
"email": "user@example.com",
"name": "홍길동",
"phone": "010-1234-5678",
"address": "서울시 강남구",
"hobby": "독서" # 불필요한 항목
}
consents = {
ConsentType.REQUIRED: True,
ConsentType.MARKETING: False
}
# 회원가입 목적으로 수집 (최소 항목만)
collected = processor.collect_personal_info(
user_data, consents, "회원가입"
)
print(f"수집된 항목: {[k for k in collected if not k.startswith('_')]}")
# 출력: ['email', 'name'] - hobby, address는 목적에 불필요하므로 제외
# ISMS-P 개인정보보호 인증 체크리스트 (자동화 점검용)
# 참고: KISA ISMS-P 인증기준 개인정보 처리 단계별 요구사항
isms_p_checklist:
version: "2024.1"
organization: "Example Corp"
audit_date: "2026-01-26"
# 1. 개인정보 수집 시 보호조치
collection:
items:
- id: "PI-001"
requirement: "개인정보 수집 시 동의 획득"
controls:
- "수집 목적 명시"
- "수집 항목 명시"
- "보유 기간 명시"
- "동의 거부권 안내"
evidence:
- "개인정보 수집 동의서"
- "회원가입 화면 캡처"
status: "compliant" # compliant / non_compliant / partial
- id: "PI-002"
requirement: "최소 수집 원칙"
controls:
- "목적에 필요한 항목만 수집"
- "민감정보 수집 시 별도 동의"
evidence:
- "개인정보 처리방침"
- "수집항목 검토 보고서"
status: "compliant"
# 2. 개인정보 이용 및 제공
usage_and_provision:
items:
- id: "PI-003"
requirement: "목적 범위 내 이용"
controls:
- "수집 목적과 이용 목적 일치 확인"
- "목적 외 이용 시 별도 동의"
evidence:
- "개인정보 이용 현황"
- "접근 로그"
status: "compliant"
- id: "PI-004"
requirement: "제3자 제공 절차"
controls:
- "제공받는 자 명시"
- "제공 목적 명시"
- "제공 항목 명시"
- "제공받는 자의 보유기간"
evidence:
- "제3자 제공 동의서"
- "위탁계약서"
status: "partial"
remediation: "위탁계약서 갱신 필요 (2026-03-01까지)"
# 3. 개인정보 보관 및 파기
retention_and_destruction:
items:
- id: "PI-005"
requirement: "보유기간 관리"
controls:
- "법정 보유기간 준수"
- "보유기간 경과 시 지체없이 파기"
evidence:
- "개인정보 파기 이력"
- "보유기간 관리 대장"
status: "compliant"
- id: "PI-006"
requirement: "안전한 파기"
controls:
- "복구 불가능한 방법으로 파기"
- "파기 확인 및 기록"
evidence:
- "파기 증명서"
- "디스크 완전삭제 확인서"
status: "compliant"
# 4. 기술적 보호조치
technical_measures:
items:
- id: "PI-007"
requirement: "접근 권한 관리"
controls:
- "개인정보 처리자 지정"
- "최소 권한 부여"
- "접근 권한 변경 이력 관리"
evidence:
- "접근 권한 관리 대장"
- "계정 생성/변경 로그"
status: "compliant"
- id: "PI-008"
requirement: "암호화"
controls:
- "비밀번호 일방향 암호화"
- "주민번호 등 고유식별정보 암호화"
- "전송 구간 암호화 (TLS)"
evidence:
- "암호화 적용 현황"
- "암호화 솔루션 설정"
status: "compliant"
# 종합 평가
summary:
total_items: 8
compliant: 7
partial: 1
non_compliant: 0
compliance_rate: 87.5%
next_audit: "2026-07-26"
-- PIMS/ISMS-P 준수 개인정보 보존 및 파기 관리 SQL
-- 1. 개인정보 테이블 (보유기간 관리 포함)
CREATE TABLE personal_info (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
user_id VARCHAR(50) NOT NULL,
-- 개인정보 항목 (암호화 저장)
name_encrypted VARBINARY(256), -- AES 암호화
email_encrypted VARBINARY(256),
phone_encrypted VARBINARY(256),
ssn_encrypted VARBINARY(256), -- 주민번호 (수집 최소화)
-- PIMS 관리 메타데이터
collection_purpose VARCHAR(100) NOT NULL,
consent_required BOOLEAN DEFAULT TRUE,
consent_marketing BOOLEAN DEFAULT FALSE,
consent_third_party BOOLEAN DEFAULT FALSE,
-- 보유기간 관리
collected_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
retention_period_days INT NOT NULL DEFAULT 365,
retention_expires_at TIMESTAMP AS (DATE_ADD(collected_at, INTERVAL retention_period_days DAY)),
is_destroyed BOOLEAN DEFAULT FALSE,
destroyed_at TIMESTAMP NULL,
-- 감사 추적
last_accessed_at TIMESTAMP NULL,
access_count INT DEFAULT 0,
INDEX idx_retention (retention_expires_at, is_destroyed),
INDEX idx_purpose (collection_purpose)
);
-- 2. 개인정보 접근 로그 (감사 추적)
CREATE TABLE pi_access_log (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
personal_info_id BIGINT NOT NULL,
accessor_id VARCHAR(50) NOT NULL,
accessor_role VARCHAR(50),
access_type ENUM('READ', 'UPDATE', 'EXPORT', 'DELETE') NOT NULL,
access_purpose VARCHAR(200),
accessed_fields TEXT, -- JSON: ["name", "email"]
access_ip VARCHAR(45),
accessed_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
INDEX idx_personal_info (personal_info_id),
INDEX idx_accessor (accessor_id),
INDEX idx_accessed_at (accessed_at)
);
-- 3. 보유기간 만료 데이터 파기 프로시저
DELIMITER //
CREATE PROCEDURE destroy_expired_personal_info()
BEGIN
DECLARE destroyed_count INT DEFAULT 0;
-- 트랜잭션 시작
START TRANSACTION;
-- 만료된 개인정보 파기 (복구 불가능하게 NULL 처리)
UPDATE personal_info
SET
name_encrypted = NULL,
email_encrypted = NULL,
phone_encrypted = NULL,
ssn_encrypted = NULL,
is_destroyed = TRUE,
destroyed_at = CURRENT_TIMESTAMP
WHERE
retention_expires_at < CURRENT_TIMESTAMP
AND is_destroyed = FALSE;
SET destroyed_count = ROW_COUNT();
-- 파기 이력 기록
INSERT INTO pi_destruction_log (
destruction_date,
destroyed_count,
destruction_method,
performed_by
) VALUES (
CURRENT_TIMESTAMP,
destroyed_count,
'AUTO_RETENTION_EXPIRY',
'SYSTEM'
);
COMMIT;
SELECT destroyed_count AS '파기된 개인정보 건수';
END //
DELIMITER ;
-- 4. 일별 자동 파기 이벤트 (MySQL Event Scheduler)
CREATE EVENT IF NOT EXISTS daily_pi_destruction
ON SCHEDULE EVERY 1 DAY
STARTS CURRENT_DATE + INTERVAL 1 DAY + INTERVAL 3 HOUR -- 매일 새벽 3시
DO
CALL destroy_expired_personal_info();
-- 5. 개인정보 접근 시 로깅 트리거
DELIMITER //
CREATE TRIGGER log_pi_access
AFTER SELECT ON personal_info
FOR EACH ROW
BEGIN
-- 접근 횟수 증가 및 마지막 접근 시간 업데이트
UPDATE personal_info
SET
access_count = access_count + 1,
last_accessed_at = CURRENT_TIMESTAMP
WHERE id = NEW.id;
END //
DELIMITER ;
-- 6. 개인정보 현황 리포트 (ISMS-P 심사용)
SELECT
collection_purpose AS '수집목적',
COUNT(*) AS '보유건수',
SUM(CASE WHEN is_destroyed = TRUE THEN 1 ELSE 0 END) AS '파기건수',
AVG(retention_period_days) AS '평균보유기간(일)',
MIN(collected_at) AS '최초수집일',
SUM(CASE
WHEN retention_expires_at < DATE_ADD(CURRENT_TIMESTAMP, INTERVAL 30 DAY)
AND is_destroyed = FALSE
THEN 1 ELSE 0
END) AS '30일내파기예정'
FROM personal_info
GROUP BY collection_purpose;
-- 7. 동의 현황 리포트
SELECT
'필수동의' AS '동의유형',
SUM(consent_required) AS '동의',
COUNT(*) - SUM(consent_required) AS '미동의'
FROM personal_info WHERE is_destroyed = FALSE
UNION ALL
SELECT
'마케팅동의',
SUM(consent_marketing),
COUNT(*) - SUM(consent_marketing)
FROM personal_info WHERE is_destroyed = FALSE
UNION ALL
SELECT
'제3자제공동의',
SUM(consent_third_party),
COUNT(*) - SUM(consent_third_party)
FROM personal_info WHERE is_destroyed = FALSE;
"ISMS-P 인증 심사 3개월 전이에요. 개인정보 처리 현황 파악부터 시작합시다. 어떤 개인정보를 어디서 수집하고, 누가 접근하고, 언제 파기하는지 전수 조사가 필요해요. 수집 동의서도 최신 법률에 맞게 업데이트해야 합니다."
"ML 모델 학습에 고객 데이터를 쓰려면 ISMS-P 개인정보 보호조치를 먼저 확인하세요. 학습 목적이 수집 동의 범위에 포함되는지, 가명처리가 필요한지, 학습 완료 후 원본 데이터 파기 절차는 어떻게 되는지 문서화해야 심사 대응이 됩니다."
"ISMS-P 사후관리 심사에서 개인정보 접근 로그 요청이 왔어요. 누가 언제 어떤 개인정보에 접근했는지 최소 6개월 로그를 제출해야 해요. 접근 권한 변경 이력, 비인가 접근 시도 탐지 현황도 준비해주세요."
개인정보보호법 위반으로 과태료 및 형사처벌 대상입니다. 수집 전 반드시 목적, 항목, 보유기간을 명시하고 동의를 획득하세요. 만 14세 미만은 법정대리인 동의가 필수입니다.
보유기간이 지난 개인정보는 지체없이(5일 이내) 파기해야 합니다. 자동 파기 시스템을 구축하고, 파기 이력을 3년간 보관하세요. 백업 데이터도 파기 대상입니다.
수집 목적과 다른 용도로 개인정보를 이용하면 안 됩니다. AI 학습, 마케팅, 제3자 제공은 별도 동의가 필요합니다. 가명처리 후 활용하더라도 재식별 위험을 평가하세요.
개인정보 처리 현황을 주기적으로 점검하고, 접근 권한은 최소한으로 부여하세요. 개인정보처리방침을 웹사이트에 상시 공개하고, 변경 시 정보주체에게 통지하세요. 연 1회 이상 개인정보보호 교육을 실시하세요.