Most Powerful Open Source ERP

Consequences of the CJEU/CNIL decision on HDH

Due to Shrems II ruling by the CJUE, using US or China clouds to process or store personal data of EU residents could be illegal. Practical solution to mitigate legal risks combines local hosting by independent companies and global orchestration without access to data.
  • Last Update:2020-10-14
  • Version:001
  • Language:en

France's National Commission on Informatics and Liberty (CNIL) ruled on 8th October 2020 that it was illegal to store personal health data of EU residents on any cloud operated by a US company or by a European company with business in the US:



Unlike Tik Tok in the US or Facebook in China, US clouds are not banned in the EU. However, using US clouds to process or store personal data of EU residents could be illegal. Using EU clouds submitted to US laws to process or store personal data of EU residents could also be illegal.

This situation is a direct consequence of the "Shrems II" ruling by the Court of Justice of the European Union (CJEU), an equivalent in EU of the US Supreme Court, which applies to all EU.


France's CNIL had thus to apply "Shrems II" ruling in its decision. Currently, EU residents have no appeal if US authorities remotely access their personal data stored in EU through legal enforcement laws such as CLOUD Act, FISA and Executive Order 12333.

CNIL suggests that in order to preserve fundamental liberties, personal health data should be stored on a cloud operated in Europe by juridical entities that are completely independent of any business activity in the US. CNIL suggests technology licensing approaches for US clouds to operate legally in EU whenever personal data of EU citizens needs to be stored.

Even though CNIL does not say anything about it, the same legal reasoning could apply to other sensitive personal data.

Conseil d'Etat (an equivalent in France of US Supreme Court) confirms in its decision that it is imposible for French government to control unsolicited access by US goverment to personal data stored on US clouds or on clouds subject to US law. Conseil d'Etat confirms that new projects involving personal health data must not use US clouds or clouds subject to US law.


It is very likely that similar decision would be taken by CNIL for personal data stored on a Chinese cloud provider for similar reasons realted to China Internet Security Law of 2016.

Understanding the reasoning behind the ruling

Let us consider the following parties

Parties in presence
Letter Name
K An EU resident
X A company or government using services of Y to store data of K
Y A cloud company with business activity in EU and in country Z
Z A country outside EU with some extra-territorial law

Because country Z can request to Y personal data of K stored by X on the cloud of Y, and because K can not appeal against this request of Z, and because Y can not refuse the request of Z due to its presence in Z and some extra-territorial law, then fundamental rights of K are violated. In application of proportionality principle and if X stores a lot of sensitive personal data, X is reponsible of this situation and should thus stop using Y. It does not matter whether data of K is stored inside EU or outside EU.

Practical mitigation

It is safe to consider that in order to avoid any litigation risk, companies which store personal data of EU residents on the cloud and especially sensitive personal data should migrate to a cloud provider which is not submitted to CLOUD Act, FISA, Executive Order 12333 or possibly China Internet Security Law.

If personal data is not encrypted, it is safe to store it on servers:

  • located inside EU, to ensure the absence of foreign jurisdiction;
  • controlled by an "independent" EU company.

Here are some examples of "independent" EU companies:

  • an EU company with a majority of EU stockholders and no business in US or China;
  • an EU company with a majority of EU stockholders and which business in US or China is operated through a subsidiary with an independent governance.

This second example still needs to be confirmed.

If personal data is encrypted, personal data could be stored on servers outside EU in certain cases as long as encryption keys used to access personal data of EU residents do not fall under the control of US or Chinese Law.


One should note that any cloud service which does not have access to personal data does not fall under the scope of CJEU/CNIL decission. An EU company which owns its servers could for example deploy on its own infrastructure a remote orchestration service as long as this remote orchestration service does not have access to personal data on the servers and does not itself store personal data.

Legal evolution

CJEU/CNIL decision will likely be reverted by national court and lead to an appeal at CJEU which will likely confirm the original decision of CNIL.

Consequences of CJEU/CNIL could also evolve if a new Privacy Shield is implemented by EU.


Even though some EU governments are deeply influenced by transatlantic social relations and US-EU business opportunities, a new privacy shield is likely to face increased opposition from citizens. Human right values are no for sale for everyone in EU.

Also, due to the nature of CLOUD Act, FISA and Executive Order 12333, it is likely that any new EU Law which authorizes transatlantic data transfer will lead to "Shrems III" unless the US government abandons its global surveillance policy. The same could be said about Chinese governmment and China Internet Security Law. 

In EU, states are prevented from mass collecting data thanks to the independence of CJEU. EU clouds which are not subject US or China


Beyond EU, US and China, some countries such as Russia or India have implemented or may implement digital sovereignty laws that prevent storing or processing data in EU. Digital surveillance defined in French law is probably incompatible with some privacy laws in Japan.


Russia or China do not allow storing personal data of staff outside Russia. 


Overall, the consequences of "Shrems II" case and CNIL ruling are just one example of similar situations which will happen again in other parts of the word and result from the contradiction between laws related surveillance, fundamental liberties and digital sovereignty. 

Legal risks

It is safer to design an IT system based on the observation that privacy should be enforced in every country and that all countries try to surveil each other through extra-territorial laws without any global framework. China's initiative to set global data security rules is unlikely to be accepted very soon by EU, US or Japan.


In a digital world with ever evolving and mutually conflicting national laws, the safest design for an IT system is to store data on servers owned by a local independent company and only rely on global cloud services that do not have access to data stored on those servers and do not store themselves personal data. Self-hosting can also be an option.

Just like GDPR did not lead to lawsuits immediately, CJEU/CNIL will not lead to lawsuits immediately.

However, privacy is important for citizens in EU, in Japan and in some other countries. Litigation in EU is not very costly and can be financed by a single person. Justice in EU is independent: national states can not control decisions of CJEU, ECHR, etc.

The risk of litigation is increasing for multinational companies that keep on ignoring EU cloud companies. Recent foreign policy in US ("America First") and in China (wolf diplomacy) is creating resentment among European population. Litigations against companies which store personal data of EU residents on clouds subject to US or China's laws will likely increase.

GDPR fines can be as high as 20,000,000€ or 4% of a company's yearly incom.


In this context, the safest approach for a company operating in the EU is to increase their use of EU cloud services that respect privacy. Another safe solution is to build their own cloud in the EU based on open source software and guarantee full auditability. One way to ensure that an EU cloud service respects privacy is to request access to operation management procedures and audits, something that companies such as BSO or Rapid.Space already provide. Another way is to verify compliance of the service with privacy standards, something which the Gaia-X project plans to provide in the future.


Some open source cloud software provided by EU companies:

Some EU cloud providers that try to ensure independence from US and China extra-territorial laws:

Some EU cloud providers that provide access to their operation management procedures:

Some unions of cloud providers that meet health data regulations and include EU members:

Gaia-X project:

08-10 2019

Adding 10000 rows in a table by Unknown User

Hello, I am trying to create a table containing 82 columns and 10000 rows (11028 to be exact) in a sheet. I tried to add the lines one by one and then to do a Sync but the table is not created. I thought it was a lot of data at one time so I tried adding lines in packets of 1000. This time, I get the table but only the first 1000 rows are filled. In the log, I see all the packets go by.   In the code below : - "values" is the json formatted data i try to add  - "tableName" speaks for itself. The steps before 5 are inscriptions of some data in other sheets but these works.   function CreateODataQuerySheetStep5_List(values, tableName) {     let n = values.length;     if (n > 0) {         CreateODataQuerySheetStep5_ListTableHeader(values, tableName);           } else { (context) {             let headers = [["No data"]];             let sheet = context.workbook.worksheets.getItem(newQueryName);             let table = sheet.tables.add("A1", true);    = tableName;             table.getHeaderRowRange().values = headers;             sheet.activate();             window.location.href = "Home.html";             return context.sync();         }).catch(function (error) {             logging(sessionStorage.getItem("Token"), error);         });             } } function CreateODataQuerySheetStep5_ListTableHeader(values, tableName) {     console.log("Creating header"); (context) {         console.log("Get Sheet");         let sheet = context.workbook.worksheets.getItem(newQueryName);         console.log("Define table horizontal length");         let line = values[0];         let keys = Object.keys(line);         let address = "A1:" + ColumnToLetter(keys.length) + "1";         console.log("Computing header columns");         let headers = [];         for (let j = 0; j < keys.length; j++) {             let key = keys[j];             headers.push(key);         }         console.log("Adding table");         let table = sheet.tables.add(address, true); = tableName;         let temp = [];         temp.push(headers);         console.log("Putting header");         table.getHeaderRowRange().values = temp;         return context.sync().then(function () {             console.log("Header created")             CreateODataQuerySheetStep5_List1000(values, 0, tableName, headers);         }).catch(function (error) {             logging(sessionStorage.getItem("Token"), error);         });     }).catch(function (error) {         logging(sessionStorage.getItem("Token"), error);     }); } function CreateODataQuerySheetStep5_List1000(values, start, tableName, headers) {     console.log("Adding 1000 rows"); (context) {         console.log("Get Sheet");         let sheet = context.workbook.worksheets.getItem(newQueryName);         console.log("Get Table");         let table = sheet.tables.getItem(tableName);         console.log("Computing max between 1000 and remaining lines");         let x = values.length - start;         let n = Math.min(1000, x);         console.log("Adding rows from " + start.toString() + " to " + (start + n).toString());         for (let i = start; i < n; i++) {             let line = values[i];             let keys = Object.keys(line);             let row = [];             for (let jj = 0; jj < headers.length; jj++) {                 let prop = headers[jj];                 let value = line[prop];                 if ($.type(value).toLowerCase() === 'string') {                     value = "'" + value;                 }                 row.push(value);             }             table.rows.add(null, [row]);         }         console.log("Rows added");              let y = start + 1000;         if (y < values.length)         {             console.log("Rows are remaining");             return context.sync().then(function () {                 console.log("Recursive Call");                 CreateODataQuerySheetStep5_List1000(values, y, tableName, headers);             }).catch(function (error) {                 logging(sessionStorage.getItem("Token"), error);             });         }         else         {             //if (Office.context.requirements.isSetSupported("ExcelApi", 1.2)) {             //    sheet.getUsedRange().format.autofitColumns();             //    sheet.getUsedRange().format.autofitRows();             //}             console.log("Sheet activation");             sheet.activate();             return context.sync().then(function () {                 console.log("return to home");                 window.location.href = "Home.html";             });         }              }).catch(function (error) {         logging(sessionStorage.getItem("Token"), error);     });      }
31-01 2019

Unprotect the excel sheet with password pro-grammatically using officejs. by Unknown User

await function(context) {   const sheet = context.workbook.worksheets.getActiveWorksheet(); // const workBook = context.workbook. console.log(;"abc") const range = sheet.getUsedRange(); range.load("values"); range.load("address"); return context.sync().then(function () { console.log(range.address); }) }).catch(function(error) { console.log("Error: " + error);   });   Giving Error: Uncaught (in promise): InvalidArgument: The argument is invalid or missing or has an incorrect format.