NAME

GDPR::IAB::TCFv2::CMPValidator - IAB Registry-based Consent Management Platform validation

SYNOPSIS

use GDPR::IAB::TCFv2::CMPValidator;

# Load from a local snapshot of the IAB CMP registry JSON
my $cmp_v = GDPR::IAB::TCFv2::CMPValidator->new(
    file => '/path/to/cmp-list.json',
);

if ( $cmp_v->is_valid(21) ) {
    print "CMP 21 exists and has not been retired\n";
}

# Compose with the main validator
use GDPR::IAB::TCFv2::Validator;

my $validator = GDPR::IAB::TCFv2::Validator->new(
    vendor_id     => 284,
    cmp_validator => $cmp_v,
);

my $result = $validator->validate($tc_string);
warn "compliance failed: $result\n" unless $result;

DESCRIPTION

GDPR::IAB::TCFv2::CMPValidator validates the cmp_id embedded in a TC string against a snapshot of the IAB TCF CMP registry. A registered CMP that has been retired (the JSON record carries a deletedDate in the past) is treated as invalid.

This module does not refresh the registry on its own. The caller is responsible for periodically downloading a fresh copy of https://cmplist.consensu.org/v2/cmp-list.json (or wherever the IAB publishes the current registry) and pointing this validator at it.

NETWORK FETCH IS OPT-IN

The url form does not fetch by default. A library that silently dials out over the network on construction is a footgun -- it traps on blocked egress, surprises operators with latency, and broadens the supply-chain surface. To enable, pass network_ok => 1 alongside url:

GDPR::IAB::TCFv2::CMPValidator->new(
    url        => 'https://cmplist.consensu.org/v2/cmp-list.json',
    network_ok => 1,
);

Without network_ok, passing url croaks with a message pointing the caller at file => ... / data => ... instead.

CONSTRUCTOR

new

my $v = GDPR::IAB::TCFv2::CMPValidator->new( %args );

Recognized keys:

  • file -- path to a local JSON file in the IAB CMP-list shape. Read synchronously via load_from_file.

  • data -- raw JSON text in the same shape. Parsed via load_from_data.

  • url -- HTTP(S) URL of the registry. Requires network_ok => 1 to actually fetch (see "NETWORK FETCH IS OPT-IN"). Uses HTTP::Tiny when allowed; croaks if the module is not installed.

  • network_ok -- boolean. Without it, the url path croaks rather than dialing out.

  • now -- override the wall clock. Useful for deterministic tests (e.g. now => 1776254400 pins comparisons to 2026-04-15).

METHODS

is_valid

my $ok = $v->is_valid($cmp_id);

Returns true when the registry knows about $cmp_id and the entry either carries no deletedDate or its deletedDate is still in the future relative to "now".

last_updated_epoch

Returns the registry's lastUpdated timestamp as a Unix epoch, or undef when the field is absent or unparseable.

load_from_file($path)

Drop-in load that re-reads the registry from $path. Useful when the file has been refreshed out-of-band.

load_from_data($json_text)

Re-load from a raw JSON string.

load_from_url($url)

Fetch and load from $url. Bypasses the network_ok gate -- the intent is that the caller has already validated they want to make a network call. Requires HTTP::Tiny.

STALE DATA WARNING

When the registry's lastUpdated is older than 28 days (relative to "now"), the constructor emits a warning via Carp::carp. Suppress with a local $SIG{__WARN__} if your audit pipeline does not benefit from it.

SEE ALSO

GDPR::IAB::TCFv2::Validator for the rule engine that composes this class as the cmp_validator rule.