Voltar ao blog
Compliance

GDPR and Children’s Data: New Guidance for Online Services

Rachel Torres, Privacy CounselOctober 19, 202515 min de leitura
Children\s DataGDPRParental ConsentCompliance

TLDR: TikTok paid €345M for how they handled children's accounts. GDPR age thresholds vary by country (13-16), parental consent is required below that, and dark patterns around kids get multiplied penalties.

Read full summary Comprehensive guide to GDPR's Article 8 requirements for children's consent. Covers age thresholds by country, verification methods, parental consent mechanisms, and designing child-friendly privacy experiences. Includes TypeScript implementations for age gates, parental verification workflows, and child-safe consent management. *Summary by Claude AI*
## The €345 Million Lesson TikTok's 2023 fine wasn't about collecting children's data. That's legal with proper consent. The fine was about *how* they collected it. Public profiles by default—so a 13-year-old's videos were visible to everyone unless they navigated buried settings to change it. "Family Pairing" that sounded protective but actually made parental controls harder to enable. Dark patterns that nudged kids toward sharing more, not less. The Irish DPC catalogued each manipulation. Each one violated Article 8's requirement that children "merit specific protection." Each one contributed to a penalty that exceeded TikTok's annual revenue in some markets. Children's data under GDPR isn't just more protected—it's a liability multiplier. Every dark pattern in your adult consent flow becomes exponentially more dangerous when a child encounters it. Every "maximize engagement" feature becomes evidence of exploitation when applied to users who can't legally consent. ## The Patchwork Problem GDPR's Article 8 sets the default age of digital consent at 16. Below that, parents must consent. But Article 8 also lets EU member states lower the threshold—down to 13. This created a patchwork: 13 in the UK, Belgium, and Portugal. 14 in Spain and Italy. 15 in France. 16 in Germany and Netherlands. If your service is available across Europe, you're managing multiple thresholds simultaneously. The default threshold under GDPR is 16 years, but Member States can set their own threshold anywhere between 13 and 16 years. This creates a patchwork of requirements across Europe that organizations must navigate carefully: | Country | Age of Digital Consent | Legal Basis | |---------|----------------------|-------------| | Germany | 16 | Default GDPR | | Netherlands | 16 | Default GDPR | | Ireland | 16 | Default GDPR (Data Protection Act 2018) | | France | 15 | Law No. 2018-493 | | UK | 13 | Data Protection Act 2018 | | Spain | 14 | LOPDGDD | | Italy | 14 | Legislative Decree 101/2018 | | Denmark | 13 | Data Protection Act | | Sweden | 13 | Data Protection Act | | Poland | 16 | Default GDPR | | Belgium | 13 | Law of 30 July 2018 | | Austria | 14 | Data Protection Act | | Portugal | 13 | Law No. 58/2019 | ```typescript // Age threshold configuration by jurisdiction interface JurisdictionAgeConfig { country: string; countryCode: string; digitalConsentAge: number; legalReference: string; additionalRequirements?: string[]; } const europeanAgeThresholds: JurisdictionAgeConfig[] = [ { country: 'Germany', countryCode: 'DE', digitalConsentAge: 16, legalReference: 'GDPR Article 8 (default)', additionalRequirements: [ 'Stricter interpretation of "information society services"', 'Enhanced documentation requirements' ] }, { country: 'France', countryCode: 'FR', digitalConsentAge: 15, legalReference: 'Law No. 2018-493', additionalRequirements: [ 'CNIL guidelines on child-friendly notices', 'Specific language requirements' ] }, { country: 'United Kingdom', countryCode: 'GB', digitalConsentAge: 13, legalReference: 'Data Protection Act 2018, Section 9', additionalRequirements: [ 'ICO Age Appropriate Design Code compliance', 'DPIA required for services likely to be accessed by children' ] }, { country: 'Spain', countryCode: 'ES', digitalConsentAge: 14, legalReference: 'LOPDGDD Article 7', additionalRequirements: [ 'AEPD specific guidance on minors' ] }, { country: 'Italy', countryCode: 'IT', digitalConsentAge: 14, legalReference: 'Legislative Decree 101/2018', additionalRequirements: [ 'Garante guidelines on processing children\'s data' ] }, { country: 'Ireland', countryCode: 'IE', digitalConsentAge: 16, legalReference: 'Data Protection Act 2018', additionalRequirements: [ 'DPC Fundamentals guidance applicable' ] } ]; class JurisdictionResolver { private thresholds: Map; constructor() { this.thresholds = new Map(); europeanAgeThresholds.forEach(config => { this.thresholds.set(config.countryCode, config); }); } getAgeThreshold(countryCode: string): number { const config = this.thresholds.get(countryCode.toUpperCase()); return config?.digitalConsentAge || 16; // Default to GDPR default } requiresParentalConsent(countryCode: string, userAge: number): boolean { return userAge < this.getAgeThreshold(countryCode); } getJurisdictionRequirements(countryCode: string): string[] { const config = this.thresholds.get(countryCode.toUpperCase()); return config?.additionalRequirements || []; } } ``` Beyond consent requirements, GDPR mandates several additional protections for children: **Transparency in Child-Friendly Language**: Privacy notices must be clear and understandable to the intended audience. If your service targets children, your privacy notice must be written in language they can understand. **Data Minimization**: The principle of collecting only necessary data applies with heightened scrutiny when children are involved. **Marketing Restrictions**: Profiling and automated decision-making directed at children face significant restrictions, with behavioral advertising to children increasingly viewed as inappropriate. **Right to Erasure**: Children have an enhanced right to have their data erased, particularly data collected when they were minors. ## Age Verification: The Technical Challenge Implementing reliable age verification is one of the most challenging aspects of child protection compliance. You need to verify age accurately enough to meet legal requirements without creating excessive friction or collecting more data than necessary. ### Age Verification Methods Different verification methods offer varying levels of assurance and user friction: ```typescript interface AgeVerificationMethod { id: string; name: string; assuranceLevel: 'low' | 'medium' | 'high'; userFriction: 'minimal' | 'moderate' | 'significant'; dataCollected: string[]; suitableFor: string[]; limitations: string[]; implementation: (userData: any) => Promise; } class AgeVerificationService { private methods: Map; private riskAssessor: RiskAssessmentService; constructor() { this.methods = new Map([ ['self_declaration', { id: 'self_declaration', name: 'Self-Declaration (Date of Birth)', assuranceLevel: 'low', userFriction: 'minimal', dataCollected: ['date_of_birth'], suitableFor: ['low_risk_services', 'initial_gate'], limitations: [ 'Easy to circumvent', 'Relies on user honesty', 'May not meet requirements for high-risk processing' ], implementation: async (userData) => { const dob = new Date(userData.dateOfBirth); const age = this.calculateAge(dob); return { verified: true, age, method: 'self_declaration', confidence: 0.3 }; } }], ['hard_age_gate', { id: 'hard_age_gate', name: 'Hard Age Gate (Year Selection)', assuranceLevel: 'low', userFriction: 'minimal', dataCollected: ['birth_year'], suitableFor: ['low_risk_services'], limitations: [ 'Trivially bypassed', 'ICO recommends against for child-focused services' ], implementation: async (userData) => { const currentYear = new Date().getFullYear(); const age = currentYear - userData.birthYear; return { verified: true, age, method: 'hard_age_gate', confidence: 0.2 }; } }], ['credit_card_verification', { id: 'credit_card_verification', name: 'Credit Card Verification', assuranceLevel: 'medium', userFriction: 'significant', dataCollected: ['payment_token'], suitableFor: ['paid_services', 'adult_content'], limitations: [ 'Assumes card holder is adult', 'Children may use parent\'s card', 'Privacy concerns about payment data' ], implementation: async (userData) => { const verification = await this.paymentGateway.verifyCard( userData.paymentToken, { amount: 0, type: 'verification_only' } ); return { verified: verification.valid, assumedAdult: true, method: 'credit_card', confidence: 0.6 }; } }], ['id_document_verification', { id: 'id_document_verification', name: 'ID Document Verification', assuranceLevel: 'high', userFriction: 'significant', dataCollected: ['id_image', 'selfie', 'extracted_dob'], suitableFor: ['high_risk_services', 'regulated_content'], limitations: [ 'High friction reduces conversion', 'Privacy concerns about ID storage', 'Accessibility issues', 'Cost of verification services' ], implementation: async (userData) => { const idVerification = await this.idVerificationService.verify({ documentImage: userData.idImage, selfieImage: userData.selfie }); return { verified: idVerification.valid, age: idVerification.extractedAge, method: 'id_document', confidence: 0.95 }; } }], ['digital_identity', { id: 'digital_identity', name: 'Digital Identity (eID, Bank ID)', assuranceLevel: 'high', userFriction: 'moderate', dataCollected: ['verified_age_attribute'], suitableFor: ['regulated_services', 'government_services'], limitations: [ 'Not universally available', 'Integration complexity', 'User needs existing digital identity' ], implementation: async (userData) => { const assertion = await this.digitalIdentityProvider.verify({ token: userData.eidToken, requestedAttributes: ['age_over_18', 'age_over_16', 'age_over_13'] }); return { verified: assertion.valid, ageAttributes: assertion.attributes, method: 'digital_identity', confidence: 0.99 }; } }], ['ai_estimation', { id: 'ai_estimation', name: 'AI-Based Age Estimation', assuranceLevel: 'medium', userFriction: 'moderate', dataCollected: ['facial_image'], suitableFor: ['medium_risk_services'], limitations: [ 'Estimation accuracy varies', 'Bias concerns across demographics', 'Privacy concerns about biometric data', 'May not meet legal requirements alone' ], implementation: async (userData) => { const estimation = await this.ageEstimationService.estimate( userData.facialImage ); return { verified: estimation.confidence > 0.8, estimatedAge: estimation.age, ageRange: estimation.range, method: 'ai_estimation', confidence: estimation.confidence }; } }] ]); } async selectVerificationMethod( context: VerificationContext ): Promise { const riskLevel = await this.riskAssessor.assessRisk(context); // Select method based on risk and service type if (riskLevel === 'high' || context.regulatedContent) { return this.methods.get('id_document_verification')!; } if (context.hasDigitalIdentitySupport) { return this.methods.get('digital_identity')!; } if (context.isPaidService) { return this.methods.get('credit_card_verification')!; } // Default to self-declaration with additional checks return this.methods.get('self_declaration')!; } private calculateAge(dateOfBirth: Date): number { const today = new Date(); let age = today.getFullYear() - dateOfBirth.getFullYear(); const monthDiff = today.getMonth() - dateOfBirth.getMonth(); if (monthDiff < 0 || (monthDiff === 0 && today.getDate() < dateOfBirth.getDate())) { age--; } return age; } } ``` ### The UK's Age Appropriate Design Code The UK's Children's Code (officially the Age Appropriate Design Code) provides detailed guidance that has influenced global thinking on child protection online. While technically a UK-specific requirement, its principles are increasingly relevant globally. Key requirements include: 1. **Best Interests of the Child**: The child's best interests must be a primary consideration in service design 2. **Age Appropriate Application**: Risk assessment must consider children likely to access the service 3. **Transparency**: Privacy information must be provided in a clear, age-appropriate manner 4. **Detrimental Use of Data**: Data must not be used in ways detrimental to children's wellbeing 5. **Policies and Community Standards**: Published terms must uphold these standards 6. **Default Settings**: High privacy settings must be the default for children 7. **Data Minimization**: Only collect data minimally necessary 8. **Data Sharing**: Limit data sharing unless compelling reason exists 9. **Geolocation**: Default off for geolocation for children 10. **Parental Controls**: Age-appropriate controls for parents 11. **Profiling**: Default off for profiling unless compelling reason 12. **Nudge Techniques**: Don't use techniques that encourage excessive use 13. **Connected Toys**: Ensure appropriate protections for connected devices 14. **Online Tools**: Provide prominent, accessible tools for children to exercise rights ```typescript class ChildrensCodeComplianceChecker { async assessCompliance( service: ServiceConfiguration ): Promise { const assessments: PrincipleAssessment[] = []; // Principle 1: Best Interests assessments.push(await this.assessBestInterests(service)); // Principle 2: Age Appropriate Application assessments.push(await this.assessAgeAppropriateness(service)); // Principle 3: Transparency assessments.push(await this.assessTransparency(service)); // Principle 4: Detrimental Use assessments.push(await this.assessDetrimentalUse(service)); // Principle 5: Policies and Standards assessments.push(await this.assessPolicies(service)); // Principle 6: Default Settings assessments.push(await this.assessDefaultSettings(service)); // Principle 7: Data Minimization assessments.push(await this.assessDataMinimization(service)); // Principle 8: Data Sharing assessments.push(await this.assessDataSharing(service)); // Principle 9: Geolocation assessments.push(await this.assessGeolocation(service)); // Principle 10: Parental Controls assessments.push(await this.assessParentalControls(service)); // Principle 11: Profiling assessments.push(await this.assessProfiling(service)); // Principle 12: Nudge Techniques assessments.push(await this.assessNudgeTechniques(service)); // Principle 13: Connected Toys if (service.type === 'connected_device') { assessments.push(await this.assessConnectedToys(service)); } // Principle 14: Online Tools assessments.push(await this.assessOnlineTools(service)); return { overallCompliance: this.calculateOverallCompliance(assessments), principles: assessments, recommendations: this.generateRecommendations(assessments), riskLevel: this.assessRiskLevel(assessments) }; } private async assessDefaultSettings( service: ServiceConfiguration ): Promise { const issues: ComplianceIssue[] = []; // Check privacy settings defaults if (!service.defaultSettings.highPrivacy) { issues.push({ severity: 'high', issue: 'Privacy settings not defaulted to high for children', requirement: 'Settings must be "high privacy" by default for children', recommendation: 'Set default privacy to maximum for users under 18' }); } // Check location sharing default if (service.defaultSettings.locationSharing !== false) { issues.push({ severity: 'high', issue: 'Location sharing not defaulted to off', requirement: 'Geolocation must be off by default for children', recommendation: 'Default location services to disabled' }); } // Check profiling default if (service.defaultSettings.profilingEnabled !== false) { issues.push({ severity: 'high', issue: 'Profiling not defaulted to off', requirement: 'Profiling must be off by default for children', recommendation: 'Disable all profiling by default for users under 18' }); } // Check data sharing defaults if (service.defaultSettings.thirdPartySharing !== false) { issues.push({ severity: 'medium', issue: 'Third-party data sharing not defaulted to off', requirement: 'Data sharing should be minimal by default', recommendation: 'Disable non-essential data sharing by default' }); } return { principle: 'Default Settings', number: 6, compliant: issues.filter(i => i.severity === 'high').length === 0, issues, score: this.calculateScore(issues) }; } private async assessProfiling( service: ServiceConfiguration ): Promise { const issues: ComplianceIssue[] = []; // Check if profiling is used if (service.features.profiling) { // Profiling must be off by default if (service.defaultSettings.profilingEnabled !== false) { issues.push({ severity: 'high', issue: 'Profiling enabled by default', requirement: 'Profiling must be off by default for children', recommendation: 'Disable profiling by default; require explicit opt-in' }); } // Check for compelling reason if (!service.profilingJustification) { issues.push({ severity: 'high', issue: 'No compelling reason documented for profiling', requirement: 'Profiling requires documented compelling reason', recommendation: 'Document and justify any profiling with child welfare focus' }); } // Check profiling uses if (service.profilingPurposes?.includes('advertising')) { issues.push({ severity: 'critical', issue: 'Behavioral advertising profiling of children', requirement: 'Profiling for behavioral advertising is problematic', recommendation: 'Remove behavioral advertising targeting for children' }); } } return { principle: 'Profiling', number: 11, compliant: issues.filter(i => i.severity === 'high' || i.severity === 'critical' ).length === 0, issues, score: this.calculateScore(issues) }; } } ``` ## Parental Consent Mechanisms When processing requires parental consent, you need mechanisms to verify that consent actually comes from a parent or guardian, not the child pretending to be a parent. ### Implementing Parental Verification ```typescript interface ParentalConsentWorkflow { initiate(childUserId: string, parentEmail: string): Promise; verify(requestId: string, verificationData: any): Promise; recordConsent(requestId: string, consentData: ConsentRecord): Promise; checkConsentStatus(childUserId: string): Promise; } class ParentalConsentService implements ParentalConsentWorkflow { private emailService: EmailService; private verificationService: ParentVerificationService; private consentStorage: ConsentStorage; async initiate( childUserId: string, parentEmail: string ): Promise { // Generate secure consent request const requestId = this.generateSecureRequestId(); const verificationToken = this.generateVerificationToken(); const request: ConsentRequest = { id: requestId, childUserId, parentEmail, verificationToken, status: 'pending', createdAt: new Date(), expiresAt: new Date(Date.now() + 48 * 60 * 60 * 1000), // 48 hours consentPurposes: await this.getRequiredConsentPurposes(childUserId) }; // Store request await this.consentStorage.saveRequest(request); // Send verification email to parent await this.sendParentVerificationEmail(request); return request; } private async sendParentVerificationEmail( request: ConsentRequest ): Promise { const verificationUrl = this.buildVerificationUrl(request); await this.emailService.send({ to: request.parentEmail, template: 'parental_consent_request', data: { childFirstName: await this.getChildFirstName(request.childUserId), serviceName: this.config.serviceName, verificationUrl, consentPurposes: request.consentPurposes.map(p => ({ name: p.name, description: p.description, dataCollected: p.dataCategories })), expiresAt: request.expiresAt, privacyPolicyUrl: this.config.privacyPolicyUrl, childRightsInfo: this.getChildRightsInfo() } }); } async verify( requestId: string, verificationData: ParentVerificationData ): Promise { const request = await this.consentStorage.getRequest(requestId); if (!request) { throw new RequestNotFoundError(requestId); } if (request.status !== 'pending') { throw new RequestAlreadyProcessedError(requestId); } if (new Date() > request.expiresAt) { throw new RequestExpiredError(requestId); } // Verify token if (verificationData.token !== request.verificationToken) { throw new InvalidTokenError(); } // Verify parent identity based on chosen method const parentVerification = await this.verifyParentIdentity( verificationData ); if (!parentVerification.verified) { return { success: false, reason: parentVerification.failureReason, retryAllowed: parentVerification.retryAllowed }; } // Update request status request.status = 'verified'; request.parentVerificationMethod = verificationData.method; request.verifiedAt = new Date(); await this.consentStorage.updateRequest(request); return { success: true, requestId, nextStep: 'consent_form' }; } private async verifyParentIdentity( data: ParentVerificationData ): Promise { switch (data.method) { case 'credit_card': return this.verifyCreditCard(data.paymentToken); case 'knowledge_based': return this.verifyKnowledgeBased(data.answers); case 'video_verification': return this.verifyVideo(data.videoSessionId); case 'signed_form': return this.verifySignedForm(data.formData); case 'government_id': return this.verifyGovernmentId(data.idData); default: throw new UnsupportedVerificationMethodError(data.method); } } private async verifyCreditCard( paymentToken: string ): Promise { // COPPA-compliant method: charge small amount, refund // FTC guidance allows this as verification method const charge = await this.paymentGateway.charge({ token: paymentToken, amount: 0.50, // Small verification charge description: 'Parent verification for child account' }); if (charge.success) { // Immediately refund await this.paymentGateway.refund(charge.transactionId); return { verified: true, method: 'credit_card', confidence: 0.7 }; } return { verified: false, failureReason: 'Payment verification failed', retryAllowed: true }; } async recordConsent( requestId: string, consentData: ParentalConsentRecord ): Promise { const request = await this.consentStorage.getRequest(requestId); if (request.status !== 'verified') { throw new UnverifiedRequestError(requestId); } const consent: StoredParentalConsent = { id: this.generateConsentId(), requestId, childUserId: request.childUserId, parentEmail: request.parentEmail, parentVerificationMethod: request.parentVerificationMethod, consentedPurposes: consentData.purposes, consentTimestamp: new Date(), ipAddress: consentData.ipAddress, userAgent: consentData.userAgent, consentLanguage: consentData.language, withdrawalInfo: { url: this.buildWithdrawalUrl(request.childUserId), contactEmail: this.config.parentContactEmail } }; await this.consentStorage.saveConsent(consent); // Update request status request.status = 'consented'; request.consentedAt = new Date(); await this.consentStorage.updateRequest(request); // Activate child account with consented features await this.activateChildAccount(request.childUserId, consentData.purposes); // Send confirmation to parent await this.sendConsentConfirmation(consent); } async handleConsentWithdrawal( childUserId: string, parentVerification: ParentVerificationData ): Promise { // Verify parent identity const verification = await this.verifyParentIdentity(parentVerification); if (!verification.verified) { throw new ParentVerificationFailedError(); } // Get current consent const consent = await this.consentStorage.getActiveConsent(childUserId); if (!consent) { throw new NoActiveConsentError(childUserId); } // Record withdrawal consent.withdrawnAt = new Date(); consent.withdrawalMethod = parentVerification.method; await this.consentStorage.updateConsent(consent); // Deactivate child account features await this.deactivateChildFeatures(childUserId); // Schedule data deletion const deletionDate = new Date(Date.now() + 30 * 24 * 60 * 60 * 1000); await this.scheduleDeletion(childUserId, deletionDate); // Notify parent await this.sendWithdrawalConfirmation(consent.parentEmail, { childUserId, deletionDate }); return { success: true, accountStatus: 'deactivated', dataDeletedBy: deletionDate }; } } ``` ## Child-Friendly Privacy Notices GDPR requires that privacy information be provided in a "concise, transparent, intelligible and easily accessible form, using clear and plain language." When the audience includes children, this requirement becomes critical and specific. ### Writing for Different Age Groups ```typescript interface ChildFriendlyNotice { ageRange: [number, number]; readingLevel: string; visualElements: boolean; interactiveElements: boolean; content: NoticeContent; } class ChildFriendlyNoticeGenerator { private templates: Map; generateNotice( processingInfo: ProcessingInformation, targetAgeRange: [number, number] ): ChildFriendlyNotice { if (targetAgeRange[1] <= 8) { return this.generateEarlyChildhoodNotice(processingInfo); } else if (targetAgeRange[1] <= 12) { return this.generatePreTeenNotice(processingInfo); } else if (targetAgeRange[1] <= 16) { return this.generateTeenNotice(processingInfo); } else { return this.generateStandardNotice(processingInfo); } } private generateEarlyChildhoodNotice( info: ProcessingInformation ): ChildFriendlyNotice { // Ages 5-8: Simple language, heavy visual elements, parent involvement return { ageRange: [5, 8], readingLevel: 'early_elementary', visualElements: true, interactiveElements: true, content: { title: `${info.serviceName} and Your Information`, sections: [ { id: 'what_we_collect', title: 'What We Learn About You', childContent: `

When you play ${info.serviceName}, we remember some things about you:

    ${info.dataCategories.map(cat => `
  • ${this.simplifyDataCategory(cat, 'early_childhood')}
  • ` ).join('')}
`, parentContent: `
Information for Parents

We collect the following categories of personal data:

    ${info.dataCategories.map(cat => `
  • ${cat.name}: ${cat.description}
  • ` ).join('')}

Legal basis: ${info.legalBasis}

` }, { id: 'why_we_collect', title: 'Why We Need This', childContent: `

We use this to:

    ${info.purposes.map(purpose => `
  • ${this.simplifyPurpose(purpose, 'early_childhood')}
  • ` ).join('')}
` }, { id: 'your_choices', title: 'Your Choices', childContent: `

You and your grown-up can:

  • Ask to see what we know about you
  • Ask us to forget about you
  • Stop playing anytime

Ask your grown-up to help!

` } ], parentGuidance: `

Guide for Parents

This notice is designed to be read together with your child. The "Information for Parents" sections provide the full legal details.

You can exercise data rights on behalf of your child by visiting our Parent Portal.

`, readAloudVersion: this.generateReadAloudScript(info) } }; } private generatePreTeenNotice( info: ProcessingInformation ): ChildFriendlyNotice { // Ages 9-12: More detail, some autonomy, still visual return { ageRange: [9, 12], readingLevel: 'upper_elementary', visualElements: true, interactiveElements: true, content: { title: `How ${info.serviceName} Uses Your Information`, sections: [ { id: 'what_we_collect', title: 'Information We Collect', childContent: `

Things You Tell Us

When you sign up or use ${info.serviceName}, you might share:

    ${info.dataCategories .filter(c => c.source === 'user_provided') .map(cat => `
  • ${this.simplifyDataCategory(cat, 'pre_teen')}
  • `) .join('')}

Things We Notice

While you use ${info.serviceName}, we also learn:

    ${info.dataCategories .filter(c => c.source === 'observed') .map(cat => `
  • ${this.simplifyDataCategory(cat, 'pre_teen')}
  • `) .join('')}
` }, { id: 'why_matters', title: 'Why This Matters', childContent: `

Your information is important! Here's what we do with it:

${info.purposes.map(purpose => `
${this.simplifyPurpose(purpose, 'pre_teen')}

${purpose.example}

`).join('')}
` }, { id: 'your_rights', title: 'Your Rights', childContent: `

You have important rights about your information:

👀
See It: Ask to see what information we have about you
✏️
Fix It: Tell us if something is wrong
🗑️
Delete It: Ask us to erase your information
📦
Take It: Get a copy of your information

Talk to your parent or guardian to use these rights, or use our Rights Center.

` } ] } }; } private generateTeenNotice( info: ProcessingInformation ): ChildFriendlyNotice { // Ages 13-16: More adult-like but still accessible return { ageRange: [13, 16], readingLevel: 'middle_school', visualElements: true, interactiveElements: true, content: { title: `${info.serviceName} Privacy Notice`, sections: [ { id: 'overview', title: 'The Quick Version', childContent: `

TL;DR

  • We collect: ${info.dataCategories.map(c => c.shortName).join(', ')}
  • We use it for: ${info.purposes.map(p => p.shortName).join(', ')}
  • We share with: ${info.sharingPartners.length > 0 ? info.sharingPartners.map(p => p.name).join(', ') : 'Nobody outside of us'}
  • You can: See, fix, delete, or download your data anytime

Read on for the details, or see our full privacy policy.

` }, { id: 'data_collection', title: 'What We Collect & Why', childContent: `
${info.dataCategories.map(cat => ` `).join('')}
Data Type Why We Need It Can You Opt Out?
${cat.name}

${cat.examples}

${cat.purposes.join(', ')} ${cat.optional ? 'Yes' : 'Required'}
` }, { id: 'your_control', title: 'You\'re In Control', childContent: `

Your data belongs to you. Here's what you can do:

Some actions might need a parent's help if you're under ${info.parentalConsentAge} in your country.

` } ] } }; } private simplifyDataCategory( category: DataCategory, ageGroup: string ): string { const simplifications: Record> = { 'early_childhood': { 'email': 'Your email address', 'username': 'The name you pick for the game', 'location': 'Where you are', 'device_info': 'What kind of phone or tablet you use', 'usage_data': 'What games you play and for how long', 'ip_address': 'Your computer\'s special number' }, 'pre_teen': { 'email': 'Your email address (or your parent\'s)', 'username': 'Your username', 'location': 'Your location (city or country)', 'device_info': 'Device type and settings', 'usage_data': 'How you use the app', 'ip_address': 'Your internet address' } }; return simplifications[ageGroup]?.[category.id] || category.simplifiedDescription || category.name; } private simplifyPurpose(purpose: Purpose, ageGroup: string): string { const simplifications: Record> = { 'early_childhood': { 'service_provision': 'Make the game work for you', 'personalization': 'Remember what you like', 'safety': 'Keep you safe', 'analytics': 'Make the game better', 'customer_support': 'Help you when something goes wrong' }, 'pre_teen': { 'service_provision': 'Make the service work', 'personalization': 'Customize your experience', 'safety': 'Keep the community safe', 'analytics': 'Improve our service', 'customer_support': 'Help when you need it' } }; return simplifications[ageGroup]?.[purpose.id] || purpose.simplifiedDescription || purpose.name; } } ``` ## Age-Appropriate Default Settings One of the most impactful requirements for child protection is appropriate default settings. Children should receive the highest privacy protections by default, not opt-in to them. ```typescript class ChildSafeDefaultsManager { private settingsRepository: SettingsRepository; private featureFlags: FeatureFlagService; async applyChildSafeDefaults( userId: string, userAge: number, jurisdiction: string ): Promise { const defaults = this.determineDefaults(userAge, jurisdiction); // Apply privacy settings await this.settingsRepository.update(userId, { privacy: { profileVisibility: defaults.profileVisibility, searchable: defaults.searchable, showActivityStatus: defaults.showActivityStatus, allowDirectMessages: defaults.allowDirectMessages }, data: { locationTracking: defaults.locationTracking, analyticsEnabled: defaults.analyticsEnabled, personalizedAds: defaults.personalizedAds, profilingEnabled: defaults.profilingEnabled, thirdPartySharing: defaults.thirdPartySharing }, communication: { marketingEmails: defaults.marketingEmails, pushNotifications: defaults.pushNotifications, inAppMessages: defaults.inAppMessages }, social: { whoCanContact: defaults.whoCanContact, whoCanSeeContent: defaults.whoCanSeeContent, whoCanTagMe: defaults.whoCanTagMe }, safety: { contentFiltering: defaults.contentFiltering, screenTimeReminders: defaults.screenTimeReminders, breakReminders: defaults.breakReminders } }); // Disable restricted features for (const feature of defaults.disabledFeatures) { await this.featureFlags.disable(userId, feature); } return { userId, appliedDefaults: defaults, appliedAt: new Date() }; } private determineDefaults( age: number, jurisdiction: string ): ChildSafeDefaults { // Most restrictive defaults for youngest users if (age < 13) { return { // Privacy - Maximum restriction profileVisibility: 'private', searchable: false, showActivityStatus: false, allowDirectMessages: 'approved_only', // Data - Minimal collection locationTracking: false, analyticsEnabled: 'essential_only', personalizedAds: false, profilingEnabled: false, thirdPartySharing: false, // Communication - Restricted marketingEmails: false, pushNotifications: 'essential_only', inAppMessages: 'essential_only', // Social - Restricted whoCanContact: 'approved_only', whoCanSeeContent: 'friends_only', whoCanTagMe: 'nobody', // Safety - Maximum contentFiltering: 'strict', screenTimeReminders: true, breakReminders: true, // Features - Restricted disabledFeatures: [ 'live_streaming', 'public_posting', 'direct_purchase', 'external_links', 'friend_suggestions', 'location_sharing' ] }; } // 13-15: Moderate restrictions if (age < 16) { return { profileVisibility: 'friends_only', searchable: false, showActivityStatus: false, allowDirectMessages: 'friends_only', locationTracking: false, analyticsEnabled: 'essential_only', personalizedAds: false, profilingEnabled: false, thirdPartySharing: false, marketingEmails: false, pushNotifications: 'friends_and_essential', inAppMessages: 'friends_and_essential', whoCanContact: 'friends_only', whoCanSeeContent: 'friends_only', whoCanTagMe: 'friends_only', contentFiltering: 'moderate', screenTimeReminders: true, breakReminders: true, disabledFeatures: [ 'live_streaming_public', 'direct_purchase', 'location_sharing_public' ] }; } // 16-17: Lighter restrictions return { profileVisibility: 'friends_only', searchable: false, showActivityStatus: false, allowDirectMessages: 'everyone', locationTracking: false, analyticsEnabled: true, personalizedAds: false, profilingEnabled: false, thirdPartySharing: false, marketingEmails: false, pushNotifications: true, inAppMessages: true, whoCanContact: 'everyone', whoCanSeeContent: 'friends_only', whoCanTagMe: 'friends_only', contentFiltering: 'off', screenTimeReminders: false, breakReminders: false, disabledFeatures: [] }; } } ``` ## FAQ **What age is a "child" under GDPR?** GDPR allows Member States to set the age of digital consent between 13 and 16 years. The default is 16. You need to know the specific threshold in each jurisdiction where you operate. Anyone below that threshold requires parental consent for consent-based processing. **Do the child-specific rules apply to all data processing?** Article 8's parental consent requirements specifically apply to "information society services offered directly to a child" where consent is the legal basis. If you're processing children's data under a different legal basis (like legitimate interests or contract), Article 8's consent requirements don't apply—but other child-protection obligations still do. **How do I know if my service is "offered directly to a child"?** Look at who your service is designed for and marketed to. Educational apps, games, social media, and entertainment services commonly used by children are typically considered offered directly to children, even if not exclusively. The ICO's guidance suggests considering if a service is "likely to be accessed by children." **What counts as "verifiable parental consent"?** GDPR requires "reasonable efforts" to verify that consent comes from a parent. Methods include credit card verification, signed consent forms, video verification, government ID verification, or knowledge-based verification. The appropriate method depends on the risk level of processing. **Can children exercise their own data rights?** Yes, children have the same data rights as adults. However, for younger children, parents can exercise rights on their behalf. As children mature, they should be able to exercise more rights independently. The UK's Children's Code specifically requires tools that allow children to exercise their rights. **What happens when a child turns the age of digital consent?** Existing parental consent doesn't automatically convert to the child's own consent. Best practice is to re-obtain consent from the now-adult user, giving them the opportunity to make their own informed choice. **Do I need to delete data when children turn 18?** GDPR gives individuals an enhanced right to erasure for data collected when they were children. While you don't automatically need to delete data at 18, you should make it easy for now-adults to request deletion and should carefully consider retention of childhood data. ## Building Child-Safe Services Protecting children online isn't just about compliance—it's about building services that genuinely respect children's wellbeing and development. The legal requirements provide a floor, not a ceiling. Organizations that excel in this space go beyond minimum compliance to create genuinely child-appropriate experiences. The most effective approach treats child safety as a design principle, not an afterthought. Consider children throughout product development: in user research, feature design, default settings, and ongoing monitoring. Involve child development experts, not just lawyers and engineers. Remember that children are not a homogeneous group. A 7-year-old and a 15-year-old have vastly different capabilities, needs, and risks. Services that succeed with children recognize this diversity and adapt accordingly. The regulatory environment for children's data protection is only becoming stricter. The EU's Digital Services Act adds new requirements. The UK's Children's Code sets detailed expectations. The US is considering comprehensive federal children's privacy legislation. Organizations that build child-safe practices now will be better positioned as these requirements evolve. Most importantly, remember that behind every data point is a real child. The choices you make about data collection, retention, and use have real impacts on real young people. Build services you'd be comfortable having your own children use.
R

Rachel Torres, Privacy Counsel

Escritor no GetCookies, especializado em conformidade de privacidade, gestão de consentimento e otimização de marketing digital.

Pronto para simplificar o consentimento de cookies?

O GetCookies torna a conformidade com RGPD, CCPA e privacidade global fácil. Comece hoje.