Lawful Basis and Consent Management

Before collecting any personal data, websites must establish and document a lawful basis under GDPR Article 6. The six lawful bases are consent, contract performance, legal obligation, vital interests protection, public task performance, and legitimate interests. Most websites rely primarily on consent for marketing activities and legitimate interests for essential operations like security and fraud prevention.

Consent implementation requires particular attention to GDPR's strict standards. Consent must be freely given, specific, informed, and unambiguous. Pre-ticked boxes, implied consent through inaction, and bundled consent for multiple purposes all violate GDPR. Websites must implement granular consent options, allowing users to consent separately to different processing purposes.

// GDPR-compliant consent management implementation
class ConsentManager {
  constructor() {
    this.consentCategories = {
      necessary: {
        name: 'Necessary Cookies',
        description: 'Essential for website functionality',
        required: true,
        cookies: ['session_id', 'security_token', 'preferences']
      },
      analytics: {
        name: 'Analytics Cookies',
        description: 'Help us understand how visitors interact with our website',
        required: false,
        cookies: ['_ga', '_gid', '_gat', 'analytics_id']
      },
      marketing: {
        name: 'Marketing Cookies',
        description: 'Used to deliver personalized advertisements',
        required: false,
        cookies: ['_fbp', 'ads_session', 'marketing_id']
      },
      functional: {
        name: 'Functional Cookies',
        description: 'Enable enhanced functionality and personalization',
        required: false,
        cookies: ['language_preference', 'timezone', 'theme']
      }
    };
    
    this.consentRecord = {
      id: this.generateConsentId(),
      timestamp: null,
      categories: {},
      ipAddress: null,
      userAgent: null,
      consentVersion: '2.0',
      withdrawn: {}
    };
  }
  
  // Initialize consent on page load
  init() {
    const existingConsent = this.getStoredConsent();
    
    if (!existingConsent) {
      this.showConsentBanner();
    } else {
      this.applyConsent(existingConsent);
      // Check if consent needs renewal (e.g., after 12 months)
      if (this.consentNeedsRenewal(existingConsent)) {
        this.showRenewalBanner();
      }
    }
  }
  
  // Show initial consent banner
  showConsentBanner() {
    const banner = document.createElement('div');
    banner.className = 'gdpr-consent-banner';
    banner.innerHTML = `
      <div class="consent-content">
        <h3>We value your privacy</h3>
        <p>We use cookies to enhance your browsing experience, analyze traffic, and personalize content. By clicking "Accept All", you consent to our use of cookies.</p>
        
        <div class="consent-options">
          ${Object.entries(this.consentCategories).map(([key, category]) => `
            <label class="consent-option ${category.required ? 'required' : ''}">
              <input type="checkbox" 
                     name="consent_${key}" 
                     value="${key}" 
                     ${category.required ? 'checked disabled' : ''}
                     onchange="consentManager.updateCategory('${key}', this.checked)">
              <span class="consent-label">${category.name}</span>
              <span class="consent-description">${category.description}</span>
            </label>
          `).join('')}
        </div>
        
        <div class="consent-actions">
          <button onclick="consentManager.acceptAll()" class="btn-primary">Accept All</button>
          <button onclick="consentManager.acceptSelected()" class="btn-secondary">Accept Selected</button>
          <button onclick="consentManager.rejectAll()" class="btn-text">Reject All</button>
          <a href="/privacy-policy" class="privacy-link">Privacy Policy</a>
        </div>
      </div>
    `;
    
    document.body.appendChild(banner);
    
    // Prevent interaction with page until consent is given
    this.createOverlay();
  }
  
  // Record consent with all required metadata
  recordConsent(categories) {
    this.consentRecord.timestamp = new Date().toISOString();
    this.consentRecord.categories = categories;
    this.consentRecord.ipAddress = this.getAnonymizedIP();
    this.consentRecord.userAgent = navigator.userAgent;
    
    // Store locally
    localStorage.setItem('gdpr_consent', JSON.stringify(this.consentRecord));
    
    // Send to server for audit trail
    this.sendConsentToServer(this.consentRecord);
    
    // Apply consent choices
    this.applyConsent(this.consentRecord);
    
    // Remove banner
    this.closeBanner();
  }
  
  // Implement granular consent withdrawal
  withdrawConsent(category) {
    const consent = this.getStoredConsent();
    if (consent && consent.categories[category]) {
      consent.categories[category] = false;
      consent.withdrawn[category] = new Date().toISOString();
      
      // Update stored consent
      localStorage.setItem('gdpr_consent', JSON.stringify(consent));
      
      // Remove associated cookies
      this.removeCoookiesForCategory(category);
      
      // Notify server
      this.sendConsentWithdrawal(category);
      
      // Update UI
      this.updateConsentUI(consent);
    }
  }
  
  // Check consent before setting cookies
  canSetCookie(cookieName) {
    const consent = this.getStoredConsent();
    if (!consent) return false;
    
    // Find which category this cookie belongs to
    for (const [category, config] of Object.entries(this.consentCategories)) {
      if (config.cookies.includes(cookieName)) {
        return config.required || consent.categories[category] === true;
      }
    }
    
    // Unknown cookies require explicit consent
    return false;
  }
  
  // Generate unique consent ID for tracking
  generateConsentId() {
    return 'consent_' + Date.now() + '_' + Math.random().toString(36).substr(2, 9);
  }
  
  // Anonymize IP for privacy
  getAnonymizedIP() {
    // This would typically be done server-side
    // Client-side placeholder for demonstration
    return 'anonymized';
  }
}

// Global consent manager instance
const consentManager = new ConsentManager();
document.addEventListener('DOMContentLoaded', () => consentManager.init());

Documentation of lawful basis decisions is crucial for demonstrating compliance. For each type of personal data collected, document which lawful basis applies and why. This documentation should be readily available for regulatory reviews and updated when processing purposes change.