Hello everyone,
in this article, I will try to look on how you can setup your Adobe tools and what these implications are for your cookies and data transfer.
I will also quickly tackle the privacy JS library but before I do any of that, some disclaimers:
- I am not a lawer (it is obvious but worth reminding that you should align with your company policy on these topics)
- I am not the voice of Adobe (obvious again, but this blog is not named “adobe-recommended-and-approved-practices” so everything is my personal experience that I share)
- If you want help on this for your adobe tools, contact Adobe directly and see what can be done. I am not giving free advice on Privacy Policies, I never promoted the Adobe Consulting Service (anyone can be a good consultant) but, in that particular case, they are the safe bet for you in order to get help on how to get things done for Adobe solutions.
What I can give you is the technicality of what is possible & happening with the different Adobe solutions. This will remain technical and will present you the options.
As usual, I am using this blog to gather different documentation or experience I had with the solutions. Nothing here is new but it may be hidden in the documentation.
Adobe Experience Cloud ID service
The first thing to start with is the Experience Cloud ID service, this application / service is used for all of the Adobe Experience Cloud solutions. Adobe Target, Adobe Analytics, Adobe Audience Manager, … you name it, it is is used there.
What is this service doing ? There have been countless articles on the subject, and the documentation is great. For a short reminder, the experience cloud ID service is a way for you to generate a unique ID for your Adobe solutions. It works such as the service is generating a unique ID for your users arriving on your website and we can then attached all experiences and share data between applications (e.g. : Target & Analytics) from that ID. Everything is stitched on the back end of Adobe (mostly) and you have less ID sync to realize for your applications.
This piece of code is important, even mandatory, for all solutions to work as expected. It is the backbone of the tracking functionality from Adobe… which means it has quite a role to play on Privacy policy.
The library usually runs on your implementation and call the service on the demdex.net server. The demdex.net server is the server application orchastrating the generation of ID and other services, but mostly related to the Adobe Audience Manager solution.
ECID & Demdex Cookies
The ECID service is generating several cookies to recognize your users on the font-end of your application. The main ones are the following:
ECID cookie
The ECID is an ID that is unique for your organization and is supposed to identify this user in the context of you organization. This ID is kept in its own cookie and generally available on your domain. This is not the only place where it is placed. If you are using the default behavior of the ECID service, this is ID is generated on the demdex domain in order to know if this is a known user or not.
Because this ID is unique to your organization, if you are using only Adobe Analytics, this cookie could still be generated and respect privacy (depends on your company policy for your country). The important point being it is not used for marketing purpose.
Demdex cookie
The Demdex ID is another cookie that is generated by the Experience Cloud ID service and this one is unique per user only. So it is cross organization. This ID is stored in the Demdex cookie and this cookie is usually store on the demdex domain. If you are using Adobe Audience Manager, you have the capability to store this cookie on the first party domain that you are working on but this is just a replication.
The purpose of this cookie is purely marketing, so the privacy policy usually differ for this ID compare to the ECID.
ID synchronization
One of the less known capability of the ECID Service is the ID synchronization that happens when the ECID and Demdex ID are being fetched.
What is the ID synchronization ?
This is to exchange ID between different applications, this synchronization is mostly used by Audience Manager use-cases but by default you are also doing some synchronization.
Be careful and check with your Adobe representative if you have some synchronization set.
How to limit these elements ?
The Experience ID has some parameters that you can use in order to limit these different elements.
We will list the different capabilities available so you can chose the one adapting your policy:
- disableIdSyncs: This parameter will limit the Id sync capability of the Experience Cloud ID Service.
- disableThirdPartyCalls: This parameter will prevent the call to demdex.net to be realized.
- disableThirdPartyCookies: This parameter will prevent the cookies on demdex.net to be set.
All of these parameters are here to help you dealing with the call to the demdex domain and setting up cookies on that domain. However, it will not prevent the ECID cookie to be generated. This cookie is required for the different tools to work properly, so if the service is not capable of calling the demdex domain, it will generate the ID and cookie client side.
It doesn’t ensure cross domain tracking but ensure ECID usage. This ID will be pushed to the demdex domain once the third party calls and third party cookies are authorized (again).
The Adobe optin service
OK. So far, we have seen that the Experience Cloud ID Service can be managed in some way but it seems that it runs in any case.
And that is true, this is the fact: You cannot stop the Experience Cloud ID Service once you have it on your implementation. It is a required component for all services, so the dependencies ensure that the service run if available in your implementation….
UNLESS…
Yes, there is a way to prevent the service to run, and actually there is a way to prevent all of the tools to run. This is the Adobe optin service.
Because it is loaded within the Experience Cloud ID Service library, this optin service is kept at the same place than the Experience Cloud ID service. However, we will see it, it is not calling the same methods
I would hope that this library is made independant, but in any case, you would need the Experience Cloud ID service to run your tool, so this is the assumption.
Configuring the optin Service
When you load the library, you can setup the optin service directly. The main challenge that I see during the implementation is that the optin service wants you to use the instance of the class as parameter.
The library provides you with an enum of the different solutions and you can only use that enum to setup your code. Because most of our colleagues in analytics are self-taught programmer, they are not used to be forced on certain variable definition.
You can actually see this enum usage on the example in the documentation.
They are located in this dimension
adobe.OptInCategories
And they can be used during the initialization setup.
In the following example, we are setting an object with these values and passing this object to Experience Cloud ID Service init function.
var preOptInApprovalsConfig = {};
preOptInApprovals[adobe.OptInCategories.ECID] = true;
Visitor.getInstance("YOUR_ORG_ID", {
"doesOptInApply": true, // NOTE: This can be a function that evaluates to true or false.
"preOptInApprovals": preOptInApprovalsConfig,
});
In case you are storing the values of the consent on your side, you can use the “previousPermission” parameter and the object is following the same structure, except this one you can use the same key and value and don’t have to use the enum.
The main deal with the Optin service is that it is the only one capable of blocking the launch of the Experience Cloud ID service.
If you are blocking the execution of the ECID service, this will not generate a cookie for the user (on demdex.net or on your domain), because the service is not running.
Adobe Analytics will use the legacy cookie for the user though.
Adobe Analytics & AAM
Adobe Analytics has several ways to prevent a call to the Adobe Analytics. There is even a way to delete information if there has been a mistake.
You can obviously setup a condition in your Launch implementation in order to prevent the firing of the tag in case the consent has not been given. This one is easy.
You can also use the s.abort = true statement in order to prevent the firing of a request. In the Launch Mobile SDK, the requests are not sent until you have setup the consent. See this post from Jan Exner on the topic.
What Adobe can do is also to use the Data Repair API if you have done a mistake and data got in by mistake. This option is not free and there is no way to select a specific request to be deleted. So it is really the last resort.
Still it is interesting that this option exists.
The data repair API is available since end of 2020 and you can find the documentation here.
The main challenge is if you are using Adobe Audience Manager at the same time.
Adobe provides a (recommended) solutio, the Server Side Forwarding that pass the information from Adobe Analytics to Audience Manager directly. That is quite nice because you don’t need to tag again the whole website with a new library. Everything happens on the server side as the data are being pass to Audience Manager.
Two things there:
- You need to enable the Server Side Forwarding option on your reportSuite. Otherwise, it won’t work.
- You need to have a condition set up in a Trait in order for this data to be used. If you don’t have any qualification traits in place, it just flows through. Nothing is stored.
The thing is that Audience Manager is for marketing purpose and Analytics for Analytics. When we can have the ECID and Analytics running for legitimate interest on our website performance, the usage of Audience Manager ruins that.
Not to worry too much, Adobe provides a flag that you can use in order to prevent the data to be passed (and billed) from Analytics to Audience Manager.
Using the context data “cm.ssf” with the value of 1 will prevent this behavior to take place. Even if you are sending the data to Audience Manager, the server will see this flag and block the request to flow to the AAM server.
The official documentation here.
The Privacy JS
OK, now you have another challenge.
You have respected the user consent but he actualy changed his/her mind and now wants that you delete the data that you have on him.
Adobe also provides this functionality but it is a bit more complex and require a multiple steps approach.
The first step is to retrieve the ID that you have on this user. You can realize that (and delete them – on the front end) by using the Adobe Privacy JS file (github repo) .
This library allows you to retrieve the identity that you have on the front end, at the moment of the request.
The usual process is that you have a specific page where the user are asking to remove the data (or access it) and that you load that library only on that page.
When the user is clicking on a button, it is retrieving the identities (and deleting them if required).
Be careful when you instanciate the library, you need to setup the context of the solutions you are using on Adobe.
In the example shown in the documentation, there is an instanciation with Adobe Analytics (reportSuite & Tracking server) but also with Adobe Target (client code).
var adobePrivacy = new AdobePrivacy({
imsOrgID: "{IMS_ORG}",
reportSuite: "{REPORT_SUITE_ID}",
trackingServer: "{SERVER_URL}",
clientCode: "{TARGET_CLIENT_CODE}"
});
The important next step is that you save these identities on your system. Do not just delete the front end variable. Especially if there is a user request.
Also, the function is a Promise so you can access the result once the promise has been resolved.
If you want to have a snapshot code on how to realize a request, below is a test code you can use.
/* function with window scope to access them later*/
let validIDs
;
let failedIDs
;
/*function that will be used in the callback*/
function handleRetrievedIDs(ids) {
validIDs = ids.validIDs;
failedIDs = ids.failedIDs;
}
/* Using the instance to retrieve the information */
result = adobePrivacy.retrieveIdentities(handleRetrievedIDs);
/* Looking at the result, 2 methods: */
validIDs // calling the valid ids
// using the promise resolution
result.then(res=>{console.log('success',res)},res=>{console.log('failure',res)})
The Adobe Privacy API (& UI)
Once you have these ID retrieved, you can then use them in your API call in order to either retrieve the data or just ensure the removal has been realized.
The API can be used raw with your own connection or with the PrivacyUI that is a wrapper around the API.
I would recommend to implement your own API wrapper for this functionality because it most probably needs to be an automated process.
If you rely on the privacy UI, you would need to manually enter and check the different jobs that you have created. Depending on the size of your website, it may well not be a scalable task.
It is important to note that the API documentation is hosted in the Platform documentation even if the connection in console.adobe.io is not the same than the one for Platform.
I think it is an error because it implies that you can use the same JWT meta scope but it is not the case.
I am sorry for how long this post was, but there was a lot to unpack as you can imagine. I hope that you found that article helpful. Let me know if you have any comments.