ccpa-compliance
California Consumer Privacy Act (CCPA) / CPRA compliance for businesses handling California resident data. Use when serving California users, building privacy features, implementing consumer data rights, or responding to data subject requests.
What this skill does
# CCPA / CPRA Compliance
## Overview
The California Consumer Privacy Act (CCPA), amended by CPRA (California Privacy Rights Act effective January 1, 2023), gives California residents rights over their personal information. Applies to for-profit businesses that:
- Have ≥$25M annual gross revenue, OR
- Buy/sell/share personal info of ≥100,000 CA consumers/households, OR
- Derive ≥50% of annual revenue from selling personal info
Fines: up to $2,500 per unintentional violation, $7,500 per intentional violation. California AG and individual consumers can sue.
## Consumer Rights Under CCPA/CPRA
| Right | Description | Response Deadline |
|-------|-------------|------------------|
| **Right to Know** | What personal info is collected, used, shared, sold | 45 days (+ 45-day extension) |
| **Right to Delete** | Request deletion of personal info | 45 days |
| **Right to Opt-Out** | Opt out of sale or sharing of personal info | Immediate effect |
| **Right to Correct** | Correct inaccurate personal info (CPRA) | 45 days |
| **Right to Limit** | Limit use of sensitive personal info (CPRA) | Immediate effect |
| **Right to Non-Discrimination** | Cannot be denied service for exercising rights | N/A — always |
| **Right to Data Portability** | Receive data in portable format | 45 days |
## Sensitive Personal Information (CPRA)
CPRA adds extra protections for sensitive PI:
- SSN, driver's license, passport number
- Financial account credentials
- Precise geolocation (within 1,852 meters)
- Racial or ethnic origin
- Religious or philosophical beliefs
- Union membership
- Contents of mail, email, text messages
- Genetic data
- Biometric data used for identification
- Health information
- Sexual orientation or sex life
## Data Inventory and Mapping
Before building DSR workflows, map your data:
```python
# data_inventory.py — document what personal data you collect
DATA_INVENTORY = {
"users": {
"table": "users",
"fields": {
"email": {"category": "contact", "sensitive": False, "sold": False},
"name": {"category": "identifier", "sensitive": False, "sold": False},
"ip_address": {"category": "usage", "sensitive": False, "sold": False},
"location": {"category": "location", "sensitive": True, "sold": False},
"phone": {"category": "contact", "sensitive": False, "sold": False},
},
"retention_days": 365 * 3, # 3 years
"third_parties": ["Stripe", "SendGrid", "Mixpanel"],
},
"analytics_events": {
"table": "events",
"fields": {
"user_id": {"category": "identifier", "sensitive": False, "sold": False},
"event_name": {"category": "behavior", "sensitive": False, "sold": False},
"device_id": {"category": "identifier", "sensitive": False, "sold": True},
},
"retention_days": 365,
"third_parties": ["Mixpanel", "Segment"],
}
}
```
## Privacy Notice Requirements
Your privacy policy must disclose:
- Categories of personal information collected
- Purposes for collection
- Whether you sell or share personal information
- Categories of third parties data is disclosed to
- Consumer rights and how to exercise them
- Contact info for privacy requests
```javascript
// Required sections in privacy policy
const REQUIRED_DISCLOSURES = {
collected_categories: [
"Identifiers (name, email, IP address)",
"Commercial information (purchase history)",
"Internet or other network activity (browsing history)",
"Geolocation data",
"Inferences drawn from above"
],
collection_purposes: [
"Provide and improve our services",
"Send transactional and marketing emails",
"Analytics and product development"
],
sells_data: false, // Required disclosure
shares_data: true, // Sharing = cross-context behavioral advertising
shared_with: ["Google Analytics", "Facebook Pixel", "Mixpanel"],
rights_contact: "[email protected]",
opt_out_url: "https://yourcompany.com/privacy/opt-out"
};
```
## GPC (Global Privacy Control) Signal Detection
GPC is a browser signal that automatically invokes the right to opt-out of sale/sharing. California law (CPRA) requires businesses to honor it as of 2023.
```javascript
// Express.js middleware — detect GPC signal and honor opt-out
const gpcMiddleware = (req, res, next) => {
const gpcEnabled = req.headers['sec-gpc'] === '1';
if (gpcEnabled) {
// Auto-apply opt-out for this request
req.privacyConsent = {
optedOutOfSale: true,
optedOutOfSharing: true,
source: 'gpc_signal',
detectedAt: new Date().toISOString()
};
// Record opt-out preference
if (req.user) {
recordOptOut(req.user.id, 'gpc_signal');
} else {
// Use cookie to persist for anonymous users
res.cookie('ccpa_optout', '1', {
maxAge: 365 * 24 * 60 * 60 * 1000, // 1 year
httpOnly: true,
secure: true,
sameSite: 'Strict'
});
}
}
next();
};
```
## Data Subject Request (DSR) API
```python
# FastAPI DSR endpoints
from fastapi import FastAPI, BackgroundTasks, HTTPException
from pydantic import BaseModel, EmailStr
from enum import Enum
import uuid
from datetime import datetime
app = FastAPI()
class DSRType(str, Enum):
KNOW = "know"
DELETE = "delete"
CORRECT = "correct"
OPT_OUT = "opt_out"
LIMIT_SPI = "limit_sensitive"
PORTABILITY = "portability"
class DSRRequest(BaseModel):
request_type: DSRType
email: EmailStr
name: str
correction_details: str = None # For CORRECT requests
class DSRResponse(BaseModel):
request_id: str
status: str
deadline: str
message: str
@app.post("/api/privacy/dsr", response_model=DSRResponse)
async def submit_dsr(request: DSRRequest, background_tasks: BackgroundTasks):
"""Submit a Data Subject Request."""
request_id = str(uuid.uuid4())
deadline_days = 1 if request.request_type == DSRType.OPT_OUT else 45
# Store request
dsr_record = {
"id": request_id,
"type": request.request_type,
"email": request.email,
"name": request.name,
"status": "pending",
"submitted_at": datetime.utcnow().isoformat(),
"deadline_days": deadline_days,
"verified": False
}
await db.dsr_requests.insert(dsr_record)
# Send verification email
background_tasks.add_task(send_verification_email, request.email, request_id)
return DSRResponse(
request_id=request_id,
status="pending_verification",
deadline=f"{deadline_days} days after identity verification",
message="We've sent a verification email. Please verify your identity to proceed."
)
@app.post("/api/privacy/dsr/{request_id}/verify")
async def verify_dsr(request_id: str, token: str, background_tasks: BackgroundTasks):
"""Verify identity and begin DSR processing."""
dsr = await db.dsr_requests.find_one({"id": request_id, "token": token})
if not dsr:
raise HTTPException(status_code=404, detail="Request not found")
await db.dsr_requests.update({"id": request_id}, {"verified": True, "verified_at": datetime.utcnow().isoformat()})
background_tasks.add_task(process_dsr, request_id, dsr["type"], dsr["email"])
return {"status": "processing", "message": "Identity verified. Processing your request."}
async def process_dsr(request_id: str, dsr_type: DSRType, email: str):
"""Process DSR by type."""
user = await db.users.find_one({"email": email})
if not user:
await complete_dsr(request_id, "no_data_found")
return
if dsr_type == DSRType.DELETE:
await delete_user_data(user["id"])
elif dsr_type == DSRType.KNOW:
data_export = await export_user_data(user["id"])
await send_data_export(email, data_export)
elif dsr_type == DSRType.OPT_OUT:
await opt_out_user(user["id"])
elif dsr_type == DSRRelated in General
modeling-omnistudio-epc-catalog
IncludedSalesforce Industries CME EPC product-modeling skill for Product2-based catalog creation. Use when creating EPC products, configuring product attributes, building offer bundles with Product Child Items, or reviewing EPC DataPack JSON metadata for product catalog changes. TRIGGER when: user creates or updates Product2 EPC records, AttributeAssignment payloads, AttributeMetadata/AttributeDefaultValues, Offer bundles, or ProductChildItem relationships. DO NOT TRIGGER when: designing OmniScripts/FlexCards/Integration Procedures (use building-omnistudio-omniscript, building-omnistudio-flexcard, or building-omnistudio-integration-procedure), implementing Apex business logic (use generating-apex), or troubleshooting deployment pipelines (use deploying-metadata).
relationship-science-coach
IncludedUse this skill for direct, practical adult relationship coaching: couples conflict, repair, trust, marriage, dating, flirting, attachment patterns, emotional connection, sex, desire differences, eroticism, kink negotiation, affection, love languages, breakups, and long-term passion. Draw on Gottman, EFT and Hold Me Tight, attachment science, modern sex research, Perel, Nagoski, Kerner, Schnarch, Love and Stosny, and flexible love-language tools. Be concrete and low-hedge. Redirect only for imminent danger, abuse, coercive control, minors, non-consent, self-harm, stalking, or medical/legal/psychiatric decisions.
building-sf-integrations
IncludedSalesforce integration architecture and runtime plumbing with 120-point scoring. Use this skill to set up Named Credentials, External Credentials, External Services, REST/SOAP callout patterns, Platform Events, and Change Data Capture. TRIGGER when: user sets up Named Credentials, External Services, REST/SOAP callouts, Platform Events, CDC, or touches .namedCredential-meta.xml files. DO NOT TRIGGER when: Connected App/OAuth config (use configuring-connected-apps), Apex-only logic (use generating-apex), or data import/export (use handling-sf-data).
venue-templates
IncludedAccess comprehensive LaTeX templates, formatting requirements, and submission guidelines for major scientific publication venues (Nature, Science, PLOS, IEEE, ACM), academic conferences (NeurIPS, ICML, CVPR, CHI), research posters, and grant proposals (NSF, NIH, DOE, DARPA). This skill should be used when preparing manuscripts for journal submission, conference papers, research posters, or grant proposals and need venue-specific formatting requirements and templates.
let-fate-decide
IncludedDraws the 12 Houses of the Zodiac Tarot spread to inject entropy into planning when prompts are vague, ambiguous, or casually delegated. Interprets the spread to guide next steps. Use when the user says 'let fate decide', 'YOLO', 'whatever', 'idk', or other nonchalant phrases, makes Yu-Gi-Oh references, or when you are about to arbitrarily pick between multiple reasonable approaches. Prefer over ask-questions-if-underspecified when the user's tone is casual or playful rather than precision-seeking.
net-ops
IncludedCross-platform network troubleshooting (Windows, macOS, Linux) via local or remote shell. Use for: DNS broken, can't resolve hostnames, nslookup/dig works but apps fail, NRPT, WFP, scutil, /etc/resolver, systemd-resolved, /etc/resolv.conf, NetworkManager, VPN DNS leak residue (ProtonVPN/Mullvad/WireGuard/AnyConnect), AV/firewall blocking DNS or DoH, Tailscale DNS interaction, intermittent connectivity, remote diagnostics over SSH.