Wrestling with GDPR and Data Protection in Kentico 11 Editions – Consents and Website Tracking
It is definite. Spring 2018 is going to be in the name of GDPR preparation for many businesses interested into doing EU business. Mapping the data flow, last minute collecting of consents, exploring the deep waters of the data-collecting ocean, and ensuring enough coffee supply for their teams to make it through on time. With Kentico 11 release, however, the preparation for GDPR (or any other data protection regulation) can be much easier and streamlined.
In this three-part series, I will shed some light on typical obstacles that you may encounter along your way towards GDPR (or other data protection) compliance. In this first article, I will go with the data flow, dive into consents in Kentico 11, and then meet the challenges directly connected to website tracking.
Data Flow Mapping
It is safe to say that before you start preparing the content of your consents, you need to get familiar with the data flow on your website. Which channels do you have and what kind of data is being collected, where is it stored and for how long, who has access to it, and how is the data going to be used in the future (digital marketing)? Once the picture is clear, you can throw yourself into consents’ content preparation.
It is important to remember that data objects differ per license. We mapped data objects for the EMS license, as it contains all objects that Kentico 11 offers — including contacts and their activities. In the Ultimate license, however, contacts and their activities don’t exist, so web analytics might be one of your biggest concerns. In the Base license, you might be dealing just with the user data (e.g., newsletters or e-store customers) as there is no web analytics functionality. Therefore, make sure that you selectively choose objects that are relevant to your current Kentico 11 license.
The list of Kentico 11’s data objects can be found here: https://docs.kentico.com/k11/configuring-kentico/gdpr-compliance/personal-data-in-kentico
Content of the Consents
When you have a clear understanding of what is happening data wise on your website, it is time to create consents for your website visitors so they can agree to the consent(s) if they so wish. To be precise, it is time to deal with the content of those consents!
The content needs to be easily manageable and searchable. In most cases, you will want to have two versions of the consent (short and long), and be able to display them easily on your website. You may also need them to be multilingual so that different language versions of the consents can be accessed.
The most straightforward way of achieving this is through Kentico 11’s content only pages: https://docs.kentico.com/k11/developing-websites/defining-website-content-structure/page-types/creating-content-only-page-types
These page types behave as simple content storage with no graphical representation (unless you access them via a repeater on another page). Such pages can be edited whenever needed, support versioning, and can be accessed through document macros anywhere on a website.
Each of the pages could have two fields — one for a shorter version of the consent (e.g., code named ShortVersionOfTheConsent), and another field for a longer version of the consent.
Then you could create a folder in the Pages app, and create all the needed consents under it, so the page structure could look like this:
As each of the consent pages has a unique URL, it can be used to access the content via a document macro. For example, if the URL of the consent page for website tracking was /consents/website-tracking, I could access its shorter version (the page field code named ShortVersionOfTheConsent) with the following macro:
{% Documents["/consents/website-tracking"].ShortVersionOfTheConsent %}
Such a macro can also be cached using the following (slightly more complex) macro syntax that would cache the macro result for 60 minutes:
{ % Cache(Documents["/consents/website-tracking"].ShortVersionOfTheConsent, 60, true, "consent|websitetracking", GetCacheDependency("node|dancinggoat|/consents/website-tracking")) % }
This way, you can display the text of a consent whenever needed and allow your visitors to check its shorter or longer version respectively.
If you have Kentico 11’s EMS license, you will probably need to deal with more complex scenarios, and, therefore, you can take advantage of the Data Protection app. It has built-in support for consent management, and allows you to access these consents through dedicated macros as well. More details on this topic can be found in our documentation: https://docs.kentico.com/k11/configuring-kentico/gdpr-compliance/working-with-consents
Website Tracking
As soon as you have the content for your consents ready, it is time to start collecting consents from your website visitors. Especially, if you want to track their website behavior.
If you have web analytics tracking enabled on your website, you may need to ensure (consult it with your legal advisor) that it doesn’t start before a website visitor agrees to it.
The easiest way to check if the visitor agreed to a tracking consent or not is via a cookie. You would place a cookie into their browser as soon as they agreed to the consent. Then you can take advantage of Kentico 11’s WebAnalyticsEvents.CheckAnalyticsConsent global event to block web analytics if necessary. In the event handler, you can implement your custom code to check if the cookie is present in the visitor’s browser or not. By setting the HasConsent property of the handler's CheckAnalyticsConsentEventArgs parameter to false, web analytics for the current request will be blocked.
The following code example outlines an approach that could be used to create a service that would check or set a cookie in the visitor’s browser. The service would be leveraged in a custom web part responsible for setting a cookie right after a visitor agrees to a tracking consent. Let’s check the service:
public class ConsentService
{
/// <summary>
/// Value that is stored in cookie when user gives consent
/// </summary>
private const int AcceptedConsentValue = 1;
/// <summary>
/// Expiration of the consent cookie
/// </summary>
private readonly TimeSpan _expiration;
/// <summary>
/// Name of the cookie where consent will be stored
/// </summary>
private string CookieName => ValidationHelper.GetCodeName(_consentName);
/// <summary>
/// Name of the consent
/// </summary>
private readonly string _consentName;
/// <summary>
/// Initialized service for given consent
/// </summary>
/// <param name="consentName">Name of the consent</param>
/// <param name="expiration">Expiration of cookie</param>
public ConsentService(string consentName, TimeSpan expiration)
{
if (String.IsNullOrEmpty(consentName))
{
throw new ArgumentNullException(nameof(consentName));
}
_expiration = expiration;
_consentName = consentName;
}
/// <summary>
/// Gives consent to log Web analytics data for current user by storing
/// it in a cookie
/// </summary>
public void GiveConsent()
{
CookieHelper.SetValue(CookieName, AcceptedConsentValue.ToString(), DateTime.Now.Add(_expiration));
}
/// <summary>
/// Indicates if current user gave consent for logging Web analytics data
/// </summary>
/// <returns>True if current user gave consent, false otherwise</returns>
public bool HasConsent()
{
// Get value out of the web analytics cookie
var consentValue = ValidationHelper.GetInteger(CookieHelper.GetValue(CookieName), 0);
return consentValue == AcceptedConsentValue;
}
}
As you can see, it is a simple service that can be used to check if a cookie exists or not. Its GiveConsent() method can be used in a custom web part to create a tracking cookie in the visitor’s browser (if the visitor agrees to the tracking consent).
Additionally, if you need to store details about the given consent(s) in some other way (e.g., as a record in a custom table), you can adjust the code of the service to reflect that need indeed.
However, it is important to keep an eye on the website’s performance. As the web analytics event handler might fire multiple times per each web request, you might consider caching your custom code.
The final part of the puzzle is to register an event handler that blocks the web analytics if there is no cookie in the visitor’s browser (e.g., the tracking cookie could be named WebAnalyticsConsent):
[assembly: RegisterModule(typeof(CustomWebAnalyticsConsentModule))]
public class CustomWebAnalyticsConsentModule : Module
{
public CustomWebAnalyticsConsentModule()
: base(nameof(CustomWebAnalyticsConsentModule))
{
}
// Contains initialization code that is executed when the application starts
protected override void OnInit()
{
base.OnInit();
// Registers custom web analytics service for setting/checking consent
Service.Use<ConsentService>(new ConsentService("WebAnalyticsConsent", TimeSpan.FromDays(30)));
// Assigns a handler to the WebAnalyticsEvents.CheckAnalyticsConsent.Execute event
// This event occurs before the system logs web analytics for visitors and processes their personal data
WebAnalyticsEvents.CheckAnalyticsConsent.Execute += Analytics_CheckConsent;
}
private void Analytics_CheckConsent(object sender, CheckAnalyticsConsentEventArgs e)
{
// Get Web analytics consent service
var consentService = Service.Resolve<ConsentService>();
// Log Web analytics only if user gave consent
e.HasConsent = consentService.HasConsent();
}
}
No big deal here, it is just a simple registration of the event handler. It utilizes the previously created service to check the cookie’s presence in a browser.
And what if your website project runs on the EMS license and needs to deal with contacts and their activities? Well, we’ve taken care of it as well — Kentico 11 EMS can be easily configured to not create any contacts or activities until the appropriate consent is given by the visitor: https://docs.kentico.com/k11/configuring-kentico/gdpr-compliance/working-with-consents#Workingwithconsents-Settinguptrackingconsent
Even though dealing with GDPR and other data protection compliance can sometimes be a challenging task, we’ve tried our best to make it easier for you in Kentico 11.
In the second part of this series, I will cover challenges related to online form and newsletter consents in Kentico 11. So, stay tuned!