Skip to content

GDPR Operations Guide

Last updated: 2025-09-19

This guide provides technical procedures for handling GDPR data requests in LeafLock. Our zero-knowledge architecture means most user data is encrypted client-side, but we still need processes for the limited server-side data we do store.

LeafLock uses a GDPR-compliant encryption system:

  • Email addresses: Encrypted with unique GDPR deletion keys
  • Email hashes: SHA-256 hashes for uniqueness constraints
  • Search hashes: Deterministic encryption for login lookups
  • GDPR keys: Separate table storing deletion keys for email recovery

The system provides automated endpoints for common requests:

Terminal window
curl -X POST https://your-domain.com/api/v1/gdpr/request \
-H "Content-Type: application/json" \
-d '{"email": "user@example.com"}'

Response includes:

  • User ID
  • Account creation date
  • Confirmation message about encrypted notes
Terminal window
curl -X DELETE https://your-domain.com/api/v1/gdpr/delete \
-H "Content-Type: application/json" \
-d '{"email": "user@example.com"}'

If you need to recover a user’s email for legitimate support purposes:

  1. Get the user’s email hash:
SELECT email_hash FROM users WHERE id = 'user-uuid-here';
  1. Retrieve the GDPR deletion key:
SELECT deletion_key FROM gdpr_keys WHERE email_hash = 'hash-from-step-1';
  1. Decrypt the email (Go code example):
// This should only be done by authorized administrators
encryptedEmail := getUserEncryptedEmail(userID)
deletionKey := getGDPRKey(emailHash)
email, err := crypto.DecryptWithGDPRKey(encryptedEmail, deletionKey)

For manual deletion (if automated endpoint fails):

  1. Verify user identity using the email verification process above

  2. Start database transaction:

BEGIN;
  1. Delete user (cascades to notes, sessions, etc.):
DELETE FROM users WHERE email_hash = 'verified-email-hash';
  1. Delete GDPR key:
DELETE FROM gdpr_keys WHERE email_hash = 'verified-email-hash';
  1. Commit transaction:
COMMIT;

For comprehensive data export:

  1. Identify user using email recovery procedure
  2. Extract account metadata:
SELECT
id,
created_at,
updated_at,
last_login,
failed_attempts,
mfa_enabled
FROM users
WHERE email_hash = 'verified-hash';
  1. Get audit trail:
SELECT
action,
resource_type,
created_at,
-- Note: IP and user agent are encrypted
ip_address_encrypted,
user_agent_encrypted
FROM audit_log
WHERE user_id = 'user-uuid';
  1. Session history:
SELECT
created_at,
expires_at,
-- Note: IP and user agent are encrypted
ip_address_encrypted,
user_agent_encrypted
FROM sessions
WHERE user_id = 'user-uuid';
  • Principle of least privilege: Only authorized administrators should access GDPR procedures
  • Audit logging: All GDPR operations are logged
  • Two-person rule: Consider requiring two administrators for deletion operations

Only decrypt user emails when:

  • ✅ User explicitly requests data export
  • ✅ Legal requirement with proper documentation
  • ✅ Legitimate support need with user consent
  • ❌ Never for marketing or analytics
  • ❌ Never for unauthorized access

After user deletion:

  • Immediate: User cannot log in
  • Within 24 hours: All user data removed from active database
  • Within 30 days: Backup cleanup completed
  • Audit logs: Deletion events are retained for compliance

If automated deletion fails:

  1. Check for foreign key constraints:
SELECT
table_name,
constraint_name
FROM information_schema.table_constraints
WHERE constraint_type = 'FOREIGN KEY';
  1. Manual cleanup of related data:
-- Notes and attachments (should cascade)
DELETE FROM notes WHERE created_by = 'user-uuid';
DELETE FROM attachments WHERE created_by = 'user-uuid';
-- Collaborations
DELETE FROM collaborations WHERE user_id = 'user-uuid';
-- User roles
DELETE FROM user_roles WHERE user_id = 'user-uuid';

If GDPR keys are corrupted:

  1. User loses access to email recovery
  2. Account can still be deleted by user ID
  3. Document the incident for audit purposes

When updating encryption:

  1. Backup all GDPR keys before schema changes
  2. Test migration on copy of production data
  3. Verify email decryption works after migration
  4. Update documentation if procedures change
  1. Verify GDPR endpoints are functioning:
Terminal window
# Test data export (use test account)
curl -X POST https://your-domain.com/api/v1/gdpr/request \
-H "Content-Type: application/json" \
-d '{"email": "test@example.com"}'
  1. Check deletion completeness:
-- Should return no results after deletion
SELECT COUNT(*) FROM users WHERE email_hash = 'deleted-user-hash';
SELECT COUNT(*) FROM gdpr_keys WHERE email_hash = 'deleted-user-hash';
  1. Audit log review:
SELECT
action,
COUNT(*) as count
FROM audit_log
WHERE action LIKE '%gdpr%'
AND created_at >= NOW() - INTERVAL '30 days'
GROUP BY action;

If GDPR keys are compromised:

  1. Immediate action: Disable GDPR endpoints
  2. Assessment: Determine scope of key exposure
  3. User notification: Contact affected users
  4. Key rotation: Generate new GDPR keys for remaining users
  5. Documentation: Full incident report

After system restore:

  1. Verify GDPR key integrity
  2. Test email decryption for sample accounts
  3. Validate deletion procedures
  4. Check audit log completeness

For GDPR operations support:

  • Technical issues: tech@leaflock.app
  • Legal questions: legal@leaflock.app
  • Emergency contact: emergency@leaflock.app