Data Privacy by Design: GDPR, CCPA, and Modern Privacy Engineering
Implementing privacy-first architectures that comply with global data protection regulations through encryption, anonymization, consent management, and privacy-enhancing technologies.
Privacy Engineering Team
Compliance & Security
Introduction
Data privacy is no longer optional—it's a fundamental requirement enforced by regulations like GDPR, CCPA, and emerging global privacy laws. Privacy by Design means building privacy protections into your systems from the ground up, not retrofitting them later. This guide covers practical privacy engineering techniques that satisfy regulatory requirements while protecting user data.
1. Data Classification and Inventory
Understanding what data you collect is the foundation of privacy compliance:
// Data classification schema
enum DataClassification {
PUBLIC // No restrictions
INTERNAL // Internal use only
CONFIDENTIAL // Sensitive business data
PERSONAL // PII under GDPR/CCPA
SENSITIVE // Special category data (health, biometric, etc.)
}
// TypeScript example with metadata
interface UserData {
id: string;
email: string; // @privacy(classification: PERSONAL, retention: 730d)
hashedPassword: string; // @privacy(classification: SENSITIVE, retention: 730d)
preferences: object; // @privacy(classification: PERSONAL, retention: 365d)
analyticsId: string; // @privacy(classification: INTERNAL, pseudonymized: true)
ipAddress: string; // @privacy(classification: PERSONAL, anonymize: 90d)
}
// Automated data mapping
const dataInventory = {
databases: {
users: {
tables: {
users: {
columns: {
email: { classification: 'PERSONAL', purpose: 'Authentication' },
name: { classification: 'PERSONAL', purpose: 'Account management' },
birthdate: { classification: 'SENSITIVE', purpose: 'Age verification' }
}
}
}
}
}
};2. Consent Management
Granular Consent Framework
// Consent management system
interface ConsentRecord {
userId: string;
timestamp: Date;
purposes: {
necessary: boolean; // Always true (legitimate interest)
analytics: boolean; // Opt-in
marketing: boolean; // Opt-in
thirdParty: boolean; // Opt-in
};
version: string; // Consent policy version
method: 'explicit' | 'implicit';
ipAddress: string; // For audit trail
userAgent: string;
}
class ConsentManager {
async recordConsent(consent: ConsentRecord): Promise<void> {
await db.consents.insert({
...consent,
id: generateId(),
createdAt: new Date()
});
// Update user preferences
await this.updateUserPreferences(consent.userId, consent.purposes);
// Audit log
await this.logConsentChange(consent);
}
async hasConsent(userId: string, purpose: string): Promise<boolean> {
const consent = await db.consents
.where('userId', userId)
.orderBy('timestamp', 'desc')
.first();
return consent?.purposes[purpose] === true;
}
async withdrawConsent(userId: string, purposes: string[]): Promise<void> {
const currentConsent = await this.getCurrentConsent(userId);
purposes.forEach(purpose => {
currentConsent.purposes[purpose] = false;
});
await this.recordConsent(currentConsent);
// Trigger data deletion for withdrawn purposes
await this.handleConsentWithdrawal(userId, purposes);
}
}
// API endpoint for consent management
app.post('/api/privacy/consent', async (req, res) => {
const { purposes } = req.body;
await consentManager.recordConsent({
userId: req.user.id,
timestamp: new Date(),
purposes,
version: '2.0',
method: 'explicit',
ipAddress: req.ip,
userAgent: req.get('user-agent')
});
res.json({ success: true });
});3. Data Minimization and Purpose Limitation
// Collect only necessary data
interface UserRegistration {
email: string; // Required
password: string; // Required
// DON'T collect: phone, address, birthdate unless truly necessary
}
// Purpose-specific data access
class DataAccessControl {
async getUserData(userId: string, purpose: string): Promise<Partial<User>> {
const user = await db.users.findById(userId);
// Return only fields needed for this purpose
switch (purpose) {
case 'authentication':
return { id: user.id, email: user.email };
case 'billing':
return { id: user.id, email: user.email, billingAddress: user.address };
case 'analytics':
// Return pseudonymized data
return { id: hashUserId(user.id), country: user.country };
default:
throw new Error('Invalid data access purpose');
}
}
}
// Automatic field filtering
function filterPersonalData(data: any, allowedFields: string[]) {
return Object.keys(data)
.filter(key => allowedFields.includes(key))
.reduce((obj, key) => {
obj[key] = data[key];
return obj;
}, {});
}4. Encryption and Pseudonymization
Encryption at Rest and in Transit
import crypto from 'crypto';
class DataProtection {
private encryptionKey: Buffer;
constructor() {
this.encryptionKey = Buffer.from(process.env.DATA_ENCRYPTION_KEY, 'hex');
}
// Field-level encryption for sensitive data
encryptField(plaintext: string): string {
const iv = crypto.randomBytes(16);
const cipher = crypto.createCipheriv('aes-256-gcm', this.encryptionKey, iv);
let encrypted = cipher.update(plaintext, 'utf8', 'hex');
encrypted += cipher.final('hex');
const authTag = cipher.getAuthTag();
// Return: iv + authTag + encrypted
return iv.toString('hex') + authTag.toString('hex') + encrypted;
}
decryptField(encrypted: string): string {
const iv = Buffer.from(encrypted.slice(0, 32), 'hex');
const authTag = Buffer.from(encrypted.slice(32, 64), 'hex');
const ciphertext = encrypted.slice(64);
const decipher = crypto.createDecipheriv('aes-256-gcm', this.encryptionKey, iv);
decipher.setAuthTag(authTag);
let decrypted = decipher.update(ciphertext, 'hex', 'utf8');
decrypted += decipher.final('utf8');
return decrypted;
}
// Pseudonymization for analytics
pseudonymize(userId: string): string {
return crypto
.createHmac('sha256', process.env.PSEUDONYM_KEY)
.update(userId)
.digest('hex');
}
}
// Database schema with encrypted fields
CREATE TABLE users (
id UUID PRIMARY KEY,
email VARCHAR(255) NOT NULL,
encrypted_ssn TEXT, -- Encrypted sensitive data
encrypted_payment_method TEXT,
pseudonym_id VARCHAR(64), -- For analytics
created_at TIMESTAMP
);5. Data Retention and Deletion
Automated Retention Policies
// Retention policy configuration
const retentionPolicies = {
userProfiles: { retention: 730, unit: 'days' }, // 2 years
accessLogs: { retention: 90, unit: 'days' },
marketingConsent: { retention: 365, unit: 'days' },
backups: { retention: 30, unit: 'days' }
};
// Scheduled cleanup job
class DataRetentionService {
async enforceRetentionPolicies(): Promise<void> {
// Delete inactive user accounts
await this.deleteInactiveUsers();
// Anonymize old analytics data
await this.anonymizeOldAnalytics();
// Delete old logs
await this.deleteOldLogs();
}
async deleteInactiveUsers(): Promise<void> {
const cutoffDate = new Date();
cutoffDate.setDate(cutoffDate.getDate() - retentionPolicies.userProfiles.retention);
const inactiveUsers = await db.users
.where('lastLoginAt', '<', cutoffDate)
.where('deletionScheduled', false);
for (const user of inactiveUsers) {
await this.scheduleUserDeletion(user.id);
}
}
async anonymizeOldAnalytics(): Promise<void> {
const cutoffDate = new Date();
cutoffDate.setDate(cutoffDate.getDate() - 90);
await db.analytics
.where('timestamp', '<', cutoffDate)
.update({
userId: null,
ipAddress: '0.0.0.0',
userAgent: 'anonymized'
});
}
}
// Cron job
import cron from 'node-cron';
cron.schedule('0 2 * * *', async () => {
const service = new DataRetentionService();
await service.enforceRetentionPolicies();
});Right to Erasure (GDPR Article 17)
class DataDeletionService {
async handleDeletionRequest(userId: string): Promise<void> {
// 1. Mark account for deletion
await db.users.update(userId, {
deletionScheduled: true,
deletionRequestedAt: new Date()
});
// 2. Notify downstream systems
await this.notifyThirdParties(userId);
// 3. Delete personal data (after grace period)
await this.deleteUserData(userId);
}
private async deleteUserData(userId: string): Promise<void> {
// Delete from all tables
await db.transaction(async (trx) => {
await trx('user_profiles').where('userId', userId).del();
await trx('user_preferences').where('userId', userId).del();
await trx('consent_records').where('userId', userId).del();
// Anonymize instead of delete for audit/legal requirements
await trx('orders').where('userId', userId).update({
userId: null,
email: '[email protected]',
name: 'Deleted User'
});
// Delete from search indexes
await searchIndex.deleteUser(userId);
// Delete from cache
await cache.del(`user:${userId}`);
// Delete from backups (scheduled job)
await this.scheduleBackupDeletion(userId);
});
// Log deletion for compliance audit
await auditLog.log({
action: 'DATA_DELETION',
userId,
timestamp: new Date(),
reason: 'User request (GDPR Article 17)'
});
}
}6. Data Subject Rights (GDPR)
Right to Access (Data Portability)
class DataExportService {
async exportUserData(userId: string): Promise<object> {
const [user, orders, consents] = await Promise.all([
db.users.findById(userId),
db.orders.where('userId', userId).select(),
db.consents.where('userId', userId).select()
]);
return {
personalInformation: {
email: user.email,
name: user.name,
createdAt: user.createdAt
},
orders: orders.map(order => ({
id: order.id,
date: order.createdAt,
items: order.items,
total: order.total
})),
consentHistory: consents.map(c => ({
timestamp: c.timestamp,
purposes: c.purposes,
version: c.version
})),
generatedAt: new Date().toISOString()
};
}
}
// API endpoint
app.get('/api/privacy/export', requireAuth, async (req, res) => {
const exportService = new DataExportService();
const data = await exportService.exportUserData(req.user.id);
res.setHeader('Content-Type', 'application/json');
res.setHeader('Content-Disposition', 'attachment; filename=my-data.json');
res.json(data);
});7. Privacy-Enhancing Technologies
Differential Privacy for Analytics
// Add noise to aggregate queries
class DifferentialPrivacy {
private epsilon: number = 0.1; // Privacy budget
addLaplaceNoise(trueValue: number, sensitivity: number): number {
const scale = sensitivity / this.epsilon;
const u = Math.random() - 0.5;
const noise = -scale * Math.sign(u) * Math.log(1 - 2 * Math.abs(u));
return Math.round(trueValue + noise);
}
async getAggregateStats(query: string): Promise<number> {
const trueCount = await db.raw(query);
// Add noise to protect individual privacy
return this.addLaplaceNoise(trueCount, 1);
}
}
// Usage in analytics
app.get('/api/analytics/user-count', async (req, res) => {
const dp = new DifferentialPrivacy();
const count = await dp.getAggregateStats(
'SELECT COUNT(*) FROM users WHERE country = ?',
[req.query.country]
);
res.json({ count });
});8. Third-Party Data Sharing
Data Processing Agreements (DPA)
// Track third-party processors
const dataProcessors = {
'email-service': {
name: 'SendGrid',
purpose: 'Transactional emails',
dataShared: ['email', 'name'],
dpaSignedDate: '2024-01-15',
region: 'US',
adequacyDecision: 'Data Privacy Framework'
},
'analytics': {
name: 'Self-hosted Matomo',
purpose: 'Website analytics',
dataShared: ['pseudonymized user ID', 'page views'],
dpaSignedDate: '2024-01-20',
region: 'EU',
adequacyDecision: 'N/A (in-house)'
}
};
// Audit data transfers
class DataTransferAudit {
async logTransfer(processor: string, userId: string, purpose: string) {
await db.dataTransfers.insert({
processor,
userId,
purpose,
timestamp: new Date(),
consentVerified: await consentManager.hasConsent(userId, purpose)
});
}
}Privacy Compliance Checklist
Essential Privacy Requirements:
- ✅ Maintain complete data inventory
- ✅ Implement granular consent management
- ✅ Practice data minimization
- ✅ Encrypt sensitive data at rest and in transit
- ✅ Enforce automated retention policies
- ✅ Support data subject rights (access, deletion, portability)
- ✅ Pseudonymize or anonymize where possible
- ✅ Conduct Privacy Impact Assessments (PIA)
- ✅ Maintain audit logs of data access
- ✅ Have Data Processing Agreements with vendors
- ✅ Provide transparent privacy policies
- ✅ Train staff on privacy practices
- ✅ Appoint Data Protection Officer (if required)
- ✅ Document lawful basis for processing
- ✅ Implement breach notification procedures
Conclusion
Privacy by Design isn't just about compliance—it's about building user trust through responsible data practices. By implementing these privacy engineering techniques, you create systems that respect user privacy while meeting the requirements of GDPR, CCPA, and other global regulations. Remember that privacy is an ongoing commitment requiring regular reviews, updates, and a culture of privacy awareness throughout your organization.