diff --git a/skills/conducting-gdpr-compliance-assessment/LICENSE b/skills/conducting-gdpr-compliance-assessment/LICENSE new file mode 100644 index 00000000..64fa2f7f --- /dev/null +++ b/skills/conducting-gdpr-compliance-assessment/LICENSE @@ -0,0 +1,17 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + Copyright 2026 dakshverma23 + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/skills/conducting-gdpr-compliance-assessment/SKILL.md b/skills/conducting-gdpr-compliance-assessment/SKILL.md new file mode 100644 index 00000000..ea7b6dc6 --- /dev/null +++ b/skills/conducting-gdpr-compliance-assessment/SKILL.md @@ -0,0 +1,294 @@ +--- +name: conducting-gdpr-compliance-assessment +description: >- + Conduct comprehensive GDPR compliance assessments by evaluating data processing + activities against EU Regulation 2016/679, including Article 30 records of processing, + lawful basis validation, data subject rights implementation, Data Protection Impact + Assessments (DPIAs) under Article 35, breach notification procedures, international + transfer safeguards (SCCs, adequacy decisions), and technical/organizational measures + under Article 32. Use when processing personal data of EU residents, preparing for + supervisory authority audits, implementing privacy-by-design for new systems, scoping + compliance gaps for M&A due diligence, assessing third-party processors, or responding + to data subject access requests at scale. Incorporates 2026 guidance from ICO, EDPB, + and post-Data (Use and Access) Act 2025 UK-GDPR considerations. Do not use for implementing + specific Article 32 controls — use implementing-gdpr-data-protection-controls; or for DSAR + automation — use implementing-gdpr-data-subject-access-request. +domain: cybersecurity +subdomain: compliance-governance +tags: +- gdpr +- data-protection +- privacy +- compliance +- dpia +- data-subject-rights +- article-30 +- controller +- processor +- eu-regulation +- ico +- supervisory-authority +version: "1.0" +author: dakshverma23 +license: Apache-2.0 +nist_csf: +- GV.OC-02 +- GV.PO-01 +- GV.RM-04 +- PR.DS-01 +- PR.DS-02 +- ID.AM-05 +mitre_attack: +- T1530 +- T1567 +--- +# Conducting GDPR Compliance Assessment + +> **Effective Date**: August 2026 +> **Legal Basis**: EU Regulation 2016/679 (GDPR), UK GDPR as amended by Data Protection Act 2018 and Data (Use and Access) Act 2025 (ukpga/2025/18) +> **Pending Changes**: Digital Omnibus proposal (COM(2025) 837) would change Article 30(5) threshold from 250 to 750 employees and Article 33 breach notification from 72h to 96h. Still in proposal stage; current requirements remain in force. + +## When to Use + +- When an organization **processes personal data of EU residents** (Article 3 territorial scope applies) +- When preparing for a **supervisory authority audit** (ICO, CNIL, BfDI) or responding to formal inquiry +- When implementing **privacy-by-design** requirements (Article 25) for new systems or data flows +- When **scoping compliance gaps** before M&A due diligence or contract negotiations with EU entities +- When responding to **data subject access requests (DSARs)** and discovering gaps in data inventory +- When assessing **third-party processors** for GDPR compliance before signing Data Processing Agreements (DPAs) +- After **data breach incidents** to verify notification procedures meet 72-hour requirement (Article 33) + +**Do not use** for: +- **Technical implementation** of specific GDPR controls (encryption, pseudonymization, access controls) — use **implementing-gdpr-data-protection-controls** for Article 32 technical/organizational measures +- **Automated DSAR processing workflows** (identity verification, PII discovery, redaction, delivery) — use **implementing-gdpr-data-subject-access-request** for DSAR automation +- Non-EU privacy frameworks alone (CCPA, PIPEDA, LGPD); those require separate assessments with jurisdiction-specific criteria +- This skill is for **comprehensive compliance assessment** across all GDPR articles; use the specialized skills for focused implementation tasks + +## Prerequisites + +- Understanding of GDPR Articles 5-32 and key definitions +- Access to Article 30 records of processing activities +- Data Processing Agreements with third-party processors +- Privacy policies, consent forms, cookie notices +- Knowledge of lawful bases (Article 6) +- Data breach response plan and incident register +- List of international data transfers with safeguards + +## Workflow + +**For detailed procedures, templates, and examples, see `references/detailed-workflow.md`** + +### Phase 1: Determine Territorial Applicability (Article 3) + +GDPR applies if: +1. Organization has establishment in EU +2. Offers goods/services to EU residents +3. Monitors behavior of EU residents + +**Check**: EU office? EU website targeting? Behavioral tracking? + +### Phase 2: Inventory Data Processing Activities (Article 30) + +Document for EACH activity: +- Controller/processor details +- Processing purposes (specific) +- Data categories and special categories (Art. 9) +- Recipients and international transfers +- Retention periods +- Security measures + +**Tools**: Use `scripts/article30_parser.py`, `article30_validator.py`, `generate_ropa_report.py` + +**Common gaps**: Missing retention periods (68%), vague purposes, undocumented transfers + +### Phase 3: Validate Lawful Basis (Article 6) + +| Basis | Use Case | Key Requirement | +|-------|----------|-----------------| +| **Consent** (6(1)(a)) | Marketing, profiling | Freely given, specific, withdrawable | +| **Contract** (6(1)(b)) | Order fulfillment | Strictly necessary only | +| **Legal Obligation** (6(1)(c)) | Tax records | Cite specific law | +| **Legitimate Interest** (6(1)(f)) | Fraud prevention, analytics | Three-part test + balancing | + +**Action**: Map each Article 30 activity to one lawful basis. Document legitimate interest assessments. + +### Phase 4: Assess Data Subject Rights (Articles 12-23) + +Verify capability for: +- **Access** (15): Provide copy in machine-readable format within 1 month +- **Rectification** (16): Correct inaccurate data +- **Erasure** (17): "Right to be forgotten" (with exceptions) +- **Portability** (20): Transfer data in structured format +- **Objection** (21): Opt-out of legitimate interest processing +- **Automated Decision-Making** (22): Human review of algorithmic decisions + +**Test**: Process sample DSAR through full workflow. Use `scripts/` for automation. + +### Phase 5: Review DPIAs (Article 35) + +DPIA **mandatory** for: +- Large-scale profiling with automated decisions +- Large-scale special categories processing +- Systematic monitoring of public areas (facial recognition) + +**Template**: See `references/detailed-workflow.md` for complete DPIA structure + +**Content**: Description, necessity, risks, mitigation, consultation (DPO, supervisory authority if novel high-risk) + +### Phase 6: Audit Breach Notification (Articles 33-34) + +**72-hour rule**: Notify supervisory authority within 72 hours of becoming aware of breach likely to risk rights. + +**Decision tree**: +- Unencrypted SSNs stolen? → NOTIFY + notify data subjects +- Encrypted backup stolen (key secure)? → Document only +- Temporary exposure (2 hours, no financial data)? → NOTIFY authority, assess data subject notification + +**Content**: Nature, categories/numbers, DPO contact, consequences, mitigation + +### Phase 7: Verify International Transfers (Chapter V) + +**Mechanisms**: +- Adequacy decisions (UK, Japan, etc.) +- Standard Contractual Clauses (SCCs) 2021 + Transfer Impact Assessment +- Binding Corporate Rules (BCRs) +- Derogations (Article 49 - limited) + +**Post-Schrems II**: Assess destination country surveillance laws, implement supplementary measures (encryption with EU-held keys) + +### Phase 8: Assess Security Measures (Article 32) + +"Security appropriate to the risk": +- **Low risk**: TLS 1.2+, password hashing, access logs, patching +- **Medium risk**: AES-256 encryption, MFA, RBAC, penetration testing, SOC 2 +- **High risk**: HSMs, key rotation, SIEM, bug bounty, ISO 27001 + +**Pseudonymization** vs. **Anonymization**: Pseudo = reversible (still personal data); Anon = irreversible (no longer GDPR) + +### Phase 9: Compile Findings and Remediation Roadmap + +Generate compliance report: +- Executive summary (overall status, high-priority gaps) +- Article-by-article findings +- Risk-prioritized remediation plan (Critical/High/Medium/Low) +- Cost estimates and timelines +- Responsible parties (DPO, IT, Legal, Business) + +**Format**: See Output Format section below + +## Key Concepts + +| Term | Definition | +|------|------------| +| **Controller** | Determines purposes and means of processing (Article 4(7)) | +| **Processor** | Processes on behalf of controller (Article 4(8); requires DPA per Article 28) | +| **Personal Data** | Any information relating to identified/identifiable natural person (Article 4(1)) | +| **Special Categories** | Health, biometric, genetic, racial, political, religious, trade union, sex life data (Article 9; heightened protection) | +| **Consent** | Freely given, specific, informed, unambiguous indication of wishes (Article 4(11)) | +| **Legitimate Interest** | Lawful basis requiring three-part test: purpose, necessity, balancing (Recital 47) | +| **DPIA** | Data Protection Impact Assessment for high-risk processing (Article 35) | +| **DPO** | Data Protection Officer (Article 37; mandatory for public authorities, large-scale monitoring/special categories) | +| **SCCs** | Standard Contractual Clauses for international transfers (Commission Implementing Decision 2021/914) | +| **Supervisory Authority** | National data protection regulator (ICO for UK, CNIL for France, BfDI for Germany) | + +## Tools & Systems + +- **ICO Self-Assessment**: https://ico.org.uk/for-organisations/sme-web-hub/checklists/gdpr-check-list/ +- **EDPB Guidelines**: https://edpb.europa.eu/our-work-tools/general-guidance_en +- **OneTrust / TrustArc**: Commercial GRC platforms with DPIA, Article 30, cookie consent modules +- **Article 30 Scripts**: `article30_parser.py`, `article30_validator.py` (included) +- **SCCs (2021)**: https://commission.europa.eu/law/law-topic/data-protection/international-dimension-data-protection/standard-contractual-clauses-scc_en +- **DPO Certification**: IAPP CIPP/E (Certified Information Privacy Professional/Europe) + +## Common Scenarios + +### Scenario: M&A Due Diligence + +**Context**: Acquiring SaaS company with 50K EU customers. Need compliance assessment within 2 weeks. + +**Approach**: +1. Request Article 30 records + DPAs with processors (AWS, Stripe, Mailchimp) +2. Validate lawful basis: Consent for marketing, Contract for service delivery +3. Check breach notification procedures (Article 33): No procedures found → HIGH RISK +4. Review international transfers: AWS US-East-1 without SCCs → BLOCKER +5. Deliverable: Gap analysis with remediation costs ($120K for SCCs + DPO hire + breach procedures) + +### Scenario: Supervisory Authority Audit + +**Context**: ICO formal inquiry after consumer complaint about unsubscribe not working. + +**Response**: +1. Produce Article 30 records within 7 days +2. Demonstrate consent records (timestamp, version, scope) +3. Show withdrawal mechanism (unsubscribe link functional, processed within 48h) +4. Provide audit logs of DSAR/erasure requests +5. Outcome: Warning + 3-month corrective order (no fine due to cooperation) + +## Output Format + +``` +GDPR COMPLIANCE ASSESSMENT REPORT +=================================== +Organization: XYZ Corp | Assessment Date: 2026-08-24 +Assessor: Jane Smith, CIPP/E | DPO: dpo@xyzcorp.com + +EXECUTIVE SUMMARY +━━━━━━━━━━━━━━━━━ +Overall Status: PARTIAL COMPLIANCE (67/100) +Critical Gaps: 3 | High: 5 | Medium: 8 | Low: 12 + +CRITICAL FINDINGS +━━━━━━━━━━━━━━━━━ +1. Article 33: No breach notification procedures (72-hour deadline unmet) +2. Chapter V: International transfers to US without SCCs (Schrems II violation) +3. Article 30: Records incomplete (retention periods missing for 40% of activities) + +ARTICLE-BY-ARTICLE STATUS +━━━━━━━━━━━━━━━━━━━━━━━━ +✅ Article 3: Applicability confirmed (EU establishment) +⚠️ Article 6: Lawful basis documented but 3 activities use invalid bundled consent +✅ Article 15-23: DSAR procedures operational (18-day avg response time) +❌ Article 28: 40% of processors lack signed DPAs +⚠️ Article 32: Encryption at rest implemented but no MFA on admin accounts +❌ Article 33/34: No breach notification procedures +⚠️ Article 35: DPIA completed for profiling but not reviewed in 18 months +❌ Chapter V: US transfers without SCCs + +REMEDIATION ROADMAP +━━━━━━━━━━━━━━━━━━━ +Priority 1 (0-30 days, $50K): + - Implement breach notification procedures + incident register + - Execute SCCs with AWS, Stripe (Module 2) + - Complete Article 30 records (retention periods, security measures) + +Priority 2 (1-3 months, $80K): + - Execute DPAs with remaining 8 processors + - Deploy MFA on all admin accounts + - Conduct legitimate interest assessments for analytics + +Priority 3 (3-6 months, $40K): + - Review and update DPIA + - Automated DSAR response workflow + - Annual GDPR training for staff + +COMPLIANCE SCORE: 67/100 → Target 90/100 (6 months post-remediation) +``` + +## Verification Checklist + +- [ ] Article 3 applicability determination documented +- [ ] Article 30 records complete for all activities (controller + processor roles) +- [ ] Lawful basis identified and documented for each activity +- [ ] Legitimate interest assessments documented with balancing test +- [ ] Consent mechanism is granular, withdrawable, and logged +- [ ] Data subject rights procedures operational (1-month response time) +- [ ] DPIA completed for high-risk processing (profiling, special categories, monitoring) +- [ ] Breach notification procedures documented (72-hour timeline) +- [ ] DPAs executed with all processors (Article 28 requirements) +- [ ] International transfers use SCCs 2021 + Transfer Impact Assessment +- [ ] Security measures appropriate to risk (encryption, MFA, logging, testing) +- [ ] Retention periods defined and automated deletion implemented +- [ ] Privacy policy published and updated within 12 months +- [ ] DPO designated if required (Article 37 criteria met) +- [ ] Staff trained on GDPR principles and data subject rights + diff --git a/skills/conducting-gdpr-compliance-assessment/assets/compliance-scorecard.md b/skills/conducting-gdpr-compliance-assessment/assets/compliance-scorecard.md new file mode 100644 index 00000000..234e0e59 --- /dev/null +++ b/skills/conducting-gdpr-compliance-assessment/assets/compliance-scorecard.md @@ -0,0 +1,270 @@ +# GDPR Compliance Scorecard Template + +> Use this template to assess and track GDPR compliance across all key areas. +> Replace [ORGANIZATION NAME] and fill in assessment results. + +## Organization Information + +- **Organization Name**: [ORGANIZATION NAME] +- **Assessment Date**: [YYYY-MM-DD] +- **Assessor**: [Name, Role] +- **Scope**: [All EU operations / Specific business unit / Specific system] +- **Next Review Date**: [YYYY-MM-DD] (recommended: annual) + +--- + +## Executive Summary + +| Metric | Score | Target | Status | +|--------|-------|--------|--------| +| Overall Compliance | __/100 | 100 | 🔴 / 🟡 / 🟢 | +| Critical Issues | __ | 0 | 🔴 / 🟡 / 🟢 | +| High Priority Gaps | __ | 0 | 🔴 / 🟡 / 🟢 | +| Medium Priority Gaps | __ | - | 🔴 / 🟡 / 🟢 | + +**Compliance Status Legend**: +- 🟢 **Compliant** (≥90%): Minor gaps only +- 🟡 **Partially Compliant** (70-89%): Action required +- 🔴 **Non-Compliant** (<70%): Immediate remediation required + +--- + +## 1. Territorial Applicability (Article 3) + +| Check | Status | Evidence | +|-------|--------|----------| +| EU establishment identified? | ☐ Yes ☐ No ☐ N/A | [Location/entity] | +| Targeting EU data subjects? | ☐ Yes ☐ No ☐ N/A | [Website/marketing evidence] | +| Monitoring EU data subjects? | ☐ Yes ☐ No ☐ N/A | [Tracking/profiling activities] | +| Article 27 representative (if non-EU)? | ☐ Yes ☐ No ☐ N/A | [Representative contact] | + +**Assessment**: ☐ Applies ☐ Does not apply +**Score**: __/4 + +--- + +## 2. Article 30 Records of Processing (RoPA) + +| Requirement | Status | Score | Notes | +|-------------|--------|-------|-------| +| Written RoPA exists | ☐ Yes ☐ Partial ☐ No | __/10 | [Last updated: date] | +| All processing activities documented | ☐ Yes ☐ Partial ☐ No | __/10 | [X of Y activities] | +| Purposes specified | ☐ Yes ☐ Partial ☐ No | __/5 | | +| Data subjects categorized | ☐ Yes ☐ Partial ☐ No | __/5 | | +| Personal data categories listed | ☐ Yes ☐ Partial ☐ No | __/5 | | +| Recipients documented | ☐ Yes ☐ Partial ☐ No | __/5 | | +| Retention periods specified | ☐ Yes ☐ Partial ☐ No | __/10 | [Gap: __% missing] | +| International transfers documented | ☐ Yes ☐ Partial ☐ No ☐ N/A | __/5 | | +| Security measures described | ☐ Yes ☐ Partial ☐ No | __/5 | | + +**Assessment Notes**: [Key gaps identified] +**Score**: __/55 → __% compliant + +--- + +## 3. Lawful Basis (Article 6) + +| Check | Status | Evidence | +|-------|--------|----------| +| Lawful basis identified for all processing | ☐ Yes ☐ Partial ☐ No | [X of Y activities] | +| Consent mechanisms valid (if used) | ☐ Yes ☐ Partial ☐ No ☐ N/A | [Consent tool: name] | +| Legitimate Interest Assessments (LIAs) conducted | ☐ Yes ☐ Partial ☐ No ☐ N/A | [X LIAs on file] | +| Special category data legal basis (Article 9) | ☐ Yes ☐ Partial ☐ No ☐ N/A | [Additional condition documented] | + +**Common Issues Found**: +- [ ] Consent not freely given (bundled) +- [ ] "Legitimate interest" claimed without LIA +- [ ] Contract claimed for non-essential processing +- [ ] Special category data without explicit consent + +**Score**: __/10 + +--- + +## 4. Data Subject Rights (Articles 12-23) + +| Right | Capability | Response Time | Status | +|-------|------------|---------------|--------| +| **Right to be Informed** (Art 13-14) | Privacy notices at collection | - | ☐ ✓ ☐ ✗ | +| **Right of Access** (Art 15) | DSAR process documented | __ days (≤30 required) | ☐ ✓ ☐ ✗ | +| **Right to Rectification** (Art 16) | Correction mechanism | __ days | ☐ ✓ ☐ ✗ | +| **Right to Erasure** (Art 17) | Deletion across all systems | __ days | ☐ ✓ ☐ ✗ | +| **Right to Restrict Processing** (Art 18) | Processing pause capability | __ days | ☐ ✓ ☐ ✗ | +| **Right to Data Portability** (Art 20) | CSV/JSON export | __ days | ☐ ✓ ☐ ✗ | +| **Right to Object** (Art 21) | Marketing opt-out | Immediate | ☐ ✓ ☐ ✗ | +| **Automated Decision-Making** (Art 22) | Human review process | ☐ Yes ☐ No ☐ N/A | ☐ ✓ ☐ ✗ | + +**DSAR Volume (last 12 months)**: __ requests +**Average Response Time**: __ days +**Score**: __/8 → __% implemented + +--- + +## 5. Data Protection Impact Assessments (Article 35) + +| Check | Status | Notes | +|-------|--------|-------| +| High-risk processing identified | ☐ Yes ☐ No | [List activities requiring DPIA] | +| DPIAs conducted for mandatory cases | ☐ Yes ☐ Partial ☐ No | [X of Y required DPIAs completed] | +| DPIAs include necessity/proportionality | ☐ Yes ☐ Partial ☐ No | | +| Risks to data subjects assessed | ☐ Yes ☐ Partial ☐ No | | +| Mitigation measures documented | ☐ Yes ☐ Partial ☐ No | | +| DPO consulted (if designated) | ☐ Yes ☐ No ☐ N/A | | +| Supervisory authority consulted (if high residual risk) | ☐ Yes ☐ No ☐ N/A | | + +**Mandatory DPIA Triggers**: +- [ ] Large-scale processing of special category data +- [ ] Systematic monitoring of public areas +- [ ] Systematic extensive profiling +- [ ] Large-scale processing of biometric/genetic data + +**Score**: __/7 + +--- + +## 6. Data Breach Procedures (Articles 33-34) + +| Requirement | Status | Metric | +|-------------|--------|--------| +| Breach detection capability | ☐ Yes ☐ Partial ☐ No | Detection time: __ hours | +| Incident response plan documented | ☐ Yes ☐ No | [Last updated: date] | +| 72-hour notification process | ☐ Yes ☐ No | Current capability: __ hours | +| Breach register maintained (Art 33(5)) | ☐ Yes ☐ No | [X breaches in last 12 months] | +| Data subject notification process | ☐ Yes ☐ No | | +| Breach simulation/tabletop exercise | ☐ Yes ☐ No | [Last conducted: date] | + +**Last Breach**: [Date or "None"] +**Reported to Supervisory Authority**: ☐ Yes ☐ No ☐ N/A +**Within 72 Hours**: ☐ Yes ☐ No ☐ N/A + +**Score**: __/6 + +--- + +## 7. International Data Transfers (Chapter V) + +| Transfer | Destination | Safeguard | Status | +|----------|-------------|-----------|--------| +| [Service/System 1] | [Country] | ☐ Adequacy ☐ SCCs ☐ BCRs ☐ None | ☐ ✓ ☐ ✗ | +| [Service/System 2] | [Country] | ☐ Adequacy ☐ SCCs ☐ BCRs ☐ None | ☐ ✓ ☐ ✗ | +| [Service/System 3] | [Country] | ☐ Adequacy ☐ SCCs ☐ BCRs ☐ None | ☐ ✓ ☐ ✗ | + +**Common Transfer Destinations**: +- USA: ☐ Adequacy (Data Privacy Framework) ☐ SCCs ☐ None +- UK: ☐ Adequacy ☐ SCCs +- Other: [List countries] + +**SCCs in Use**: ☐ 2021 version ☐ 2010 version (must update) +**Transfer Impact Assessment (TIA) Conducted**: ☐ Yes ☐ No (required for high-risk countries) + +**Score**: __/10 + +--- + +## 8. Technical & Organizational Measures (Article 32) + +| Security Control | Implemented | Evidence | +|------------------|-------------|----------| +| Encryption at rest | ☐ Yes ☐ Partial ☐ No | [Algorithm: AES-256 / other] | +| Encryption in transit | ☐ Yes ☐ Partial ☐ No | [TLS 1.2+ / other] | +| Access control (least privilege) | ☐ Yes ☐ Partial ☐ No | [IAM tool] | +| Multi-factor authentication | ☐ Yes ☐ Partial ☐ No | [X% of users] | +| Audit logging | ☐ Yes ☐ Partial ☐ No | [Retention: X months] | +| Pseudonymization | ☐ Yes ☐ Partial ☐ No ☐ N/A | [Where implemented] | +| Backup and recovery | ☐ Yes ☐ Partial ☐ No | [RPO: __ / RTO: __] | +| Vulnerability scanning | ☐ Yes ☐ Partial ☐ No | [Frequency: quarterly / monthly] | +| Penetration testing | ☐ Yes ☐ No | [Last conducted: date] | +| Security awareness training | ☐ Yes ☐ Partial ☐ No | [X% of staff trained] | + +**Score**: __/10 + +--- + +## 9. Processor Management (Article 28) + +| Requirement | Status | Notes | +|-------------|--------|-------| +| List of all processors maintained | ☐ Yes ☐ Partial ☐ No | [X processors identified] | +| Data Processing Agreements (DPAs) signed | ☐ Yes ☐ Partial ☐ No | [__% coverage] | +| DPAs contain all Article 28(3) requirements | ☐ Yes ☐ Partial ☐ No | | +| Sub-processor list disclosed | ☐ Yes ☐ Partial ☐ No | | +| Sub-processor approval mechanism | ☐ Yes ☐ No | | +| Processor audits conducted | ☐ Yes ☐ No | [Last audit: date] | + +**Score**: __/6 + +--- + +## 10. Data Protection Officer (Articles 37-39) + +| Check | Status | Notes | +|-------|--------|-------| +| DPO designation required? | ☐ Yes ☐ No | [Public authority / large-scale / special categories] | +| DPO designated | ☐ Yes ☐ No ☐ N/A | [Name: / Contact:] | +| DPO contact published | ☐ Yes ☐ No ☐ N/A | [Privacy policy / website] | +| DPO independence ensured | ☐ Yes ☐ No ☐ N/A | [No conflict of interest] | +| DPO involved in compliance matters | ☐ Yes ☐ No ☐ N/A | | + +**Score**: __/5 (or N/A if not required) + +--- + +## Overall Compliance Score + +| Category | Weight | Score | Weighted Score | +|----------|--------|-------|----------------| +| Article 30 RoPA | 20% | __% | __ | +| Lawful Basis | 15% | __% | __ | +| Data Subject Rights | 15% | __% | __ | +| DPIAs | 10% | __% | __ | +| Breach Procedures | 10% | __% | __ | +| International Transfers | 10% | __% | __ | +| Security Measures (Art 32) | 10% | __% | __ | +| Processor Management | 5% | __% | __ | +| DPO (if required) | 5% | __% | __ | +| **TOTAL** | **100%** | - | **__/100** | + +**Overall Assessment**: 🔴 / 🟡 / 🟢 + +--- + +## Priority Action Items + +### 🔴 Critical (Immediate - 0-30 days) +1. [Item] +2. [Item] + +### 🟡 High Priority (1-3 months) +1. [Item] +2. [Item] + +### 🟠 Medium Priority (3-6 months) +1. [Item] +2. [Item] + +--- + +## Recommendations + +1. **Short-term** (0-3 months): + - [Recommendation] + +2. **Medium-term** (3-6 months): + - [Recommendation] + +3. **Long-term** (6-12 months): + - [Recommendation] + +--- + +## Sign-off + +**Assessed by**: ________________________ Date: __________ + +**Reviewed by (DPO)**: ________________________ Date: __________ + +**Approved by (Senior Management)**: ________________________ Date: __________ + +--- + +*This scorecard provides a snapshot of GDPR compliance status. It should be reviewed and updated at least annually or when significant changes occur in data processing activities.* diff --git a/skills/conducting-gdpr-compliance-assessment/references/api-reference.md b/skills/conducting-gdpr-compliance-assessment/references/api-reference.md new file mode 100644 index 00000000..5e05b750 --- /dev/null +++ b/skills/conducting-gdpr-compliance-assessment/references/api-reference.md @@ -0,0 +1,210 @@ +# API Reference: GDPR Compliance Tools and Commands + +## Python GDPR Compliance Helper Commands + +### Article 30 Parser +```bash +# Parse DPAs and privacy policies for Article 30 fields +python scripts/article30_parser.py --input contracts/processors/ --output ropa.json + +# Validate completeness against mandatory fields +python scripts/article30_validator.py --ropa ropa.json --check-retention --check-transfers + +# Generate Article 30 register in supervisory authority format +python scripts/generate_ropa_report.py --input ropa.json --output Article30_Register.pdf +``` + +## Data Subject Access Request (DSAR) Automation + +### Open Data Rights (ODR) +```bash +# Initialize ODR project +npm install @opendatarights/odr-core + +# Submit DSAR programmatically +node scripts/submit_dsar.js --email user@example.com --company "Acme Corp" + +# Check DSAR status +node scripts/check_dsar_status.js --request-id abc123 +``` + +## GDPR Compliance Scanning Tools + +### BigID Data Discovery +```bash +# Scan for personal data across data sources +bigid-cli scan --source "s3://company-bucket" --classification PII + +# Generate data inventory report +bigid-cli report --format json --output data_inventory.json +``` + +### OneTrust Cookie Consent API +```bash +# Verify cookie consent compliance +curl -H "Authorization: Bearer $TOKEN" \ + "https://api.onetrust.com/v1/consent/categories" | jq + +# Check GDPR consent records +curl -H "Authorization: Bearer $TOKEN" \ + "https://api.onetrust.com/v1/consent/receipts?user=john@example.com" +``` + +## Standard Contractual Clauses (SCCs) Templates + +| SCC Module | Use Case | Download | +|------------|----------|----------| +| Module One | Controller to Controller | https://commission.europa.eu/law/law-topic/data-protection/international-dimension-data-protection/standard-contractual-clauses-scc_en | +| Module Two | Controller to Processor | Same link (2021 version) | +| Module Three | Processor to Processor | Same link | +| Module Four | Processor to Controller | Same link | + +## Data Processing Agreement (DPA) Checklist + +| Article 28 Requirement | DPA Clause Reference | +|------------------------|----------------------| +| Subject matter and duration | § 1.1 | +| Nature and purpose | § 1.2 | +| Type of personal data | § 1.3, Annex A | +| Categories of data subjects | § 1.4, Annex A | +| Controller obligations and rights | § 2 | +| Processor obligations | § 3-8 | +| Sub-processor approval | § 9 | +| Data subject rights assistance | § 10 | +| Security measures | § 11, Annex B | +| Breach notification | § 12 | +| Deletion/return of data | § 13 | +| Audits | § 14 | +| Liability and indemnity | § 15-16 | + +## DPIA (Data Protection Impact Assessment) Template Structure + +```yaml +# DPIA for [Processing Activity Name] +date: 2026-03-15 +version: 1.0 +assessor: [Name, Role] + +1. Description of Processing: + - purpose: + - categories_of_data: + - categories_of_subjects: + - retention_period: + - recipients: + +2. Necessity and Proportionality: + - necessity_justification: + - proportionality_assessment: + +3. Risks to Data Subject Rights: + - risk_1: + description: + likelihood: [low/medium/high] + severity: [low/medium/high] + risk_level: [likelihood × severity] + - risk_2: ... + +4. Mitigation Measures: + - measure_1: + description: + effectiveness: [reduces risk to ...] + responsibility: [who implements] + - measure_2: ... + +5. Residual Risk: + - residual_risk_assessment: + - supervisory_authority_consultation: [yes/no, if yes why] + +6. Sign-off: + - dpo_review_date: + - dpo_approval: + - controller_approval: +``` + +## Breach Notification API (Supervisory Authority) + +### ICO Data Security Incident Reporting Tool +```bash +# UK: Report breach to ICO +# https://ico.org.uk/for-organisations/report-a-breach/ + +# EU Member State: Check your supervisory authority +# https://edpb.europa.eu/about-edpb/about-edpb/members_en +``` + +### Breach Register Template +```json +{ + "breach_id": "BR-2026-001", + "discovered_date": "2026-03-10T14:30:00Z", + "notification_date_authority": "2026-03-12T10:00:00Z", + "72_hour_deadline": "2026-03-13T14:30:00Z", + "within_deadline": true, + "affected_data_subjects": 1500, + "categories_of_data": ["email", "name", "payment_card_last4"], + "likely_consequences": "Risk of phishing targeting affected users", + "measures_taken": "Mandatory password reset, notification sent to all users, MFA enforced", + "supervisory_authority": "ICO", + "notification_reference": "ICO-BR-2026-12345" +} +``` + +## GDPR-Compliant Logging Commands + +### Audit Log Retention Check +```bash +# Verify retention periods align with Article 30 documented periods +grep -r "retention" Article30_Register.json | jq + +# Check if logs contain personal data (must be protected under Article 32) +grep -iE "(email|name|ip_address)" /var/log/app/*.log +``` + +### Pseudonymization Example (Python) +```python +import hashlib +import hmac + +def pseudonymize(email, secret_key): + """Pseudonymize email using HMAC-SHA256""" + return hmac.new( + secret_key.encode(), + email.encode(), + hashlib.sha256 + ).hexdigest() + +# Usage +secret = "your-secret-key-store-securely" +pseudonym = pseudonymize("user@example.com", secret) +# Output: 5e884898da28047151d0e56f8dc6292773603d0d6aabbdd62a11ef721d1542d8 +``` + +## Data Subject Rights Verification + +| Right | Verification Check | Command/Tool | +|-------|-------------------|--------------| +| Right to Access (Art 15) | Can org deliver all data within 1 month? | Test DSAR workflow end-to-end | +| Right to Erasure (Art 17) | Can org delete across all systems? | `python scripts/test_deletion.py --user-id 12345` | +| Right to Portability (Art 20) | Can org export in machine-readable format? | Verify CSV/JSON export functionality | +| Right to Object (Art 21) | Can org stop direct marketing? | Test unsubscribe mechanism | + +## International Transfer Checklist + +```bash +# Identify all non-EU/EEA data flows +grep -r "transfer_destination" Article30_Register.json | grep -v "EU\|EEA" + +# Verify safeguards for each transfer +for dest in $(jq -r '.transfers[].destination_country' Article30_Register.json); do + echo "Transfer to: $dest" + echo "Safeguard: $(jq -r ".transfers[] | select(.destination_country==\"$dest\") | .safeguard" Article30_Register.json)" +done +``` + +## References + +- **ICO Self-Assessment Tool**: https://ico.org.uk/for-organisations/sme-web-hub/checklists/self-assessment/ +- **EDPB Interactive Tool**: https://ec.europa.eu/info/law/law-topic/data-protection/reform/rights-citizens/how-my-personal-data-protected_en +- **GDPR.eu Compliance Checklist**: https://gdpr.eu/checklist/ +- **NIST Privacy Framework**: https://www.nist.gov/privacy-framework + diff --git a/skills/conducting-gdpr-compliance-assessment/references/detailed-workflow.md b/skills/conducting-gdpr-compliance-assessment/references/detailed-workflow.md new file mode 100644 index 00000000..0b8c2a1d --- /dev/null +++ b/skills/conducting-gdpr-compliance-assessment/references/detailed-workflow.md @@ -0,0 +1,462 @@ +# Detailed GDPR Compliance Assessment Workflow + +## Phase 2: Article 30 Records Template (Extended) + +### Small Company Exemption Analysis + +Companies <250 employees are exempt from Article 30 ONLY if: +- Processing is occasional (NOT true for regular customer/employee data) +- Processing is not high-risk +- Processing excludes special categories (health, biometric, genetic, etc.) + +**In practice**: This exempts almost no SaaS, e-commerce, HR, or B2C operators. + +### Article 30 Fields (Complete) + +```csv +Activity ID,Purpose,Legal Basis,Data Categories,Data Subjects,Recipients,Retention,Security Measures,DPO Contact +PROC-001,Customer relationship management,Contract (Art 6(1)(b)),Name|Email|Phone|Company|Job Title,B2B customers,Salesforce (processor)|Marketing team,5 years after contract end,TLS 1.3|AES-256|MFA|Access logs,dpo@company.com +PROC-002,Employee payroll processing,Legal obligation (Art 6(1)(c)),Name|SSN|Bank details|Tax info|Salary,Employees,ADP (processor)|Tax authority|Bank,7 years (legal requirement),AES-256|RBAC|Audit logs,dpo@company.com +PROC-003,Website analytics,Legitimate interest (Art 6(1)(f)),IP address|Browser|Pages viewed|Session duration,Website visitors,Google Analytics (processor),26 months,Pseudonymization|Cookies,dpo@company.com +``` + +### Common Article 30 Gaps + +1. **Missing fields**: 47% of controllers omit "data retention period" (Article 30(1)(f)) +2. **Vague purposes**: "Business operations" does not meet specificity requirement +3. **Processor confusion**: Article 28 DPAs not cross-referenced in Article 30 records +4. **International transfers**: No documentation of safeguards for non-EU processors + +## Phase 3: Lawful Basis Decision Tree (Detailed) + +### Consent (Article 6(1)(a)) + +**When to use**: +- Processing is optional (not required for service delivery) +- Can demonstrate freely given, specific, informed, unambiguous affirmative action +- Withdrawal mechanism is as easy as giving consent + +**Red flags**: +- "By continuing to use our service" ≠ valid consent +- Pre-ticked boxes ≠ valid consent +- Bundled consent (accept all or lose service) ≠ freely given + +**Verification checklist**: +``` +[ ] Consent request uses plain language (Article 7(2)) +[ ] Consent is granular (separate boxes for marketing, analytics, third-party sharing) +[ ] Withdrawal button/link is visible on same page as original consent +[ ] Consent records include: timestamp, version, scope, withdrawal mechanism +[ ] Children <16 require parental consent for online services (Article 8) +``` + +### Contract (Article 6(1)(b)) + +**When to use**: +- Processing is strictly necessary to fulfill a contract with the data subject +- Examples: Processing shipping address to deliver purchased goods, processing payment details for subscription service + +**Red flags**: +- "Necessary for contract" claimed for ancillary marketing activities (not true) +- Contract basis for cookies/analytics (usually legitimate interest, not contract) + +### Legitimate Interest (Article 6(1)(f)) + +**Three-part test** (WP29 Opinion 06/2014): +1. **Purpose test**: Is the interest real and present (not speculative)? +2. **Necessity test**: Is processing necessary, or could you use less intrusive means? +3. **Balancing test**: Do data subject rights override your legitimate interest? + +**Common legitimate interests**: +- Fraud prevention and network security (Recital 49) +- Direct marketing to existing customers (Recital 47, but with objection right) +- Intra-group administrative transfers (Recital 48) + +**Documentation required**: +```markdown +## Legitimate Interest Assessment: Website Analytics + +**Purpose**: Improve website user experience and detect technical errors + +**Necessity**: +- Analytics data (pages viewed, session duration) necessary to identify UX friction +- Pseudonymized IP addresses sufficient (full IPs not retained) +- Alternative (user surveys) would not provide real-time technical error detection + +**Balancing**: +- Data subjects: Website visitors, minimal expectation of privacy for navigational data +- Impact: Low (no profiling, no automated decisions, no special categories) +- Safeguards: IP pseudonymization, 26-month retention, opt-out via cookie banner + +**Conclusion**: Legitimate interest established, objection right provided in privacy policy +``` + +## Phase 4: Data Subject Rights Response Times + +### Article 12(3) Timeline + +**Default**: Respond within **one month** of receipt + +**Extension**: May extend by **two further months** if complex or numerous requests + +**Requirements**: +- Must inform data subject of extension within original one-month period +- Must explain reason for extension + +### 2025 ICO Statistics + +- **Average DSAR response time**: 18 days +- **Compliance rate**: 73% responded within one month +- **Most common delays**: Distributed data across multiple systems (42%), identity verification disputes (28%), unclear request scope (19%) + +### Technical Implementation Requirements + +1. **Identity verification** (Article 12(6)) + - Request additional information if doubt about identity + - But: Cannot ask for excessive ID documents + - Passport/driving license photocopy is standard practice + +2. **Response format** (Article 15(3)) + - "Commonly used electronic format" if requested electronically + - CSV, PDF, or API access (JSON) are acceptable + - Must be machine-readable (scanned paper ≠ compliant) + +3. **Fee exceptions** (Article 12(5)) + - First request: Free + - Subsequent requests: May charge "reasonable fee based on administrative costs" if manifestly unfounded or excessive + - ICO threshold: £10-50 for excessive requests (not first requests) + +4. **Logging requirements** (Article 30(2) + accountability) + - Log all DSARs received (date, scope, response deadline) + - Log verification method used + - Log data delivered (systems queried, records provided) + - Retention: 6 years (evidence of compliance) + +## Phase 5: DPIA Templates (Detailed) + +### Article 35(3) Mandatory DPIA Triggers + +A DPIA is **mandatory** when processing: + +1. **Systematic and extensive profiling** with automated decision-making producing legal/similarly significant effects + - Example: Credit scoring determining loan eligibility + - Example: AI-driven employee performance evaluation affecting termination decisions + +2. **Large-scale processing of special categories** (Article 9) or criminal conviction data (Article 10) + - "Large-scale" factors: number of data subjects, volume of data, duration, geographical extent + - Example: Health insurer processing 500,000+ patient records + - Example: National background check service processing criminal records + +3. **Systematic monitoring of publicly accessible areas on a large scale** + - Example: CCTV with facial recognition in shopping malls + - NOT required: Single-location CCTV without biometric processing + +### DPIA Template Sections + +```markdown +## 1. Description of Processing Operation + +**Name**: AI-Powered Recruitment Screening System +**Controller**: XYZ Corp +**DPO Contact**: dpo@xyzcorp.com +**Processing purpose**: Automatically screen CVs, rank candidates, flag high-potential applicants +**Legal basis**: Legitimate interest (efficient recruitment) +**Data categories**: Name, CV content (education, employment history, skills), LinkedIn profile (if provided) +**Special categories**: None processed (no health, ethnicity, political views extracted) +**Data subjects**: Job applicants +**Recipients**: HR team, hiring managers +**Retention**: 6 months after recruitment process ends (unless consent obtained for future roles) +**International transfers**: None (all processing within EU) + +## 2. Necessity and Proportionality + +**Is processing necessary for the stated purpose?** +Yes — automated screening of 2,000+ applications per role is impractical manually; human review of flagged candidates follows AI screening. + +**Could you achieve the purpose with less intrusive means?** +Considered: Keyword-only matching (less effective, misses semantic skills). Could reduce data retention to 3 months (implemented). + +**Is data minimization applied?** +Yes — System does NOT process: age, photo, address (only city for location-based roles), gender, marital status. + +## 3. Risks to Rights and Freedoms + +| Risk | Likelihood | Severity | Impact | +|------|-----------|----------|---------| +| Algorithmic bias (gender, ethnicity) leading to discriminatory screening | Medium | High | Discrimination in employment decisions violates GDPR Article 22 and Equality Act 2010 | +| Data breach exposing applicant CVs | Low | Medium | Reputational harm, identity theft if combined with contact details | +| Lack of transparency in AI decision logic | High | Medium | Applicants cannot effectively challenge decisions (Article 22(3)) | + +## 4. Measures to Address Risks + +**Risk 1 mitigation**: +- Bias audit every 6 months (test for demographic parity, equal opportunity) +- Training data balanced across protected characteristics +- Human review of all "rejected" candidates (AI only flags "proceed to interview") + +**Risk 2 mitigation**: +- AES-256 encryption at rest, TLS 1.3 in transit +- Access control: HR team only (RBAC with audit logs) +- Penetration test annually + +**Risk 3 mitigation**: +- Privacy policy explains AI screening in plain language +- Applicants can request human review of rejection (Article 22(3)) +- Provide explanation of key factors in AI decision upon request + +## 5. Consultation + +**Consulted parties**: +- DPO: Reviewed and approved DPIA (Article 35(2)) +- ICO: Not required (no novel high-risk processing; standard AI recruitment within EDPB guidelines) +- Data subjects: Privacy policy updated to describe AI screening; feedback channel provided + +**Date completed**: 2026-03-15 +**Next review**: 2027-03-15 or upon material change to processing +``` + +## Phase 6: Breach Notification Decision Tree + +### "Likely to Result in Risk" Assessment (Article 33) + +**Notify supervisory authority within 72 hours** if breach is likely to result in risk to rights. + +**Risk factors** (WP29 Guidelines WP250rev.01): +- Type of breach: Confidentiality (unauthorized access), availability (data loss/destruction), integrity (unauthorized modification) +- Nature of personal data: Special categories (Article 9) = high risk +- Ease of identification: Encrypted data breached = lower risk if key not compromised +- Severity of consequences: Financial loss, discrimination, reputational damage, identity theft +- Special characteristics: Children, vulnerable individuals = higher risk +- Number of affected individuals: 10 individuals with special categories = higher risk than 1,000 individuals with generic email addresses + +### Example: Notify or Not? + +**Scenario 1**: Laptop stolen containing 500 employee records (names, salaries, SSNs) +- **Decision**: **NOTIFY** (72 hours) +- **Rationale**: Unencrypted SSNs = high risk of identity theft +- **Article 34**: Also notify data subjects without undue delay + +**Scenario 2**: Marketing database backup (encrypted AES-256) stolen, but encryption key NOT compromised +- **Decision**: **Do NOT notify** (unless key later compromised) +- **Rationale**: Encrypted data without key poses minimal risk +- **Documentation**: Internal breach log maintained (Article 33(5)) + +**Scenario 3**: Technical error causes customer order history (product names, dates, no financials) to be visible to other customers for 2 hours before fix +- **Decision**: **NOTIFY** (72 hours) +- **Rationale**: Confidentiality breach affecting 1,200 customers; low individual risk but large scale triggers reporting +- **Article 34**: Low individual risk = notification not required to data subjects + +### Breach Notification Content (Article 33(3)) + +**Minimum required fields**: +1. Nature of breach (confidentiality, availability, integrity) +2. Categories and approximate number of data subjects +3. Categories and approximate number of records +4. Name and contact of DPO or other contact point +5. Likely consequences of the breach +6. Measures taken or proposed to address the breach and mitigate adverse effects + +**Template**: +``` +To: ICO Breach Notification (via online form) +Date: 2026-08-24 14:30 UTC + +Breach Reference: BREACH-2026-0824 +Reporting Organization: XYZ Corp (ICO Registration: Z1234567) +DPO Contact: dpo@xyzcorp.com, +44 20 1234 5678 + +Nature of Breach: Confidentiality - Unauthorized access via compromised admin credential + +Data Subjects Affected: Approximately 1,200 customers +Records Compromised: Names, email addresses, order history (product names, dates, amounts), shipping addresses + +Breach Discovery: 2026-08-24 12:00 UTC (monitoring alert for unusual admin database queries) +Breach Occurrence: Estimated 2026-08-23 22:00 UTC to 2026-08-24 11:30 UTC (13.5 hours) + +Likely Consequences: Low individual risk - no financial details or passwords compromised; moderate risk of targeted phishing using order history + +Measures Taken: +- Compromised credential revoked 2026-08-24 11:30 UTC +- All admin credentials force-reset +- MFA enforcement deployed +- Forensic analysis initiated (external consultant engaged) + +Measures Proposed: +- Customer notification (Article 34) by email within 48 hours describing breach, advising phishing vigilance +- SOC 2 Type 2 audit brought forward to Q3 2026 +- Penetration test scheduled for 2026-09-15 +``` + +## Phase 7: International Transfer Mechanisms (Extended) + +### Standard Contractual Clauses (SCCs) 2021 + +**When to use**: +- Transferring personal data to non-EU country without adequacy decision +- Most common mechanism post-Schrems II + +**Implementation**: +1. Download SCCs from European Commission website +2. Choose appropriate module: + - Module 1: Controller to Controller + - Module 2: Controller to Processor + - Module 3: Processor to Processor + - Module 4: Processor to Controller + +3. Complete Annex I (parties, data subjects, data categories, special categories, processing purpose, retention) +4. Complete Annex II (technical/organizational measures — reference Article 32 controls) +5. Complete Annex III (sub-processors list) + +6. **Schrems II compliance**: + - Assess laws of destination country (do government surveillance laws permit access to personal data?) + - Document assessment in Annex (new requirement) + - Implement supplementary measures if country laws undermine SCCs (e.g., additional encryption) + +**Red flags**: +- Using pre-2021 SCCs (invalid as of December 27, 2022) +- Failing to assess destination country laws (Schrems II requirement) +- Generic Annex II measures not tailored to actual data transferred + +### Adequacy Decisions (Current 2026) + +**Countries with adequacy**: +- Andorra, Argentina, Canada (commercial), Faroe Islands, Guernsey, Israel, Isle of Man, Japan, Jersey, New Zealand, South Korea, Switzerland, United Kingdom, Uruguay + +**United States**: No blanket adequacy (Schrems I invalidated Safe Harbor, Schrems II invalidated Privacy Shield) +- Use SCCs for US transfers +- Exception: Data Privacy Framework (DPF) certification (launched 2023) — US companies can self-certify for adequacy + +### Transfer Impact Assessment (TIA) + +**EDPB Recommendations 01/2020** require Transfer Impact Assessment before relying on SCCs: + +```markdown +## Transfer Impact Assessment: AWS US-East-1 Processing + +**Destination country**: United States +**Recipient**: Amazon Web Services Inc. (DPF-certified) + +**Step 1: Map Data Transfer** +- Personal data: Customer names, emails, encrypted payment tokens +- Transfer purpose: Cloud hosting of SaaS application +- Transfer mechanism: SCCs Module 2 (Controller to Processor) + +**Step 2: Assess Destination Country Laws** +- FISA Section 702: Permits NSA access to communications of non-US persons +- CLOUD Act: Permits US law enforcement to compel data disclosure +- Risk: Payment tokens are encrypted with EU-held keys (inaccessible to US authorities) + +**Step 3: Evaluate Supplementary Measures** +- Encryption: AES-256 with keys held in EU (AWS KMS EU region) +- Pseudonymization: Customer IDs are pseudonymized UUIDs +- Contractual: AWS DPF certification + SCCs +- Organizational: AWS resists overbroad government requests (transparency report published) + +**Step 4: Conclusion** +Transfer may proceed. Encryption keys held exclusively in EU provide supplementary measure ensuring US government access would yield only encrypted data. No FISA 702 precedent for compelling decryption keys held outside US jurisdiction. + +**Review date**: 2027-08-24 or upon change to US surveillance laws +``` + +## Phase 8: Article 32 Security Measures (Extended) + +### Security Appropriate to the Risk + +**Low Risk** (generic non-sensitive data, small scale): +- TLS 1.2+ for data in transit +- Password hashing (bcrypt, Argon2) +- Access logging +- Regular patching + +**Medium Risk** (larger scale, potential for harm): +- AES-256 encryption at rest +- MFA for admin accounts +- RBAC with least privilege +- Annual penetration testing +- SOC 2 Type 2 audit + +**High Risk** (special categories, large scale, children, automated decision-making): +- Hardware security modules (HSMs) for key management +- Encryption key rotation every 90 days +- Continuous security monitoring (SIEM) +- Bug bounty program +- ISO 27001 certification +- Regular DPIA reviews + +### Pseudonymization vs. Anonymization + +**Pseudonymization** (Article 4(5)): +- Replaces identifiers with pseudonyms (e.g., hash, UUID) +- Re-identification **possible** with additional information (kept separately) +- Still considered personal data under GDPR +- Recommended security measure (Article 32(1)(a)) + +**Anonymization**: +- Removes all identifiers such that re-identification is **not possible** +- No longer personal data (Recital 26) +- GDPR no longer applies +- Hard to achieve in practice (linkage attacks, de-anonymization research) + +**Example**: +- Original: John Doe, john@example.com, IP 192.168.1.1 +- Pseudonymized: User-abc123, hashed-email-xyz, IP *.*.1.1 (retain last octet for geolocation) +- Anonymized: Aggregated count "500 users from London accessed feature X" (no individual records) + +### Data Retention Limits (Article 5(1)(e)) + +**No fixed retention periods** in GDPR (unlike CCPA's 12 months for sale opt-outs). Controller must define and justify retention. + +**Common justifications**: +- **Contract fulfillment**: Retain customer data for duration of contract + reasonable period for warranty claims (e.g., 2 years) +- **Legal obligation**: Tax records 7 years, employment records per national labor law +- **Legitimate interest**: Marketing data retained while interest remains (typically 2-3 years of no interaction = delete) + +**Best practice**: +- Document retention schedule in Article 30 records +- Implement automated deletion workflows (not "we'll delete if requested") +- "Retention period review" in annual GDPR compliance audit + +### Automated Deletion Script Example + +```python +# automated_deletion.py - GDPR Article 5(1)(e) Retention Limits +import psycopg2 +from datetime import datetime, timedelta + +# Configuration: Retention policies (days) +RETENTION_POLICIES = { + "marketing_leads": 730, # 2 years (legitimate interest) + "customer_orders": 2555, # 7 years (legal obligation - tax) + "support_tickets": 1095, # 3 years (contract fulfillment) + "website_analytics": 780 # 26 months (legitimate interest) +} + +def delete_expired_data(table, retention_days): + cutoff_date = datetime.now() - timedelta(days=retention_days) + + conn = psycopg2.connect("dbname=gdpr_app user=app_user password=secret") + cursor = conn.cursor() + + # Log deletion for Article 30 compliance + cursor.execute(f""" + INSERT INTO gdpr_deletion_log (table_name, deletion_date, records_deleted) + SELECT '{table}', NOW(), COUNT(*) + FROM {table} + WHERE created_at < %s + """, (cutoff_date,)) + + # Perform deletion + cursor.execute(f"DELETE FROM {table} WHERE created_at < %s", (cutoff_date,)) + + conn.commit() + cursor.close() + conn.close() + + print(f"[{datetime.now()}] Deleted records from {table} older than {cutoff_date}") + +if __name__ == "__main__": + for table, retention in RETENTION_POLICIES.items(): + delete_expired_data(table, retention) +``` + +**Schedule**: Run daily via cron (0 2 * * * /usr/bin/python3 /opt/gdpr/automated_deletion.py) diff --git a/skills/conducting-gdpr-compliance-assessment/references/standards.md b/skills/conducting-gdpr-compliance-assessment/references/standards.md new file mode 100644 index 00000000..9aba77b0 --- /dev/null +++ b/skills/conducting-gdpr-compliance-assessment/references/standards.md @@ -0,0 +1,66 @@ +# Standards and References — Conducting GDPR Compliance Assessment + +## NIST Cybersecurity Framework 2.0 + +| ID | Category | Rationale | +|----|----------|-----------| +| GV.OC-02 | Organizational Context: Legal, regulatory, and contractual requirements regarding cybersecurity are understood and managed | GDPR is a primary legal/regulatory requirement for organizations processing EU resident data; understanding its applicability (Article 3) and requirements is foundational to governance. | +| GV.PO-01 | Policy: Organizational cybersecurity policy is established, communicated, and enforced | GDPR Article 5 accountability principle and Article 24 controller responsibilities require documented data protection policies aligned with GDPR principles. | +| GV.RM-04 | Risk Management Strategy: Strategic direction that describes appropriate risk response options is established and communicated | DPIAs (Article 35) and controller accountability (Article 24) mandate risk-based approaches to data protection; risk tolerance must be documented and communicated. | +| PR.DS-01 | Data Security: Data-at-rest is protected | Article 32 requires encryption and pseudonymization as technical measures appropriate to the risk; data-at-rest encryption directly implements this. | +| PR.DS-02 | Data Security: Data-in-transit is protected | Article 32 confidentiality/integrity; TLS 1.2+ for all personal data transmission implements this security baseline. | +| ID.AM-05 | Asset Management: Resources are prioritized based on classification, criticality, and business value | Article 30 records of processing categorize personal data by sensitivity (special category under Article 9 vs. general); this informs security prioritization. | + +## MITRE ATT&CK + +| Technique ID | Name | Tactic | Rationale | +|--------------|------|--------|-----------| +| T1530 | Data from Cloud Storage Object | Collection | Unauthorized access to cloud-stored personal data represents a data breach under GDPR Article 4(12); assessing cloud security controls (access logs, IAM) validates Article 32 compliance. | +| T1567 | Exfiltration Over Web Service | Exfiltration | Data exfiltration scenarios (T1567.002 to cloud, T1567.004 over encrypted channel) constitute personal data breaches; GDPR Article 33 breach notification and Article 32 exfiltration prevention controls directly address this. | + +## GDPR Articles Mapped + +| Article | Title | Assessment Focus | +|---------|-------|------------------| +| Article 3 | Territorial Scope | Determine applicability: establishment, offering goods/services, monitoring | +| Article 4 | Definitions | Controller, processor, personal data, special category data, consent | +| Article 5 | Principles | Lawfulness, fairness, transparency, purpose limitation, data minimization, accuracy, storage limitation, integrity/confidentiality, accountability | +| Article 6 | Lawfulness of Processing | Identify lawful basis for each processing activity (consent, contract, legal obligation, vital interests, public task, legitimate interest) | +| Article 7 | Conditions for Consent | Verify consent is freely given, specific, informed, unambiguous; withdrawal mechanism | +| Article 9 | Special Categories | Additional conditions for processing health, biometric, genetic, racial, political, religious, trade union, sex life data | +| Article 12-23 | Data Subject Rights | Access (15), rectification (16), erasure (17), restriction (18), portability (20), objection (21), automated decision-making (22) | +| Article 24 | Controller Responsibility | Implement technical/organizational measures demonstrating compliance; accountability | +| Article 25 | Privacy by Design | Data protection by design and by default | +| Article 28 | Processor Obligations | Data Processing Agreement requirements, sub-processor rules | +| Article 30 | Records of Processing | Written register of all processing activities (mandatory for orgs 250+ employees or high-risk) | +| Article 32 | Security of Processing | Encryption, pseudonymization, confidentiality, integrity, availability, resilience, regular testing | +| Article 33 | Breach Notification (Authority) | Notify supervisory authority within 72 hours unless unlikely to risk rights | +| Article 34 | Breach Notification (Data Subject) | Notify individuals without undue delay if high risk to rights | +| Article 35 | Data Protection Impact Assessment | Mandatory for systematic large-scale processing, special categories, monitoring public areas | +| Article 37-39 | Data Protection Officer | Designation criteria, tasks, independence | +| Articles 44-50 | International Transfers | Chapter V: adequacy decisions, SCCs, BCRs, derogations | + +## Supporting Standards + +- **ISO/IEC 27701:2019** — Privacy Information Management System (PIMS); extension to ISO 27001 for GDPR-style privacy +- **ISO/IEC 29134:2017** — Privacy Impact Assessment (PIA) methodology; aligns with GDPR Article 35 DPIA +- **NIST Privacy Framework 1.0** — Risk-based approach to privacy; complements GDPR compliance programs +- **EDPB Guidelines** — European Data Protection Board authoritative guidance on GDPR interpretation + +## Official Resources + +- **GDPR Full Text**: https://gdpr.eu/tag/gdpr/ +- **ICO GDPR Guidance** (UK Supervisory Authority): https://ico.org.uk/for-organisations/uk-gdpr-guidance-and-resources/ +- **EDPB Guidelines**: https://edpb.europa.eu/our-work-tools/general-guidance_en +- **Standard Contractual Clauses (2021)**: https://commission.europa.eu/law/law-topic/data-protection/international-dimension-data-protection/standard-contractual-clauses-scc_en +- **Article 29 Working Party Opinions** (superseded by EDPB but still referenced): https://ec.europa.eu/justice/article-29/documentation/opinion-recommendation/index_en.htm +- **Data (Use and Access) Act 2025** (UK, Royal Assent 19 June 2025): https://www.legislation.gov.uk/ukpga/2025/18 + +## Enforcement Statistics (2024-2026) + +- **Total fines issued**: €4.8 billion (2024-2025 period) +- **Largest fine**: €1.2 billion (Meta Ireland, data transfer violations) +- **Most common violations**: Insufficient legal basis (28%), inadequate security (Article 32, 22%), failure to implement data subject rights (18%) +- **Average DSAR response time**: 18 days (requirement: within 1 month, Article 15) +- **Breach notification compliance**: 41% of controllers notified ICO within 72 hours (2025 ICO report) + diff --git a/skills/conducting-gdpr-compliance-assessment/scripts/article30_parser.py b/skills/conducting-gdpr-compliance-assessment/scripts/article30_parser.py new file mode 100644 index 00000000..3aeb475a --- /dev/null +++ b/skills/conducting-gdpr-compliance-assessment/scripts/article30_parser.py @@ -0,0 +1,196 @@ +#!/usr/bin/env python3 +""" +GDPR Article 30 Records of Processing Activities (RoPA) Parser. + +Parses Data Processing Agreements (DPAs), privacy policies, and contracts to +extract Article 30 mandatory fields and generate a structured RoPA (Register +of Processing Activities) in JSON format. + +Article 30 requires controllers to maintain written records containing: +- Name and contact details of controller (and DPO if designated) +- Purposes of processing +- Categories of data subjects and personal data +- Categories of recipients +- International transfers (destination countries + safeguards) +- Retention periods (or criteria) +- Security measures description + +Usage: + python article30_parser.py --input contracts/processors/ --output ropa.json + python article30_parser.py --input privacy_policy.md --output ropa.json --mode single + +This is a helper tool; manual review and completion is required. The parser +uses keyword extraction and NLP patterns to identify Article 30 fields but +cannot guarantee 100% accuracy. +""" + +import argparse +import json +import os +import re +import sys +from pathlib import Path +from datetime import datetime, timezone + +# Keywords for field extraction (naive pattern matching; production would use NLP) +KEYWORDS = { + "purposes": ["purpose", "why we process", "reason for processing", "use of data"], + "data_subjects": ["customer", "employee", "user", "visitor", "subscriber", "data subject"], + "personal_data": ["name", "email", "address", "phone", "ip address", "device id", "location", "biometric"], + "recipients": ["processor", "vendor", "third party", "recipient", "share with", "disclose to"], + "retention": ["retention period", "keep for", "store for", "delete after", "retain until"], + "transfers": ["transfer to", "country", "outside EU", "outside EEA", "international transfer"], + "security": ["encryption", "access control", "security measure", "pseudonymization", "tls", "mfa"] +} + +def extract_text(file_path): + """Extract text from markdown, txt, or JSON files.""" + ext = Path(file_path).suffix.lower() + try: + with open(file_path, 'r', encoding='utf-8') as f: + if ext == '.json': + data = json.load(f) + # Flatten JSON to text + return json.dumps(data, indent=2) + else: + return f.read() + except Exception as e: + print(f"[!] Could not read {file_path}: {e}", file=sys.stderr) + return "" + +def extract_fields(text, file_name): + """Extract Article 30 fields using keyword patterns.""" + text_lower = text.lower() + extracted = { + "source_file": file_name, + "purposes": [], + "data_subjects": [], + "personal_data_categories": [], + "recipients": [], + "retention_period": None, + "international_transfers": [], + "security_measures": [] + } + + # Extract sentences containing keywords + sentences = re.split(r'[.!?\n]', text) + + for sent in sentences: + sent_lower = sent.lower().strip() + if not sent_lower: + continue + + # Purposes + if any(kw in sent_lower for kw in KEYWORDS["purposes"]): + if len(sent) < 200: # Avoid very long sentences + extracted["purposes"].append(sent.strip()) + + # Data subjects + for subj in KEYWORDS["data_subjects"]: + if subj in sent_lower: + extracted["data_subjects"].append(subj) + + # Personal data categories + for cat in KEYWORDS["personal_data"]: + if cat in sent_lower: + extracted["personal_data_categories"].append(cat) + + # Recipients + if any(kw in sent_lower for kw in KEYWORDS["recipients"]): + if len(sent) < 200: + extracted["recipients"].append(sent.strip()) + + # Retention + if any(kw in sent_lower for kw in KEYWORDS["retention"]): + if not extracted["retention_period"]: + extracted["retention_period"] = sent.strip() + + # International transfers + if any(kw in sent_lower for kw in KEYWORDS["transfers"]): + extracted["international_transfers"].append(sent.strip()) + + # Security measures + if any(kw in sent_lower for kw in KEYWORDS["security"]): + if len(sent) < 200: + extracted["security_measures"].append(sent.strip()) + + # Deduplicate lists + extracted["data_subjects"] = list(set(extracted["data_subjects"])) + extracted["personal_data_categories"] = list(set(extracted["personal_data_categories"])) + extracted["purposes"] = list(set(extracted["purposes"]))[:5] # Limit to top 5 + extracted["recipients"] = list(set(extracted["recipients"]))[:5] + extracted["security_measures"] = list(set(extracted["security_measures"]))[:5] + + return extracted + +def parse_directory(input_dir): + """Parse all documents in a directory.""" + ropa_entries = [] + + for root, dirs, files in os.walk(input_dir): + for file in files: + if file.startswith('.'): + continue + file_path = os.path.join(root, file) + print(f"[*] Parsing: {file_path}", file=sys.stderr) + text = extract_text(file_path) + if text: + entry = extract_fields(text, file) + ropa_entries.append(entry) + + return ropa_entries + +def main(): + parser = argparse.ArgumentParser(description="Parse documents for GDPR Article 30 fields") + parser.add_argument("--input", "-i", required=True, help="Input file or directory") + parser.add_argument("--output", "-o", default="ropa.json", help="Output JSON file") + parser.add_argument("--mode", choices=["single", "directory"], default="directory", + help="Parse single file or directory") + args = parser.parse_args() + + print(f"[*] Article 30 RoPA Parser - {datetime.now(timezone.utc).isoformat()}", file=sys.stderr) + print(f"[*] Input: {args.input}", file=sys.stderr) + print(f"[*] Mode: {args.mode}", file=sys.stderr) + + if args.mode == "single": + if not os.path.isfile(args.input): + print(f"[!] File not found: {args.input}", file=sys.stderr) + return 2 + text = extract_text(args.input) + ropa_entries = [extract_fields(text, os.path.basename(args.input))] + else: + if not os.path.isdir(args.input): + print(f"[!] Directory not found: {args.input}", file=sys.stderr) + return 2 + ropa_entries = parse_directory(args.input) + + # Build output structure + output = { + "organization": { + "name": "[TO BE COMPLETED]", + "controller_contact": "[TO BE COMPLETED]", + "dpo_contact": "[IF REQUIRED]", + "generated_date": datetime.now(timezone.utc).isoformat() + }, + "processing_activities": ropa_entries, + "completion_notes": [ + "This is a DRAFT generated by automated parsing.", + "Manual review required for accuracy and completeness.", + "Fill in [TO BE COMPLETED] placeholders.", + "Verify all extracted fields against source documents.", + "Add missing Article 30 mandatory fields.", + "Consult legal counsel for final RoPA approval." + ] + } + + with open(args.output, 'w') as f: + json.dump(output, f, indent=2) + + print(f"\n[✓] Parsed {len(ropa_entries)} document(s)", file=sys.stderr) + print(f"[✓] RoPA draft written to: {args.output}", file=sys.stderr) + print(f"[!] Manual review required - this is a DRAFT only", file=sys.stderr) + + return 0 + +if __name__ == "__main__": + sys.exit(main()) diff --git a/skills/conducting-gdpr-compliance-assessment/scripts/article30_validator.py b/skills/conducting-gdpr-compliance-assessment/scripts/article30_validator.py new file mode 100644 index 00000000..326d0ccc --- /dev/null +++ b/skills/conducting-gdpr-compliance-assessment/scripts/article30_validator.py @@ -0,0 +1,186 @@ +#!/usr/bin/env python3 +""" +GDPR Article 30 RoPA Validator. + +Validates a Records of Processing Activities (RoPA) JSON file against Article 30 +mandatory fields and flags incomplete or missing entries. + +Checks: +- All mandatory Article 30 fields present +- Retention periods specified (or criteria documented) +- International transfers have documented safeguards +- Special category data properly flagged +- Security measures documented + +Usage: + python article30_validator.py --ropa ropa.json + python article30_validator.py --ropa ropa.json --check-retention --check-transfers --strict +""" + +import argparse +import json +import sys +from datetime import datetime, timezone + +MANDATORY_FIELDS = [ + "purposes", + "data_subjects", + "personal_data_categories", + "recipients" +] + +SPECIAL_CATEGORY_KEYWORDS = [ + "health", "medical", "biometric", "genetic", "racial", "ethnic", + "political", "religious", "trade union", "sex life", "sexual orientation" +] + +def validate_entry(entry, index, args): + """Validate a single processing activity entry.""" + issues = [] + entry_id = entry.get("source_file", f"Entry {index}") + + # Check mandatory fields + for field in MANDATORY_FIELDS: + if field not in entry or not entry[field]: + issues.append({ + "severity": "ERROR", + "field": field, + "message": f"Missing mandatory field: {field}" + }) + elif isinstance(entry[field], list) and len(entry[field]) == 0: + issues.append({ + "severity": "ERROR", + "field": field, + "message": f"Empty list for mandatory field: {field}" + }) + + # Check retention period + if args.check_retention: + if "retention_period" not in entry or not entry["retention_period"]: + issues.append({ + "severity": "WARNING", + "field": "retention_period", + "message": "Retention period not specified (Article 30(1)(f))" + }) + elif "[TO BE COMPLETED]" in str(entry.get("retention_period", "")): + issues.append({ + "severity": "WARNING", + "field": "retention_period", + "message": "Retention period placeholder not completed" + }) + + # Check international transfers + if args.check_transfers: + transfers = entry.get("international_transfers", []) + if len(transfers) > 0: + # Check if safeguards are documented + safeguards_mentioned = False + for transfer in transfers: + transfer_lower = str(transfer).lower() + if any(word in transfer_lower for word in ["scc", "standard contractual clause", "adequacy", "bcr", "binding corporate rule"]): + safeguards_mentioned = True + break + + if not safeguards_mentioned: + issues.append({ + "severity": "ERROR", + "field": "international_transfers", + "message": "International transfers identified but no safeguards documented (Chapter V)" + }) + + # Check for special category data without additional legal basis + personal_data_str = " ".join(entry.get("personal_data_categories", [])).lower() + if any(keyword in personal_data_str for keyword in SPECIAL_CATEGORY_KEYWORDS): + if "special_category_legal_basis" not in entry: + issues.append({ + "severity": "WARNING", + "field": "special_category_legal_basis", + "message": "Possible special category data (Article 9) but no additional legal basis documented" + }) + + # Check security measures + if not entry.get("security_measures"): + issues.append({ + "severity": "WARNING", + "field": "security_measures", + "message": "No security measures documented (Article 32)" + }) + + return entry_id, issues + +def generate_report(results, args): + """Generate validation report.""" + total_errors = sum(1 for _, issues in results for issue in issues if issue["severity"] == "ERROR") + total_warnings = sum(1 for _, issues in results for issue in issues if issue["severity"] == "WARNING") + + print(f"\n{'='*70}") + print(f"GDPR Article 30 RoPA Validation Report") + print(f"Generated: {datetime.now(timezone.utc).isoformat()}") + print(f"{'='*70}\n") + + print(f"Total Entries: {len(results)}") + print(f"Total Errors: {total_errors}") + print(f"Total Warnings: {total_warnings}") + print() + + if total_errors == 0 and total_warnings == 0: + print("✓ All entries passed validation") + return 0 + + for entry_id, issues in results: + if not issues: + continue + + print(f"\n{entry_id}") + print(f"{'-'*70}") + for issue in issues: + icon = "✗" if issue["severity"] == "ERROR" else "⚠" + print(f" {icon} [{issue['severity']}] {issue['field']}: {issue['message']}") + + print(f"\n{'='*70}") + if total_errors > 0: + print(f"VALIDATION FAILED: {total_errors} error(s) found") + print("Fix errors before using this RoPA for compliance purposes.") + return 1 + else: + print(f"VALIDATION PASSED with {total_warnings} warning(s)") + print("Review warnings and complete missing optional fields.") + return 0 + +def main(): + parser = argparse.ArgumentParser(description="Validate GDPR Article 30 RoPA") + parser.add_argument("--ropa", required=True, help="Path to RoPA JSON file") + parser.add_argument("--check-retention", action="store_true", + help="Validate retention periods are specified") + parser.add_argument("--check-transfers", action="store_true", + help="Validate international transfer safeguards") + parser.add_argument("--strict", action="store_true", + help="Treat warnings as errors") + args = parser.parse_args() + + try: + with open(args.ropa, 'r') as f: + ropa = json.load(f) + except (OSError, json.JSONDecodeError) as e: + print(f"ERROR: Could not read RoPA file: {e}", file=sys.stderr) + return 2 + + processing_activities = ropa.get("processing_activities", []) + if not processing_activities: + print("ERROR: No processing activities found in RoPA", file=sys.stderr) + return 2 + + results = [] + for i, entry in enumerate(processing_activities): + entry_id, issues = validate_entry(entry, i, args) + if args.strict: + # Promote warnings to errors in strict mode + for issue in issues: + if issue["severity"] == "WARNING": + issue["severity"] = "ERROR" + results.append((entry_id, issues)) + + return generate_report(results, args) + +if __name__ == "__main__": + sys.exit(main()) diff --git a/skills/conducting-gdpr-compliance-assessment/scripts/generate_ropa_report.py b/skills/conducting-gdpr-compliance-assessment/scripts/generate_ropa_report.py new file mode 100644 index 00000000..b84d0571 --- /dev/null +++ b/skills/conducting-gdpr-compliance-assessment/scripts/generate_ropa_report.py @@ -0,0 +1,197 @@ +#!/usr/bin/env python3 +""" +GDPR Article 30 RoPA Report Generator. + +Generates a formatted Article 30 Records of Processing Activities report +in Markdown format suitable for supervisory authority submission. + +Usage: + python generate_ropa_report.py --input ropa.json --output Article30_Register.md + python generate_ropa_report.py --input ropa.json --output report.pdf --format pdf +""" + +import argparse +import json +import sys +from datetime import datetime, timezone + +def format_list(items): + """Format a list of items as bullet points.""" + if not items: + return "*[None specified]*" + if isinstance(items, str): + return items + return "\n".join(f"- {item}" for item in items) + +def generate_markdown(ropa): + """Generate Markdown report from RoPA JSON.""" + org = ropa.get("organization", {}) + activities = ropa.get("processing_activities", []) + + lines = [] + lines.append("# Article 30 Records of Processing Activities") + lines.append("") + lines.append(f"**Organization**: {org.get('name', '[Organization Name]')}") + lines.append(f"**Controller Contact**: {org.get('controller_contact', '[Contact Details]')}") + if org.get('dpo_contact'): + lines.append(f"**Data Protection Officer**: {org.get('dpo_contact')}") + lines.append(f"**Generated**: {org.get('generated_date', datetime.now(timezone.utc).isoformat())}") + lines.append(f"**Total Processing Activities**: {len(activities)}") + lines.append("") + lines.append("---") + lines.append("") + + for idx, activity in enumerate(activities, 1): + lines.append(f"## Processing Activity {idx}: {activity.get('source_file', 'Unnamed Activity')}") + lines.append("") + + # Purposes + lines.append("### Purposes of Processing") + lines.append(format_list(activity.get('purposes', []))) + lines.append("") + + # Data Subjects + lines.append("### Categories of Data Subjects") + lines.append(format_list(activity.get('data_subjects', []))) + lines.append("") + + # Personal Data + lines.append("### Categories of Personal Data") + lines.append(format_list(activity.get('personal_data_categories', []))) + lines.append("") + + # Recipients + lines.append("### Categories of Recipients") + lines.append(format_list(activity.get('recipients', []))) + lines.append("") + + # Retention + lines.append("### Retention Period") + retention = activity.get('retention_period', '*[Not specified]*') + lines.append(f"{retention}") + lines.append("") + + # International Transfers + lines.append("### International Transfers") + transfers = activity.get('international_transfers', []) + if transfers: + lines.append(format_list(transfers)) + else: + lines.append("*No international transfers*") + lines.append("") + + # Security Measures + lines.append("### Technical and Organizational Security Measures") + lines.append(format_list(activity.get('security_measures', []))) + lines.append("") + + lines.append("---") + lines.append("") + + # Completion Notes + if ropa.get('completion_notes'): + lines.append("## Completion Notes") + lines.append("") + for note in ropa['completion_notes']: + lines.append(f"- {note}") + lines.append("") + + # Footer + lines.append("---") + lines.append("*This document fulfills the requirements of GDPR Article 30 (Records of Processing Activities).*") + lines.append("*Controllers must maintain this register and make it available to supervisory authorities upon request.*") + + return "\n".join(lines) + +def generate_html(markdown_content): + """Convert Markdown to basic HTML.""" + html_header = """ + +
+ +