Privacy Tools Guide

CCPA Compliance Requirements for Online Businesses: California Privacy Law Guide 2026

CCPA requires California businesses to disclose what data they collect, allow users to delete and opt-out, avoid selling data without explicit consent, and respond to data access requests within 45 days. You must comply if you handle California residents’ data and meet revenue or data thresholds, implementing privacy policies, opt-out mechanisms, and data request processes. The CPRA (2023 successor) adds more consumer rights including data correction and algorithm opt-out, increasing compliance complexity and potential penalties for non-compliance.

Who Must Comply?

CCPA applies to for-profit businesses that meet any of these thresholds:

If your online business meets any of these criteria, you must comply with CCPA requirements. The law defines “personal information” broadly—it includes identifiers, commercial information, internet activity, geolocation data, and professional information.

Consumer Rights Under CCPA

California residents have five primary rights you must support:

  1. Right to Know — Consumers can request what personal data you collect and how it’s used
  2. Right to Delete — Consumers can request deletion of their personal data
  3. Right to Opt-Out — Consumers can opt out of the sale or sharing of their data
  4. Right to Correct — Consumers can request correction of inaccurate data
  5. Right to Limit — Consumers can limit use of sensitive personal information

Implementing Consumer Rights in Your Application

Building a Data Subject Access Request (DSAR) Handler

Your application needs an endpoint to handle consumer requests. Here’s a practical implementation:

from flask import request, jsonify
from functools import wraps

def handle_dsar_request(func):
    """Decorator for CCPA data subject access request handling"""
    @wraps(func)
    def wrapper(*args, **kwargs):
        # Verify consumer identity before processing
        consumer_id = request.headers.get('X-Consumer-Identifier')
        if not consumer_id:
            return jsonify({'error': 'Identity verification required'}), 401

        return func(*args, **kwargs)
    return wrapper

@app.route('/api/ccpa/request', methods=['POST'])
@handle_dsar_request
def submit_ccpa_request():
    data = request.get_json()
    request_type = data.get('type')  # know, delete, correct, limit

    valid_types = ['know', 'delete', 'correct', 'opt-out', 'limit']
    if request_type not in valid_types:
        return jsonify({'error': 'Invalid request type'}), 400

    # Queue request for processing
    dsar_queue.push({
        'consumer_id': get_current_consumer_id(),
        'request_type': request_type,
        'request_date': datetime.utcnow(),
        'status': 'pending'
    })

    return jsonify({
        'message': 'Request received',
        'request_id': generate_request_id(),
        'timeline': '45 days to fulfill'
    }), 202

Implementing Data Deletion

The right to delete requires removing all personal information from your systems:

// Data deletion handler for MongoDB
async function handleDataDeletion(consumerId) {
    const deletionTasks = [
        // Remove from users collection
        db.users.deleteOne({ consumerId }),

        // Remove from analytics (if applicable)
        db.analytics.deleteMany({ consumerId }),

        // Remove from session data
        db.sessions.deleteMany({ consumerId }),

        // Remove from logs (consider retention policies)
        db.logs.deleteMany({ consumerId, timestamp: { $lt: getDeletionCutoff() } })
    ];

    const results = await Promise.allSettled(deletionTasks);

    const failed = results.filter(r => r.status === 'rejected');
    if (failed.length > 0) {
        await logDeletionFailure(consumerId, failed);
    }

    return {
        deleted: results.filter(r => r.status === 'fulfilled').length,
        failed: failed.length
    };
}

Privacy Notice Requirements

Your privacy policy must contain specific elements. Update your policy to include:

<!-- Cookie consent banner with CCPA compliance -->
<div id="cookie-consent" class="ccpa-banner" style="display:none;">
    <p>We collect personal information to improve our services.
       California residents have the right to opt-out of data sales.</p>
    <button onclick="acceptCookies()">Accept</button>
    <button onclick="showDoNotSell()">Do Not Sell My Personal Information</button>
</div>

<script>
function showDoNotSell() {
    // Display opt-out mechanism
    fetch('/api/ccpa/opt-out', { method: 'POST' })
        .then(() => {
            document.getElementById('cookie-consent').innerHTML =
                '<p>Your opt-out preference has been recorded.</p>';
        });
}
</script>

Technical Safeguards for Data Protection

Data Minimization

Collect only what you need. Review your data models:

# Before: Collecting excessive data
class User:
    name = StringField()
    email = StringField()
    phone = StringField()
    ssn = StringField()  # Often unnecessary
    browsing_history = ListField()  # Massive data collection
    precise_location = GeoPointField()  # Sensitive data

# After: Minimal necessary data
class User:
    email = StringField()  # Required for account
    display_name = StringField()  # Optional, user-provided
    # Remove SSN unless specifically required
    # Remove or anonymize browsing history
    # Use ZIP code instead of precise location

Encryption and Access Controls

Implement encryption at rest and in transit:

from cryptography.fernet import Fernet
import hashlib

class DataProtection:
    def __init__(self):
        self.cipher = Fernet(settings.ENCRYPTION_KEY)

    def encrypt_pii(self, data):
        """Encrypt personally identifiable information"""
        return self.cipher.encrypt(data.encode()).decode()

    def pseudonymize(self, data):
        """Replace identifiers with pseudonyms"""
        return hashlib.sha256(
            f"{data}{settings.SALT}".encode()
        ).hexdigest()[:16]

    def anonymize_location(self, lat, lon):
        """Reduce location precision to ~1 mile"""
        return {
            'lat': round(lat, 1),
            'lon': round(lon, 1)
        }

Sale of Personal Information

If you sell data, you must:

  1. Include a “Do Not Sell My Personal Information” link on your homepage
  2. Respect opt-out signals from browsers (Global Privacy Control)
  3. Provide clear opt-out mechanisms
// Check for GPC (Global Privacy Control) signal
function checkGPCSignal() {
    const gpcSignal = navigator.globalPrivacyControl;
    if (gpcSignal === true) {
        // Immediately halt data sale
        disableDataSale();
        return true;
    }
    return false;
}

// Opt-out endpoint
app.post('/api/ccpa/opt-out', async (req, res) => {
    const consumerId = await verifyConsumer(req);

    await db.consumers.updateOne(
        { _id: consumerId },
        {
            $set: {
                'privacy.preferences.optOutOfSale': true,
                'privacy.preferences.updatedAt': new Date()
            }
        }
    );

    // Disable all downstream data sharing
    await disableThirdPartySharing(consumerId);

    res.json({ status: 'opt-out-recorded' });
});

Record Keeping and Compliance Evidence

Maintain logs demonstrating compliance:

import logging
from datetime import datetime

class CCPAComplianceLogger:
    """Audit trail for CCPA compliance"""

    def log_request_received(self, request_id, request_type, consumer_id):
        logging.info(f"CCPA Request: {request_id} | Type: {request_type} | "
                    f"Consumer: {consumer_id[:8]}... | Date: {datetime.utcnow()}")

    def log_request_fulfilled(self, request_id, data_returned):
        logging.info(f"CCPA Fulfilled: {request_id} | "
                    f"Data categories: {list(data_returned.keys())}")

    def log_deletion_completed(self, request_id, consumer_id, systems_affected):
        logging.info(f"CCPA Deletion: {request_id} | "
                    f"Consumer: {consumer_id[:8]}... | Systems: {systems_affected}")

Non-Compliance Consequences

Failure to comply can result in:

Getting Started

To achieve CCPA compliance:

  1. Audit your data — Map what you collect, where it’s stored, and who accesses it
  2. Update privacy notices — Ensure clear disclosure of data practices
  3. Build request handlers — Implement endpoints for all consumer rights
  4. Configure opt-out mechanisms — Add GPC support and do-not-sell links
  5. Implement safeguards — Apply encryption, access controls, and data minimization
  6. Establish audit logging — Document compliance efforts

The regulations continue evolving. Monitor updates from the California Privacy Protection Agency (CPPA) and consult legal counsel for specific business guidance.


Built by theluckystrike — More at zovo.one