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 California consent posture
The jurisdiction matrix in core/consent_multi_territory.py defines the CCPA row explicitly:
| Action | CCPA requirement | What it means |
|---|---|---|
| Marketing send | opt_out | Default-in; only an explicit withdrawal blocks the send. |
| Data share | opt_in | Requires a granted consent record before sharing. |
| Enrichment | implied | Permitted under implied basis. |
| DSAR | always_allowed | The 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 anerasure_executedaudit 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 ajurisdictionofCCPAwhere 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.