0Pricing
AI Agents · 강의

규제 준수: GDPR 및 SOC2

규정을 준수하는 에이전트를 위해 데이터 최소화, 동의 추적, 접근 제어를 구현합니다.

규제 준수: GDPR 및 SOC2은(는) CoddyKit의 무료 AI Agents 강의입니다. 이것은 4개 중 3번째 강의입니다. 아래에서 전체 강의를 무료로 읽을 수 있으며, 내장 코드 에디터와 24/7 AI 튜터와 함께 브라우저에서 직접 실습할 수 있습니다. 이 강의는 AI Agents 학습 경로의 일부이며, 진행 상황이 웹과 CoddyKit 앱에 동기화됩니다. AI Agents 강의에는 총 4개의 강의가 포함되어 있습니다.

AI 에이전트에 규정이 적용되는 이유

AI 에이전트는 사용자 데이터를 처리하고, 결정을 내리며, 작업을 수행합니다. 따라서 데이터 보호 규정(GDPR)과 보안 프레임워크(SOC 2)의 직접적인 적용 범위에 포함됩니다.

COMPLIANCE는 선택 사항이 아닙니다. GDPR 위반 시 전 세계 연간 매출의 최대 4%에 해당하는 벌금이 부과될 수 있습니다.

GDPR: 데이터 최소화

GDPR의 데이터 최소화 원칙에 따르면 명시된 목적에 반드시 필요한 개인 데이터만 수집해야 합니다. 분석에 결과(해결됨/해결되지 않음)만 필요하다면 에이전트는 전체 대화 기록을 저장해서는 안 됩니다.

def minimized_log_entry(conversation: list[dict], user_id: str) -> dict:
    '''Store only what is needed — not the full transcript.'''
    return {
        'user_id':       user_id,
        'timestamp':     conversation[-1].get('timestamp'),
        'turns':         len(conversation),
        'resolved':      conversation[-1].get('resolved', False),
        'intent':        conversation[-1].get('intent'),
        'satisfaction':  conversation[-1].get('csat_score'),
        # NOT stored: full message text, PII mentioned in conversation
    }

# WRONG — stores raw messages which may contain PII
# {'messages': conversation, 'user_id': user_id}

if __name__ == '__main__':
    conversation = [
        {'timestamp': 1717000000, 'resolved': True, 'intent': 'reset_password', 'csat_score': 5}
    ]
    print('Minimized log entry:', minimized_log_entry(conversation, user_id='u42'))

GDPR: 동의 추적

에이전트가 개인 데이터를 처리하기 전에 법적 근거가 있어야 하며, 일반적으로는 사용자의 동의가 필요합니다. 동의가 언제 이루어졌는지, 어떤 범위에 적용되는지 추적하고, 철회 요청을 반영해야 합니다.

from datetime import datetime, timezone

consent_store: dict[str, dict] = {}  # user_id -> consent record

def record_consent(user_id: str, purpose: str, version: str = '1.0'):
    if user_id not in consent_store:
        consent_store[user_id] = {'purposes': {}}
    consent_store[user_id]['purposes'][purpose] = {
        'granted':     True,
        'timestamp':   datetime.now(timezone.utc).isoformat(),
        'version':     version
    }

def withdraw_consent(user_id: str, purpose: str):
    if user_id in consent_store:
        consent_store[user_id]['purposes'].pop(purpose, None)

def has_consent(user_id: str, purpose: str) -> bool:
    return bool(
        consent_store.get(user_id, {}).get('purposes', {}).get(purpose, {}).get('granted')
    )

if __name__ == '__main__':
    record_consent('u42', 'marketing_emails')
    print('Has consent:', has_consent('u42', 'marketing_emails'))
    withdraw_consent('u42', 'marketing_emails')
    print('Has consent after withdrawal:', has_consent('u42', 'marketing_emails'))

GDPR: 삭제 권리(잊힐 권리)

사용자가 삭제를 요청하면 에이전트는 해당 사용자와 관련된 모든 개인 데이터를 삭제해야 합니다. 여기에는 에이전트 로그, 대화 기록, 캐시된 프로필이 포함됩니다. 이 작업은 요청 후 30일 이내에 완료되어야 합니다.

import os

def erase_user_data(user_id: str, conn) -> dict:
    '''Delete all personal data for a user across all storage systems.'''
    deleted = {}

    # 1. Delete from audit log (if not using WORM storage)
    with conn.cursor() as cur:
        cur.execute('DELETE FROM agent_audit_log WHERE user_id = %s', (user_id,))
        deleted['audit_log_rows'] = cur.rowcount

    # 2. Delete conversation history
    with conn.cursor() as cur:
        cur.execute('DELETE FROM conversation_history WHERE user_id = %s', (user_id,))
        deleted['conversations'] = cur.rowcount

    # 3. Remove consent record
    consent_store.pop(user_id, None)
    deleted['consent_record'] = 1

    # 4. Clear cached profile
    profile_cache = {}  # reference to your cache
    profile_cache.pop(user_id, None)
    deleted['profile_cache'] = 1

    conn.commit()
    return {'user_id': user_id, 'erased': deleted}

GDPR: 데이터 이동성

사용자는 자신의 데이터를 기계가 읽을 수 있는 형식(예: JSON 또는 CSV)으로 받을 권리가 있습니다. 에이전트 시스템 전반에 해당 사용자에 관해 저장된 모든 데이터를 수집하는 내보내기 기능을 구축합니다.

import json

def export_user_data(user_id: str, conn) -> str:
    export = {'user_id': user_id, 'data': {}}

    with conn.cursor() as cur:
        cur.execute(
            'SELECT timestamp, action_type, result FROM agent_audit_log '
            'WHERE user_id = %s ORDER BY timestamp',
            (user_id,)
        )
        rows = cur.fetchall()
        export['data']['audit_log'] = [
            {'timestamp': r[0], 'action': r[1], 'result': r[2]}
            for r in rows
        ]

    export['data']['consent'] = consent_store.get(user_id, {})
    return json.dumps(export, indent=2)

SOC 2: 액세스 제어

SOC 2 Type II는 시스템과 데이터에 대한 액세스가 권한이 있는 사람으로 제한된다는 사실을 입증하도록 요구합니다. 에이전트의 경우 여기에는 에이전트 도구에 대한 역할 기반 액세스, 관리자 액세스를 위한 MFA, 정기적인 액세스 검토가 포함됩니다.

ROLE_PERMISSIONS = {
    'agent_basic':    {'web_search', 'read_file', 'query_database'},
    'agent_email':    {'web_search', 'read_file', 'query_database', 'send_email'},
    'agent_admin':    {'web_search', 'read_file', 'write_file', 'query_database',
                       'send_email', 'create_ticket', 'execute_python_sandbox'},
    'human_admin':    {'*'}  # all permissions
}

def get_permitted_actions(role: str) -> set:
    perms = ROLE_PERMISSIONS.get(role, set())
    if '*' in perms:
        return ALLOWED_ACTIONS  # reference to full allowlist
    return perms

def check_role_permission(role: str, action: str) -> bool:
    return action in get_permitted_actions(role)

SOC 2: 저장 및 전송 중 암호화

SOC 2에서는 저장된 데이터(데이터베이스 암호화, 암호화된 디스크)와 전송 중인 데이터(TLS 1.2 이상)를 암호화해야 합니다. 에이전트의 경우 암호화된 대화 저장소, 모든 애플리케이션 프로그래밍 인터페이스 호출에 적용되는 TLS, 로그에 평문으로 기록되지 않는 비밀 정보가 필요합니다.

from cryptography.fernet import Fernet
import os

# Key stored in environment variable, never in code
ENCRYPTION_KEY = os.environ.get('LOG_ENCRYPTION_KEY', Fernet.generate_key())
cipher = Fernet(ENCRYPTION_KEY)

def encrypt_sensitive_field(value: str) -> str:
    return cipher.encrypt(value.encode()).decode()

def decrypt_sensitive_field(encrypted: str) -> str:
    return cipher.decrypt(encrypted.encode()).decode()

# Usage: encrypt PII before storing in audit log
encrypted_email = encrypt_sensitive_field('user@example.com')
print(encrypted_email[:30], '...')  # starts with gAAAA...

SOC 2: 보안 이벤트 감사 로그

SOC 2 감사 담당자는 로그인 시도, 민감한 데이터에 대한 접근, 구성 변경, 정책 위반과 같은 보안 이벤트의 로그를 확인하려고 합니다. 이러한 로그는 안전하게 저장하고 최소 1년 동안 보존해야 합니다.

import logging, json, time

security_logger = logging.getLogger('agent.security')

SECURITY_EVENTS = {
    'auth_success', 'auth_failure', 'policy_violation',
    'data_access_pii', 'admin_action', 'config_change'
}

def log_security_event(event_type: str, agent_id: str,
                       user_id: str, details: dict):
    assert event_type in SECURITY_EVENTS, f'Unknown security event: {event_type}'
    entry = {
        'timestamp':  time.time(),
        'event_type': event_type,
        'agent_id':   agent_id,
        'user_id':    user_id,
        'details':    details
    }
    security_logger.warning(json.dumps(entry))

if __name__ == '__main__':
    import sys
    security_logger.addHandler(logging.StreamHandler(sys.stdout))
    log_security_event('auth_failure', 'agent-1', 'user-42', {'reason': 'bad_token'})

에이전트 출력의 PII 추적

에이전트는 로그에 기록되거나 제3자 서비스(분석, 모니터링)로 전송되는 출력에 PII를 포함해서는 안 됩니다. 전송하기 전에 발신 콘텐츠에서 PII 패턴을 검사하십시오.

import re

PII_PATTERNS = [
    (r'\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b', 'email'),
    (r'\b\d{3}[-.]?\d{3}[-.]?\d{4}\b',                         'phone'),
    (r'\b\d{4}[\s-]?\d{4}[\s-]?\d{4}[\s-]?\d{4}\b',           'credit_card'),
    (r'\b\d{3}-\d{2}-\d{4}\b',                                   'ssn')
]

def redact_pii(text: str) -> tuple[str, list[str]]:
    redacted = text
    found_types = []
    for pattern, pii_type in PII_PATTERNS:
        if re.search(pattern, redacted):
            found_types.append(pii_type)
            redacted = re.sub(pattern, f'[{pii_type.upper()}_REDACTED]', redacted)
    return redacted, found_types

text, types = redact_pii('Contact john@example.com or call 555-867-5309')
print(text)
print('PII found:', types)

준수 여부 점검 목록 작성

개인 데이터를 처리하는 에이전트를 배포하기 전에 다음 제어 항목이 마련되어 있는지 확인하십시오.

COMPLIANCE_CHECKLIST = [
    ('GDPR',  'Consent captured before processing personal data'),
    ('GDPR',  'Data minimization: only necessary data is collected'),
    ('GDPR',  'Right-to-erasure endpoint implemented and tested'),
    ('GDPR',  'Data portability export available'),
    ('GDPR',  'Data retention policy enforced (auto-delete after N days)'),
    ('SOC2',  'Role-based access control implemented for all agent tools'),
    ('SOC2',  'All data encrypted at rest and in transit (TLS 1.2+)'),
    ('SOC2',  'Security events logged and retained for 12+ months'),
    ('SOC2',  'Access reviews scheduled quarterly'),
    ('SOC2',  'Incident response plan documented'),
    ('BOTH',  'PII redaction applied to logs and analytics exports'),
    ('BOTH',  'Vendor DPAs signed for all third-party APIs used'),
]

for framework, control in COMPLIANCE_CHECKLIST:
    print(f'[ ] [{framework}] {control}')

데이터 보존 자동화

GDPR에서는 원래 목적에 더 이상 필요하지 않은 데이터를 삭제하도록 요구합니다. 구성 가능한 보존 기간을 기준으로 오래된 레코드를 삭제하는 보존 정책 작업으로 이 과정을 자동화하십시오.

from datetime import datetime, timedelta, timezone

RETENTION_POLICIES = {
    'conversation_history': 90,    # days
    'agent_audit_log':      365,
    'cached_profiles':      1,
    'session_data':         30
}

def purge_expired_data(conn):
    purged = {}
    for table, retention_days in RETENTION_POLICIES.items():
        cutoff = datetime.now(timezone.utc) - timedelta(days=retention_days)
        try:
            with conn.cursor() as cur:
                cur.execute(
                    f'DELETE FROM {table} WHERE timestamp < %s',
                    (cutoff.timestamp(),)
                )
                purged[table] = cur.rowcount
        except Exception as e:
            purged[table] = f'Error: {e}'
    conn.commit()
    return purged

if __name__ == '__main__':
    class FakeCursor:
        def __enter__(self):
            return self
        def __exit__(self, *exc):
            return False
        def execute(self, sql, params):
            self.rowcount = 3

    class FakeConn:
        def cursor(self):
            return FakeCursor()
        def commit(self):
            pass

    result = purge_expired_data(FakeConn())
    print('Rows purged per table:')
    for table, count in result.items():
        print(f'  {table}: {count}')

GDPR의 데이터 최소화 원칙이란 무엇인가?

데이터 최소화는 GDPR의 핵심 원칙 중 하나이며, 에이전트 시스템을 처음부터 어떻게 설계해야 하는지에 직접적인 영향을 줍니다.

GDPR 및 SOC 2 준수 요약

GDPR 준수에 필요한 사항은 동의 추적, 데이터 최소화, 삭제할 권리 구현, 데이터 이동성 내보내기, 로그에서의 PII 수정입니다.

SOC 2에 필요한 사항은 역할 기반 접근 제어, 저장 및 전송 중 암호화, 보안 이벤트 로그 기록, 접근 권한 검토입니다. 만료된 데이터를 삭제하도록 보존 정책을 자동화하십시오.

자주 묻는 질문

“규제 준수: GDPR 및 SOC2” 강의는 무료인가요?

네 — “규제 준수: GDPR 및 SOC2” 전체 내용을 이 웹사이트에서 무료로 읽을 수 있습니다. 인터랙티브하게 실습하려면(내장 코드 에디터와 24/7 AI 튜터), CoddyKit PRO로 업그레이드하면 AI Agents 강의 전체를 잠금 해제할 수 있습니다. AI Agents 강의에는 총 4개의 강의가 포함되어 있습니다.

“규제 준수: GDPR 및 SOC2”에서 뭘 배우나요?

규정을 준수하는 에이전트를 위해 데이터 최소화, 동의 추적, 접근 제어를 구현합니다. 브라우저에서 직접 실행하는 실습 코드로 AI Agents을(를) 배우며, 24/7 AI 튜터가 강의를 진행하면서 질문에 답변해줍니다.

AI Agents을(를) 시작하는 데 경험이 필요한가요?

사전 경험은 필요하지 않습니다. CoddyKit의 AI Agents은(는) 초급자부터 고급 학습자까지를 위해 구성되어 있으므로, 여기서 시작하거나 처음부터 시작할 수 있으며 자신의 속도대로 진행할 수 있습니다. 이것은 4개 중 3번째 강의입니다.

“규제 준수: GDPR 및 SOC2” 강의는 얼마나 걸리나요?

대부분의 CoddyKit 강의는 약 5~10분이 소요됩니다. 각 강의는 간결하고 인터랙티브하여 꾸준한 진행이 가능하며, 웹과 앱에서 중단한 부분부터 바로 시작할 수 있습니다.

이 AI Agents 강의에서 코드를 작성하고 실행할 수 있나요?

네. 모든 AI Agents 강의에는 내장 코드 에디터가 포함되어 있으므로, 브라우저에서 바로 실제 코드를 작성하고 실행한 후 즉시 AI 피드백을 받을 수 있습니다 — 로컬 설정이 필요 없습니다.

이 강의의 모든 강의

  1. 에이전트를 위한 변경 불가 작업 기록
  2. 에이전트 작업에 대한 정책 적용
  3. 규제 준수: GDPR 및 SOC2
  4. 사람 참여형 승인 관문
← AI Agents(으)로 돌아가기