PPactDocs
Compliance & Privacy

CCPA

How Pact enforces California's opt-out marketing bar, honors right-to-know and right-to-delete requests, and treats CCPA as a first-class jurisdiction in the consent engine.

Pact treats CCPA/CPRA as a first-class jurisdiction, not a checkbox. California's consumer-privacy regime differs from GDPR in a way the consent engine encodes directly: marketing is opt-out (you may send until the consumer says stop), while data sharing is opt-in. Those defaults are wired into the same multi-territory decision path that gates every send.

The jurisdiction matrix in core/consent_multi_territory.py defines the CCPA row explicitly:

ActionCCPA requirementWhat it means
Marketing sendopt_outDefault-in; only an explicit withdrawal blocks the send.
Data shareopt_inRequires a granted consent record before sharing.
EnrichmentimpliedPermitted under implied basis.
DSARalways_allowedThe controller can never refuse an access or deletion request.

A contact resolves to CCPA via core/territories.py, which maps location to one of the supported jurisdictions (GDPR, UK_GDPR, CCPA, CASL, PIPEDA, LGPD, PIPL, OTHER). When a contact spans multiple territories, the engine picks the strictest applicable bar, so a California contact who is also EU-resident is protected at the GDPR level, not the looser CCPA one.

Opt-out is enforced, not assumed

Because CCPA marketing is opt-out, a California contact with no consent record is sendable. The moment they withdraw, a withdrawn state is recorded and every subsequent marketing send is blocked at the gate. You can see those denials in real time on the blocked sends triage view.

Right to know and right to delete

CCPA §1798.100 (right to know) and §1798.105 (right to delete) are handled through the same machinery as GDPR access and erasure:

  • Right to know / access — run through the DSAR inbox as an Access request. Pact assembles an evidence packet of the consumer's records, consent history, suppression entries, and engagement.
  • Right to delete — run as a Delete request. The cross-table erasure orchestrator (core/erasure.py, cited to "GDPR Art. 17 / CCPA §1798.105") nulls PII on events, hard-deletes the projection, and appends an erasure_executed audit event so the record of the deletion survives.

Both request types carry the same statutory clock (core/dsar.py sets a 30-day ceiling that covers GDPR, CCPA, and LGPD). The consumer-facing self-service portal (core/customer_portal.py) surfaces the right to erasure with the CCPA citation directly.

Where CCPA is honored across the product

  • DSAR request forms (core/form_templates.py) describe themselves as "Data-subject access / deletion request (GDPR / CCPA)".
  • Preference center (core/preference_center.py) reads the resolved jurisdiction and sets marketing/profiling defaults per territory — opt-in-default-off for GDPR, the opt-out posture for CCPA.
  • Compliance rules (core/compliance_rules.py) tag evaluated rules with a jurisdiction of CCPA where applicable.

Partial: 'Do Not Sell or Share' link

Pact enforces the CCPA consent posture and the access/deletion rights described above. A dedicated, one-click "Do Not Sell or Share My Personal Information" consumer link — the specific CPRA UI control — is a planned addition to the preference center rather than a shipped widget today. In the interim, a share opt-out is captured as a consent withdrawal on the data_share action, which the engine enforces.

What's next