CCPA Compliance
The California Consumer Privacy Act (CCPA) took effect on January 1, 2020, and is the first comprehensive personal data protection law in the United States. Starting in 2023, its amended version CPRA (California Privacy Rights Act) officially took effect, further strengthening consumer rights and business obligations. CCPA applies to businesses with annual revenue over $25 million, processing data of more than 100,000 consumers, or deriving 50% or more of revenue from data sales. Violators can be fined $7,500 per intentional violation.
For retailers providing energy services in California, user electricity data, customer account information, and energy efficiency service data all constitute personal information protected by CCPA. EnerOS provides opt-out signal handlers, consumer rights APIs, and sales activity recording capabilities to help energy retailers fulfill compliance obligations.
Act Overview
CCPA/CPRA consists of the following core sections:
| Section | Topic | Key Requirements |
|---|---|---|
| § 1798.100 | General consumer rights | Know, delete, refuse sale |
| § 1798.105 | Right to delete | Consumers can request deletion of personal information |
| § 1798.106 | Right to know | Know categories and purposes collected |
| § 1798.110 | Right to know categories | Specific data categories collected |
| § 1798.115 | Right to know sources | Categories of data sources |
| § 1798.120 | Right to opt-out of sale | opt-out of data sale |
| § 1798.121 | Right to withdraw consent | opt-in to re-consent |
| § 1798.125 | Right to non-discrimination | opt-out does not affect service level |
| § 1798.130 | Notification obligation | Privacy policy and notices |
| § 1798.135 | opt-out signal | Accept GPC and other universal opt-out signals |
| § 1798.140 | Definitions | Personal information, sale, and other terms |
| § 1798.150 | Data breach lawsuits | Private right of action |
| § 1798.155 | Administrative penalties | Attorney General enforcement |
Personal Information Definition
CCPA uses a broad definition of “personal information,” covering information that can directly or indirectly identify consumers or households:
| Category | Example | Power Scenario Example |
|---|---|---|
| Identifiers | Name, email, IP, account | Customer account, email |
| Commercial information | Transaction records, consumption history | Electricity consumption records, payment history |
| Network activity | Browsing history, search history | Web access logs |
| Geolocation data | GPS, Wi-Fi positioning | Node geolocation |
| Professional information | Occupation, employer | Commercial and industrial user information |
| Inferred data | Profiles, preferences | Electricity consumption behavior profiles |
| Sensitive personal information (CPRA) | Health, biometrics, precise geolocation | Financial accounts |
Consumer Rights Mapping
EnerOS provides corresponding API endpoints and processing flows for each CCPA right:
| CCPA Section | Right | EnerOS API | Default Response Time |
|---|---|---|---|
| § 1798.100 | Right to know | GET /ccpa/notice/{consumer_id} | Immediate |
| § 1798.105 | Right to delete | POST /ccpa/delete/{consumer_id} | ≤ 45 days |
| § 1798.110 | Right to know categories | GET /ccpa/categories/{consumer_id} | ≤ 45 days |
| § 1798.115 | Right to know sources | GET /ccpa/sources/{consumer_id} | ≤ 45 days |
| § 1798.120 | Right to opt-out of sale | POST /ccpa/opt-out/{consumer_id} | ≤ 15 days |
| § 1798.121 | Withdraw consent | POST /ccpa/opt-in/{consumer_id} | ≤ 15 days |
| § 1798.125 | Right to non-discrimination | GET /ccpa/service-level/{consumer_id} | Immediate |
| § 1798.135 | GPC signal | POST /ccpa/gpc | Immediate |
Business Obligations
1. Notification Obligation
CCPA requires businesses to clearly inform consumers before collecting personal information:
- Categories of personal information collected
- Purposes of collection
- Whether sold or shared
- Rights consumers have
- opt-out link (“Do Not Sell My Personal Information”)
2. opt-out Signal Obligation
CPRA § 1798.135 requires businesses to accept universal opt-out signals (GPC, Global Privacy Control) and treat them as valid opt-out requests.
3. Service Provider and Contractor Obligations
Businesses must sign data agreements (CDPA, CCPA Data Processing Agreement) with third-party service providers and contractors.
4. Data Minimization Obligation (CPRA)
CPRA introduces the data minimization principle, requiring that information collected, processed, and retained by businesses be reasonably related and necessary to the collection purpose.
EnerOS Compliance Implementation
1. opt-out Signal Handling
use eneros_privacy::ccpa::{GpcSignal, OptOutManager};
// Parse GPC header
let gpc = request.headers()
.get("Sec-GPC")
.map(|v| v == "1")
.unwrap_or(false);
if gpc {
let manager = OptOutManager::new();
let record = manager.set_opt_out(
consumer_id,
OptOutSource::Gpc,
OptOutScope::All,
).await?;
println!("GPC opt-out recorded: {:?}", record);
}
2. Data Sales Activity Recording
[ccpa.sales_tracking]
enabled = true
auto_log = true # Auto-record sales activities
retention_years = 7 # Retain for 7 years
[[ccpa.sales_channels]]
name = "third-party-marketer"
category = "marketing-analytics"
opt_out_respected = true
data_categories = ["identifiers", "consumption-pattern"]
revenue_share = false
[[ccpa.sales_channels]]
name = "energy-research-institute"
category = "research"
opt_out_respected = true
data_categories = ["aggregated-consumption"]
revenue_share = true
3. Deletion Request Handling
use eneros_privacy::ccpa::DeletionRequest;
let request = DeletionRequest::builder()
.consumer_id("consumer-99")
.reason("user-request")
.scope(DeletionScope::All)
.cascade_backups(true) # Cascade delete backups
.cascade_logs(true) # Cascade delete logs (per retention policy)
.approver("privacy-officer@eneros.io")
.build()?;
let result = request.execute().await?;
println!("Deleted {} records", result.deleted_count);
println!("Backups will be overwritten in {} days", result.backup_overwrite_days);
4. Non-discrimination Protection
// opt-out consumer service level unchanged
let service_level = ServiceLevel::for_consumer("consumer-99").await?;
assert_eq!(service_level.tier, ServiceTier::Standard);
assert_eq!(service_level.response_time_ms, 100);
// Even with opt-out, service level is not downgraded
Data Processing Configuration
Complete CCPA Configuration in eneros.toml
[compliance]
standard = "ccpa"
version = "CPRA-2023"
enforce = true
privacy_officer = "privacy@eneros.io"
[ccpa]
enabled = true
data_minimization = true # Data minimization principle
default_retention_years = 7
breach_notification_days = 30 # Data breach notification
sensitive_data_opt_in_required = true # Sensitive data requires opt-in
# opt-out signal
[ccpa.opt_out]
accept_gpc = true # Accept GPC signal
treat_as_valid = true # Treat as valid opt-out
default_scope = "all" # All data sales
response_days = 15
# Consumer rights
[ccpa.rights]
response_days = 45
extension_days = 45 # Can be extended 45 days
extension_notify = true # Extension requires written notice
verify_request = true # Verify requester identity
# Sales activity tracking
[ccpa.sales]
track_all = true
auto_log = true
retention_years = 7
monthly_report = true
# Minor protection
[ccpa.minors]
under_13_opt_in_required = true # Under 13 requires opt-in
under_16_opt_in_required = true # Under 16 requires opt-in
parental_consent = true
# Data minimization
[ccpa.minimization]
review_frequency_days = 90 # Quarterly review
auto_purge_expired = true # Auto-purge expired data
purpose_limitation = true # Purpose limitation
Data Category Declaration
[ccpa.data_categories]
declared = true
[[ccpa.data_categories.items]]
name = "identifiers"
collected = true
purpose = "account-management"
sold = false
shared = false
retention_days = 2555
[[ccpa.data_categories.items]]
name = "consumption-records"
collected = true
purpose = "billing-and-forecasting"
sold = true # Sold to research institutions
shared = true
retention_days = 2555
[[ccpa.data_categories.items]]
name = "geolocation"
collected = true
purpose = "outage-detection"
sold = false
shared = false
retention_days = 365
sensitive = true # Precise location is sensitive information
Invocation Example
opt-out Signal Handling
// Parse GPC header
let gpc = request.headers().get("Sec-GPC").map(|v| v == "1").unwrap_or(false);
if gpc {
privacy.set_opt_out(consumer_id, Source::Gpc).await?;
}
Command-line Operations
# opt-out consumer
eneros-cli ccpa opt-out consumer-99 --source gpc
# opt-in to re-consent
eneros-cli ccpa opt-in consumer-99 --approver consumer-99
# Handle deletion request
eneros-cli ccpa delete consumer-99 \
--reason "user-request" \
--approver privacy@eneros.io
# Export annual sales report
eneros-cli ccpa report --year 2026 --output ccpa-2026.csv
# Query consumer data categories
eneros-cli ccpa categories consumer-99 --output categories.json
# Receive GPC signal
eneros-cli ccpa gpc --consumer consumer-99 --signal 1
Sales activities are exported monthly as compliance evidence.
Consumer Notice Generation
# Generate privacy policy
eneros-cli ccpa notice generate --template ccpa-notice.html \
--output privacy-policy.html
# Update "Do Not Sell My Personal Information" link
eneros-cli ccpa opt-out-link update --url "/ccpa/opt-out"
# Verify notice compliance
eneros-cli ccpa notice verify --input privacy-policy.html
Compliance Checklist
Confirm each item before deployment:
- Homepage and terms of service provide “Do Not Sell My Personal Information” link
- Accept Global Privacy Control (GPC) signal and treat as valid opt-out
- Respond to consumer requests within 45 days, can extend 45 days with written notice
- Deletion requests cover time-series data, logs, and backups (per retention policy)
- opt-out consumers do not enter any data sales pipeline
- Data of minors under 12 requires explicit opt-in
- Appoint a data processing officer with public contact information
- Conduct data protection audit every two years
- Data category list clearly stated in privacy policy
- Collection purpose, retention period, and sales targets clearly declared
- Service providers and contractors sign CCPA data agreements
- opt-out does not affect service level (non-discrimination)
- Sensitive personal information requires opt-in consent
- Selling data of consumers under 16 requires opt-in
- Notify affected consumers of data breach within 30 days
- Conduct annual data minimization review
- Export and archive sales activities monthly
- Consumer request identity verification mechanism in place
- Privacy policy updated at least every 12 months