Skip to content

Opt-Out (CCPA)

The CCPA requires that users can opt out of data sale/sharing without creating an account or logging in. The opt-out system supports both authenticated users and anonymous visitors.

  1. POST /privacy/opt-out is [AllowAnonymous]
  2. If authenticated → opt-out recorded against UserId
  3. If anonymous → AnonymousTrackId generated, stored in _optout_id HTTP-Only cookie
  4. Idempotent — repeated requests return existing opt-out status
PropertyValue
CategoryStrictlyNecessary (registered in ICookieRegistry)
HttpOnlytrue
Securetrue
SameSiteLax
Retention730 days (2 years)

When a visitor logs in after opting out anonymously, the application should merge the anonymous opt-out with their user profile:

// In your login handler (e.g., Wolverine handler on UserLoggedInEto)
await optOutWriter.MergeAnonymousAsync(anonymousTrackId, userId);

The framework provides the IOptOutRecordWriter.MergeAnonymousAsync() interface; the merge call is application-level logic, not auto-triggered.

MethodRouteOperationAuth
POST/opt-outRequestOptOutAnonymous
GET/opt-out/statusGetOptOutStatusAnonymous
context.Services.AddGranitPrivacy(privacy =>
{
privacy.UseOptOutRecordStore<EfCoreOptOutRecordStore>();
});