<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Rijks ICT Gilde</title>
    <description>The latest articles on DEV Community by Rijks ICT Gilde (@rijks-ict-gilde).</description>
    <link>https://dev.to/rijks-ict-gilde</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Forganization%2Fprofile_image%2F379%2F8ecfb227-6bdb-4416-9e25-18b28f9215f4.png</url>
      <title>DEV Community: Rijks ICT Gilde</title>
      <link>https://dev.to/rijks-ict-gilde</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/rijks-ict-gilde"/>
    <language>en</language>
    <item>
      <title>Privacy by design (Pragmatic Privacy for Programmers, Part 3)</title>
      <dc:creator>Jeroen Heijmans</dc:creator>
      <pubDate>Fri, 15 Mar 2019 14:22:44 +0000</pubDate>
      <link>https://dev.to/rijks-ict-gilde/privacy-by-design-pragmatic-privacy-for-programmers-part-3-13oa</link>
      <guid>https://dev.to/rijks-ict-gilde/privacy-by-design-pragmatic-privacy-for-programmers-part-3-13oa</guid>
      <description>&lt;p&gt;In &lt;a href="https://dev.to/rijks-ict-gilde/pragmatic-privacy-for-programmers-part-1-2gh4"&gt;part 1&lt;/a&gt; and &lt;a href="https://dev.to/rijks-ict-gilde/pragmatic-privacy-for-programmers-part-2-5d05"&gt;2&lt;/a&gt; we have been building a very simple "Kitchen Sink" app to demonstrate how we can pragmatically deal with privacy, specifically when following the European Union's &lt;a href="https://eur-lex.europa.eu/legal-content/EN/TXT/PDF/?uri=CELEX:32016R0679&amp;amp;qid=1551798373256&amp;amp;from=NL"&gt;General Data Protection Regulation&lt;/a&gt; (GDPR). In this instalment, we'll try to tackle a rather vague GDPR requirement: privacy by design.&lt;/p&gt;

&lt;h1&gt;
  
  
  A bit of theory again
&lt;/h1&gt;

&lt;p&gt;In part 2, we discussed six responsibilities processors of personal data have under GDPR (lawfulness, purpose limitation, data minimisation, accuracy, storage limitation, integrity &amp;amp; confidentiality). At the time, we skipped a seventh responsibility: accountability. Accountability is specified as both being &lt;em&gt;responsible&lt;/em&gt; for adhering to the other six responsibilities, and being able to &lt;em&gt;demonstrate compliance&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;The law text proceeds to mention several measures to be taken. Many of these, such as processor contracts or data protection officers are either legal or organisational in nature, and are better discussed elsewhere. One of the measures, however, is of particular interest to developers: "data protection by design and by default".&lt;/p&gt;

&lt;p&gt;Privacy by default is a useful concept - it means a person's data is protected without them having to actively do anything about that. In the context of GDPR, it's mostly redundant in my opinion, as it's defined as ensuring purpose limitation, data minimisation, etc. &lt;/p&gt;

&lt;p&gt;As typical is for laws, the definition of privacy by design is rather fuzzy, however. Fortunately, one of the inspirations for GDPR on this topic is of use. The 7 principles of &lt;a href="https://www.ipc.on.ca/wp-content/uploads/Resources/7foundationalprinciples.pdf"&gt;Privacy by Design&lt;/a&gt; (PbD), which dates back from the 1990s, specifies that "[privacy] is not bolted on as an add-on, after the fact." Let's see how to apply this principle for Kitchen Sink.&lt;/p&gt;

&lt;h1&gt;
  
  
  Increment 2 (continued)
&lt;/h1&gt;

&lt;p&gt;In &lt;a href="https://dev.to/rijks-ict-gilde/pragmatic-privacy-for-programmers-part-2-5d05"&gt;increment 2&lt;/a&gt; we started working on a feature that allows users to fill in their postal address so we can send them a hard copy of a photo of a kitchen sink. These addresses are personal data, and are subject to several protective principles under GDPR. We made an overview of these principles, how we've fulfilled them and how we check this fulfilment is still in place (ideally automatically). We ended up with this table:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Principle&lt;/th&gt;
&lt;th&gt;Fulfilment&lt;/th&gt;
&lt;th&gt;Check&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Lawfulness&lt;/td&gt;
&lt;td&gt;Contractual obligation&lt;/td&gt;
&lt;td&gt;Contract (foreign key)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Purpose limitation&lt;/td&gt;
&lt;td&gt;Access limitation&lt;/td&gt;
&lt;td&gt;Test ✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Data minimisation&lt;/td&gt;
&lt;td&gt;UPU suggested address fields&lt;/td&gt;
&lt;td&gt;Test ✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Accuracy&lt;/td&gt;
&lt;td&gt;User input validation&lt;/td&gt;
&lt;td&gt;Contract (column checks) ✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Storage limitation&lt;/td&gt;
&lt;td&gt;Auto removal&lt;/td&gt;
&lt;td&gt;Test ✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Storage limitation&lt;/td&gt;
&lt;td&gt;Backup rollover&lt;/td&gt;
&lt;td&gt;Test ✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Integrity &amp;amp; confidentiality&lt;/td&gt;
&lt;td&gt;HTTPS&lt;/td&gt;
&lt;td&gt;Test ✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Integrity &amp;amp; confidentiality&lt;/td&gt;
&lt;td&gt;Secure components&lt;/td&gt;
&lt;td&gt;Test ✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Integrity &amp;amp; confidentiality&lt;/td&gt;
&lt;td&gt;Strong authentication&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;We'll continue with this approach and add "Privacy by Design" as a principle to the list. Now we'll have to see how we can fulfil it and check it:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Principle&lt;/th&gt;
&lt;th&gt;Fulfilment&lt;/th&gt;
&lt;th&gt;Check&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Privacy by design&lt;/td&gt;
&lt;td&gt;TBD&lt;/td&gt;
&lt;td&gt;TBD&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Fulfilment
&lt;/h2&gt;

&lt;p&gt;Doing something "by design" is one of these things that are easy to agree on - it sounds like a good thing - but hard to do. There are no clear steps or activities to perform to achieve the goal. The best PbD has to offer is a documentation standard called &lt;a href="https://docs.oasis-open.org/pbd-se/pbd-se/v1.0/pbd-se-v1.0.html"&gt;"Privacy by Design for Software Engineers"&lt;/a&gt;. Unfortunately, it's mostly a list of documentation to be generated for each principle. Apart from (seemingly) not being very Agile, it's not really specific. It states rules like "documentation shall contain a privacy architecture", but doesn't go to say what that is and what it should look like.&lt;/p&gt;

&lt;p&gt;Fortunately, others have been more concrete. ENISA, the EU's agency for network and information security, gives a very good &lt;a href="https://www.enisa.europa.eu/publications/privacy-and-data-protection-by-design"&gt;privacy by design overview&lt;/a&gt; (the EU's agency for network and information security). Specifically, it provides one tool that I think is ideal for our purposes here: privacy design strategies.&lt;/p&gt;

&lt;p&gt;These strategies have been devised by associate professor Hoekman, who also wrote an &lt;a href="https://www.cs.ru.nl/J.H.Hoepman/publications/pds-booklet.pdf"&gt;excellent booklet&lt;/a&gt; on them. In total, he identifies eight strategies for dealing with privacy when making a design. We can incorporate this into our checks above by making sure we've considered all eight strategies for the personal data in question.&lt;/p&gt;

&lt;p&gt;For brevity's sake, I'll only go through the first four strategies (Minimize, Separate, Abstract and Hide). The other four are "process oriented strategies". While these are definitely valuable to consider, they are, well, more process oriented and they also overlap with GDPR requirements which are handled elsewhere in this series. That's not a reason to always skip these, since these principles can go beyond what's strictly required by law and provide additional approaches.&lt;/p&gt;

&lt;h2&gt;
  
  
  Strategy 1: Minimize
&lt;/h2&gt;

&lt;p&gt;In &lt;a href="https://dev.to/rijks-ict-gilde/pragmatic-privacy-for-programmers-part-2-5d05"&gt;part 2&lt;/a&gt;, we already discussed minimisation of personal data. We only store attributes we really need, and only for people who actually request a photo. But we could go further and consider if we could do it without storing personal data at all. I'm not sure how we could do this for letters, but it's possible in other situations. For example, if you're building an iOS app, &lt;a href="https://developer.apple.com/documentation/usernotifications?language=objc"&gt;it's possible to send push messages&lt;/a&gt; to the user without knowing their phone number, Apple ID, or any other personal data. Instead, you get a token that you use to send data to Apple, which then makes sure it ends up on the right phone. &lt;/p&gt;

&lt;p&gt;Another angle would be to give people the option not to share their personal data and offer an alternative. Perhaps people want to pick up their photo in person at my place or, more likely, at a pick up point near them. Some delivery services offer that option, and it's worth considering giving users some choice in the matter. The impact of this doesn't end with privacy: it may be more costly to use such a service, it may scare away users that don't live near a pickup point, etc. As with all design decisions, we should briefly document the trade-off and the decision so we can honestly say we've considered the options here.&lt;/p&gt;

&lt;h2&gt;
  
  
  Strategy 2: Separate
&lt;/h2&gt;

&lt;p&gt;In an ideal case of the separation strategy, personal data would remain in control of the owner, and not end up at our servers at all. I don't see any realistic options for this for Kitchen Sink, but in the future &lt;a href="https://solid.inrupt.com"&gt;initiatives like that of Tim Berners-Lee&lt;/a&gt; might allow for this.&lt;/p&gt;

&lt;p&gt;But simpler separation options are available to us today. We could make sure the application part that retrieves the addresses from the database is separate from the web site. We could also ensure different (physical or virtual) servers are used to host the database and the web server. Both of these are reasonable steps to take.&lt;/p&gt;

&lt;h2&gt;
  
  
  Strategy 3: Abstract
&lt;/h2&gt;

&lt;p&gt;Hoepman describes abstraction as "zooming out" on the data. We applied this strategy in the &lt;a href="https://dev.to/rijks-ict-gilde/pragmatic-privacy-for-programmers-part-1-2gh4"&gt;first part&lt;/a&gt; of the series, when we left out part of IP addresses to remove precise information while still allowing us to use it for traffic analysis.&lt;/p&gt;

&lt;p&gt;For the address data we're collecting, such an approach doesn't work as we need it to be precise to send the photo. But if we wanted to collect statistics on where we've sent photos, we could use this approach and for example only keep the city or state/province.&lt;/p&gt;

&lt;h2&gt;
  
  
  Strategy 4: Hide
&lt;/h2&gt;

&lt;p&gt;We've taken some steps to hide the personal data already in Kitchen Sink. Access to the data is restricted, as only the person sending the envelopes is allowed to read data from the database. Furthermore, the address data is not linked to any other personal data (e.g. IP addresses).&lt;/p&gt;

&lt;p&gt;Further hiding is still possible: we can choose to encrypt the data in the database, for example, but that seems of limited benefit while increasing technical complexity of the application.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;With the above design considerations, we can say we've tried to apply privacy by design. Of course, we should present some evidence to illustrate our compliance. A simple link to the above decisions and considerations would be enough, for example if they're summarised in a design document. This can be a formal versioned document, a wiki, or just a plain text document with some contents. &lt;/p&gt;

&lt;p&gt;This should give the following table:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Principle&lt;/th&gt;
&lt;th&gt;Fulfillment&lt;/th&gt;
&lt;th&gt;Check&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Privacy by design&lt;/td&gt;
&lt;td&gt;Checklist &amp;amp; Documentation&lt;/td&gt;
&lt;td&gt;
&lt;a&gt;Minimize&lt;/a&gt; ✅&lt;br&gt;&lt;a&gt;Separate&lt;/a&gt; ✅&lt;br&gt;&lt;a&gt;Abstract&lt;/a&gt; ✅&lt;br&gt;&lt;a&gt;Hide&lt;/a&gt; ✅&lt;br&gt;&lt;a&gt;Inform&lt;/a&gt; ✅&lt;br&gt;&lt;a&gt;Control&lt;/a&gt; ✅&lt;br&gt;&lt;a&gt;Enforce&lt;/a&gt; ✅&lt;br&gt;&lt;a&gt;Demonstrate&lt;/a&gt; ✅&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;In the next part of the series, we'll continue our iteration as we still need to address the data owner's rights for our address data.&lt;/p&gt;

&lt;p&gt;In the meanwhile, the two resources above are recommended for further reading:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://www.enisa.europa.eu/publications/privacy-and-data-protection-by-design"&gt;Privacy and Data Protection by Design – from policy to engineering&lt;/a&gt; by ENISA&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.cs.ru.nl/J.H.Hoepman/publications/pds-booklet.pdf"&gt;Privacy Design Strategies (The Little Blue Book)&lt;/a&gt; by Jaap-Henk Hoepman&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;Photo by &lt;a href="https://unsplash.com/photos/ChxHHjesbSM?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText"&gt;Jose Soriano&lt;/a&gt; on &lt;a href="https://unsplash.com/"&gt;Unsplash&lt;/a&gt;&lt;/p&gt;

</description>
      <category>privacy</category>
      <category>security</category>
      <category>design</category>
      <category>architecture</category>
    </item>
    <item>
      <title>Pragmatic Privacy for Programmers (Part 2)</title>
      <dc:creator>Jeroen Heijmans</dc:creator>
      <pubDate>Tue, 19 Feb 2019 17:42:02 +0000</pubDate>
      <link>https://dev.to/rijks-ict-gilde/pragmatic-privacy-for-programmers-part-2-5d05</link>
      <guid>https://dev.to/rijks-ict-gilde/pragmatic-privacy-for-programmers-part-2-5d05</guid>
      <description>&lt;p&gt;In &lt;a href="https://dev.to/rijks-ict-gilde/pragmatic-privacy-for-programmers-part-1-2gh4"&gt;part 1&lt;/a&gt; of this series, we started with a simple approach to handling (GDPR) privacy concerns in an imaginary Kitchen Sink app. &lt;/p&gt;

&lt;p&gt;We developed a simple checklist for each feature to see if we were &lt;em&gt;compliant&lt;/em&gt; with all privacy requirements. Even for a simple static site, there was a privacy issue which resulted in this tiny compliance table:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Information Related To Person&lt;/th&gt;
&lt;th&gt;Person identifiable?&lt;/th&gt;
&lt;th&gt;Depersonalized?&lt;/th&gt;
&lt;th&gt;Duties fulfilled?&lt;/th&gt;
&lt;th&gt;Owner Rights supported?&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Website visit&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;Yes (Masking) ✅&lt;/td&gt;
&lt;td&gt;NA&lt;/td&gt;
&lt;td&gt;NA&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;In this second part, we'll do a second increment on Kitchen Sink. &lt;/p&gt;

&lt;h1&gt;
  
  
  Another bit of theory
&lt;/h1&gt;

&lt;p&gt;One of the key elements of privacy (as given in part 1) is that processors* of personal data have certain duties to fulfil. If we actually want to fulfil these duties, it's time to know what they are. &lt;/p&gt;

&lt;p&gt;&lt;em&gt;(*) GDPR actually distinguishes between responsibilties of processors and controllers, but we lump these responsibilities together here.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Once again following the &lt;a href="https://eur-lex.europa.eu/legal-content/EN/TXT/PDF/?uri=CELEX:32016R0679&amp;amp;qid=1541482324985&amp;amp;from=EN"&gt;General Data Protection Regulation&lt;/a&gt; (GDPR), it outlines six principles related to the processing of personal data:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Lawfulness, fairness and transparency: have a valid reason for processing personal data, use personal data in fair and expected ways, and communicate clearly and openly about this&lt;/li&gt;
&lt;li&gt;Purpose limitation: only use personal data for the stated purpose&lt;/li&gt;
&lt;li&gt;Data minimisation: only collect the minimum amount of personal data needed&lt;/li&gt;
&lt;li&gt;Accuracy: try to ensure personal data is correct&lt;/li&gt;
&lt;li&gt;Storage limitation: keep the personal data only as long as is needed&lt;/li&gt;
&lt;li&gt;Integrity &amp;amp; confidentiality: safeguard personal data from unauthorised reading or modification&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Being principles, these are not ready to go duties, but they do help understanding and grouping the actual duties as specified by GDPR. They also make a good list to use when working on our app.&lt;/p&gt;

&lt;p&gt;Those of you who followed the above link to GDPR may have noticed there's actually a seventh duty: accountability. Since GDPR lists it separately, and it's a big topic, we'll treat it in a separate article.&lt;/p&gt;

&lt;h1&gt;
  
  
  Increment 2: sending pictures of kitchen sinks
&lt;/h1&gt;

&lt;p&gt;In order to make our static Kitchen Sink app a bit more "exciting", we're going to add a new feature: visitors to the site can order the picture of the Kitchen Sink, and we'll send them a hard copy in the mail. To be able to do so, they only have to provide their address information. Since we don't expect lots of people wanting a kitchen sink photograph, we'll be handling the mailing manually and free of charge. &lt;/p&gt;

&lt;p&gt;Clearly, address information relates to a person, and it's certainly possible to identify a person based on an address. So we'll add it to our list below: &lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Information Related To Person&lt;/th&gt;
&lt;th&gt;Person identifiable?&lt;/th&gt;
&lt;th&gt;Depersonalized?&lt;/th&gt;
&lt;th&gt;Duties fulfilled?&lt;/th&gt;
&lt;th&gt;Owner Rights supported?&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Website visit&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;Yes (Masking) ✅&lt;/td&gt;
&lt;td&gt;NA&lt;/td&gt;
&lt;td&gt;NA&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Address&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;N/A&lt;/td&gt;
&lt;td&gt;TBD&lt;/td&gt;
&lt;td&gt;TBD&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Since we have six duties, we'll fill the field above with another (small) table:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Principle&lt;/th&gt;
&lt;th&gt;Fulfillment&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Lawfulness&lt;/td&gt;
&lt;td&gt;TBD&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Purpose limitation&lt;/td&gt;
&lt;td&gt;TBD&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Data minimisation&lt;/td&gt;
&lt;td&gt;TBD&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Accuracy&lt;/td&gt;
&lt;td&gt;TBD&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Storage limitation&lt;/td&gt;
&lt;td&gt;TBD&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Integrity &amp;amp; confidentiality&lt;/td&gt;
&lt;td&gt;TBD&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Lawfulness, fairness and transparency
&lt;/h2&gt;

&lt;p&gt;The first principle is really more a group of principles. The most important one is lawfulness: do we have a valid reason for processing personal data? In our case, there's a clear functional need: otherwise we cannot mail the photograph! Under GDPR, there are &lt;a href="http://www.gdprtoons.com/2017/08/the-gdpr-provides-six-6-grounds-for_29.html"&gt;six valid reasons for processing personal data&lt;/a&gt;, and one of them is contractual obligation. While our contract is informal, it still applies here.&lt;/p&gt;

&lt;p&gt;This means we should be able to show that every address we store is linked to a contract. A simple way to do that - assuming we have a relational database - is to create a one-to-one relationship between the &lt;code&gt;contracts&lt;/code&gt; and &lt;code&gt;addresses&lt;/code&gt; tables, and enforce it using a &lt;a href="https://www.sqltutorial.org/sql-foreign-key/"&gt;foreign key constraint&lt;/a&gt;. This ensures that no address is stored without a corresponding contract, and that if the contract is removed, so is the address. (If we want to use NoSQL or store the address data in the &lt;code&gt;contracts&lt;/code&gt; table, we'll have to write some tests to checks ourselves.) Our table now looks like this:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Principle&lt;/th&gt;
&lt;th&gt;Fulfillment&lt;/th&gt;
&lt;th&gt;Check&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Lawfulness&lt;/td&gt;
&lt;td&gt;Contractual obligation&lt;/td&gt;
&lt;td&gt;Contract (foreign key)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;You might have noticed that we're missing the other two parts of this principle: fairness and transparency. Both are concepts not  directly related to duties that we can test for here. Since they are also strongly related to one of the owner's rights (the right to be informed), we will deal with them in an upcoming part of the series.&lt;/p&gt;

&lt;h2&gt;
  
  
  Purpose limitation
&lt;/h2&gt;

&lt;p&gt;We stated we will use the address to fulfil a contractual obligation: mailing a photo. That means we cannot use it for anything else, unless it's "compatible" with the original purpose. In our case, we don't have any uses outside sending the photo. &lt;/p&gt;

&lt;p&gt;While that means we are not legally allowed to, say, use these addresses to subscribe everybody to my new Kitchen Sink Monthly magazine, there's very little physically stopping me from doing so. And while trusting your future self is already risky, the risk grows if more people are involved. The two principles of storage limitation and data minimisation (see below) will help with this, but we can do more.&lt;/p&gt;

&lt;p&gt;One is that nobody should have access to the addresses, except the people or processes that actually need it. This fits under the broader &lt;a href="https://digitalguardian.com/blog/what-principle-least-privilege-polp-best-practice-information-security-and-compliance"&gt;principle of least privilege&lt;/a&gt;.In our case, it means that the Kitchen Sink web app should only have insert access to the &lt;code&gt;address&lt;/code&gt; table, because it only has to store new entries, but no select, update or delete privileges.&lt;/p&gt;

&lt;p&gt;We can test if these privileges have been set up with a test that reads the database privileges and checks only the &lt;code&gt;mail-sender&lt;/code&gt; user has read access to the &lt;code&gt;addresses&lt;/code&gt; table.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Principle&lt;/th&gt;
&lt;th&gt;Fulfillment&lt;/th&gt;
&lt;th&gt;Check&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Lawfulness&lt;/td&gt;
&lt;td&gt;Contractual obligation&lt;/td&gt;
&lt;td&gt;Contract (foreign key)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Purpose limitation&lt;/td&gt;
&lt;td&gt;Access limitation&lt;/td&gt;
&lt;td&gt;Test ✅&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;We could do more here. For example, we can enable &lt;a href="https://www.datamation.com/columns/article.php/3578916/The-Importance-of-Audit-Logs.htm"&gt;audit logging&lt;/a&gt;. This will not prevent addresses from being used for other purposes, but can help detecting if it happens. Setting up audit logging in a secure and useful way can be quite a hassle, however, and for our simple application this is a large investment to cover a tiny risk. GPDR allows such considerations when discussing measures to protect data, and it is valid to not take measures provided the risk is reasonable.&lt;/p&gt;

&lt;h2&gt;
  
  
  Data minimisation
&lt;/h2&gt;

&lt;p&gt;We should only collect personal data that is "adequate, relevant and limited to what is necessary". That means we cannot collect information we don't need for our purpose of sending a letter, such as a date of birth. But it also means we don't have to get overly minimalistic. In the Netherlands, where I live, in practice sending a letter will in many cases work with just a postal code and house number. A name, street and town are relevant to the purpose, and are in fact recommend by in the &lt;a href="http://www.upu.int/en/activities/addressing/postal-addressing-systems-in-member-countries.html"&gt;Universal Postal Union's addressing guidelines&lt;/a&gt; for Netherlands. &lt;/p&gt;

&lt;p&gt;Sticking to Dutch addresses only, we need to add four fields to our &lt;code&gt;addresses&lt;/code&gt; database table: &lt;code&gt;name&lt;/code&gt;, &lt;code&gt;streetAndNumber&lt;/code&gt;, &lt;code&gt;postal Code&lt;/code&gt; and &lt;code&gt;town&lt;/code&gt;. In order to prevent unverified personal data fields from being added to the database table, we can add a simple test that checks the column names of the &lt;code&gt;addresses&lt;/code&gt; table, and fails if it encounters a non-whitelisted column.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Principle&lt;/th&gt;
&lt;th&gt;Fulfillment&lt;/th&gt;
&lt;th&gt;Check&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Lawfulness&lt;/td&gt;
&lt;td&gt;Contractual obligation&lt;/td&gt;
&lt;td&gt;Contract (foreign key)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Purpose limitation&lt;/td&gt;
&lt;td&gt;Access limitation&lt;/td&gt;
&lt;td&gt;Test ✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Data minimisation&lt;/td&gt;
&lt;td&gt;UPU suggested address fields&lt;/td&gt;
&lt;td&gt;Test ✅&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Accuracy
&lt;/h2&gt;

&lt;p&gt;When storing personal data, we are responsible for making sure personal data is accurate, up-to-date and rectified as soon as possible. Since we only keep the addresses until we've jotted them on an envelope (see storage limitation), an update or rectification process is not necessary for us. We still have to take "reasonable" steps to ensure the data we record is accurate, though.&lt;/p&gt;

&lt;p&gt;Since the impact of this data being wrong is very limited, we can get away with some minimal steps here. An obvious one would be to do some user input validation. In our cases, we could require that all fields are non-empty, and that postal code have the &lt;a href="https://en.wikipedia.org/wiki/Postal_codes_in_the_Netherlands"&gt;correct format&lt;/a&gt;.  A more advanced approach could be a look-up of the post code to verify (or auto-fill) it matches the street and place name. But since Kitchen Sink isn't bringing in any money, and these are paid services, so we'll leave out that check.&lt;/p&gt;

&lt;p&gt;In addition to unit tests for the validation code, we can test this by looking at the actual data in the database and perform the same checks (non-empty, valid postal code). However, that has the downside of requiring our checks to read the data, which is not ideal. It would be better to add these as a contract to the database model. SQL databases &lt;a href="https://www.sqltutorial.org/sql-check-constraint/"&gt;can do this by using &lt;code&gt;CHECK&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Principle&lt;/th&gt;
&lt;th&gt;Fulfillment&lt;/th&gt;
&lt;th&gt;Check&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Lawfulness&lt;/td&gt;
&lt;td&gt;Contractual obligation&lt;/td&gt;
&lt;td&gt;Contract (foreign key)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Purpose limitation&lt;/td&gt;
&lt;td&gt;Access limitation&lt;/td&gt;
&lt;td&gt;Test ✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Data minimisation&lt;/td&gt;
&lt;td&gt;UPU suggested address fields&lt;/td&gt;
&lt;td&gt;Test ✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Accuracy&lt;/td&gt;
&lt;td&gt;User input validation&lt;/td&gt;
&lt;td&gt;Contract (column checks) ✅&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Storage limitation
&lt;/h2&gt;

&lt;p&gt;If we no longer need personal data for the reason we acquired it, we must get rid of it. In our simplistic case, we no longer need the address after we've written it on the envelope and put it in the mailbox. (If we'd be a bit more sophisticated, we might want to keep it a bit longer to handle track-and-trace, return deliveries, etc.) We could choose to manually delete every address record after that has happened, but manual actions are error prone and easily forgotten - in which case we'd be stuck with personal data we're not allowed to retain.&lt;/p&gt;

&lt;p&gt;An automated cleanup process is more robust. For example, if we record when addresses are retrieved by the person sending the mail, we can run a daily job that deletes all addresses received before that point in time. We can run a test checking if that went well, counting the amount of "old" records. (Note this has the same downside as mentioned above for accuracy. We can work around it here by creating a view on the &lt;code&gt;addresses&lt;/code&gt; table with only the old records and give access to that.)&lt;/p&gt;

&lt;p&gt;A second issue we should address is backups. It's a good practice to set these up, but they will of course also contain personal data. Since we'd like to avoid having to remove individual addresses from a backup file, we need a different approach. It's reasonable that we keep a backup around for a limited amount of days - let's say 30 days - and remove it afterwards. This is a fairly standard setup alled "rolling backups". We can verify by checking the age of the oldest backup is at most 30 days.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Principle&lt;/th&gt;
&lt;th&gt;Fulfillment&lt;/th&gt;
&lt;th&gt;Check&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Lawfulness&lt;/td&gt;
&lt;td&gt;Contractual obligation&lt;/td&gt;
&lt;td&gt;Contract (foreign key)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Purpose limitation&lt;/td&gt;
&lt;td&gt;Access limitation&lt;/td&gt;
&lt;td&gt;Test ✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Data minimisation&lt;/td&gt;
&lt;td&gt;UPU suggested address fields&lt;/td&gt;
&lt;td&gt;Test ✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Accuracy&lt;/td&gt;
&lt;td&gt;User input validation&lt;/td&gt;
&lt;td&gt;Contract (column checks) ✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Storage limitation&lt;/td&gt;
&lt;td&gt;Auto removal&lt;/td&gt;
&lt;td&gt;Test ✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Storage limitation&lt;/td&gt;
&lt;td&gt;Backup rollover&lt;/td&gt;
&lt;td&gt;Test ✅&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Integrity &amp;amp; confidentiality
&lt;/h2&gt;

&lt;p&gt;This is by far the broadest and most difficult principle to ensure. Integrity and confidentiality are two of the three traditional &lt;a href="https://en.wikipedia.org/wiki/Information_security#Key_concepts"&gt;key concepts of information security&lt;/a&gt;, known as the "CIA triad". Properly securing applications is way beyond the scope of this post, but fortunately many others have written extensively about this (see the reading suggestions below). Moreover, verifying that applications are properly secured is not trivial either. Just look at OWASPS &lt;a href="https://www.owasp.org/index.php/Category:OWASP_Application_Security_Verification_Standard_Project"&gt;Application Security Verification Standard&lt;/a&gt; (ASVS); there's nearly 200 checks you might perform for a web application. For several of these, automation is either difficult, expensive, or both. I will list two measures we can take in our Kitchen Sink app, though, to give an impression of what we can do here.&lt;/p&gt;

&lt;p&gt;Let's start with HTTPS. While slowly becoming the default, there's still &lt;a href="https://whynohttps.com"&gt;many sites that don't protect traffic between browser and web server&lt;/a&gt;. There's really no excuse not to use it anymore, with &lt;a href="http://letsencrypt.org"&gt;Let's Encrypt&lt;/a&gt; offering free certificates, and web servers like &lt;a href="http://caddyserver.com"&gt;Caddy&lt;/a&gt; having it enabled by default. We can even verify HTTPS is setup correctly with an automated test using one of the free HTTPS configuration checkers out there. I like the one by &lt;a href="https://www.ssllabs.com/ssltest/"&gt;SSL Labs&lt;/a&gt;, but there's others out there. &lt;/p&gt;

&lt;p&gt;A second security is that's getting increasingly common is vulnerabilities in third party components. For a simple web app we likely already depend on a web application framework, a programming language, a web server, a database, an operating system and several libraries to glue these together. All of these, whether open source or proprietary, may contain vulnerabilities, and these are regularly discovered and exploited. Checking all your components regularly and patching, upgrading or moving away from vulnerable ones is the best practice here. While you can make that into a manual process, (partial) support is available. Source control giant GitHub has support to &lt;a href="https://help.github.com/articles/viewing-and-updating-vulnerable-dependencies-in-your-repository/"&gt;check vulnerable libraries&lt;/a&gt; for some languages, as do tools like &lt;a href="https://snyk.io"&gt;Snyk&lt;/a&gt; or &lt;a href="https://dependabot.com"&gt;Dependabot&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Earlier, we already mentioned the principle of least privilege, ensuring users have only the minimum privilege required. But to use these user accounts securely, we should secure them properly. This includes protecting them with a password or with SSH keys, but also limiting the IP addresses they can connect from (ideally, the database isn't even reachable from the entire internet). If you use a password or SSH keys, you should have strength requirements for those, ideally enforced by the database (e.g. in MySQL there's the &lt;a href="https://dev.mysql.com/doc/refman/8.0/en/validate-password.html"&gt;password validation component&lt;/a&gt;). Unfortunately, I'm not aware of any (easy) way in which we can verify that this is set up correctly.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Principle&lt;/th&gt;
&lt;th&gt;Fulfillment&lt;/th&gt;
&lt;th&gt;Check&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Lawfulness&lt;/td&gt;
&lt;td&gt;Contractual obligation&lt;/td&gt;
&lt;td&gt;Contract (foreign key)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Purpose limitation&lt;/td&gt;
&lt;td&gt;Access limitation&lt;/td&gt;
&lt;td&gt;Test ✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Data minimisation&lt;/td&gt;
&lt;td&gt;UPU suggested address fields&lt;/td&gt;
&lt;td&gt;Test ✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Accuracy&lt;/td&gt;
&lt;td&gt;User input validation&lt;/td&gt;
&lt;td&gt;Contract (column checks) ✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Storage limitation&lt;/td&gt;
&lt;td&gt;Auto removal&lt;/td&gt;
&lt;td&gt;Test ✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Storage limitation&lt;/td&gt;
&lt;td&gt;Backup rollover&lt;/td&gt;
&lt;td&gt;Test ✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Integrity &amp;amp; confidentiality&lt;/td&gt;
&lt;td&gt;HTTPS&lt;/td&gt;
&lt;td&gt;Test ✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Integrity &amp;amp; confidentiality&lt;/td&gt;
&lt;td&gt;Secure components&lt;/td&gt;
&lt;td&gt;Test ✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Integrity &amp;amp; confidentiality&lt;/td&gt;
&lt;td&gt;Strong authentication&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;This last gap in verification is typical for security. While there are (expensive) tools that cover a lot of security issues, ultimately &lt;a href="http://www.veracode.com/security/penetration-testing"&gt;manual verification&lt;/a&gt; is usually in order. Be sure to hire a professional for key applications, but don't be afraid to &lt;a href="http://hack-yourself-first.com"&gt;do it yourself&lt;/a&gt; either.&lt;/p&gt;

&lt;p&gt;This marks the end this post, but not of this iteration. Our checklist still has the "Owner Rights supported?" column marked as to be done. In the next part, we'll address that gap.&lt;/p&gt;

&lt;p&gt;In the meanwhile, here's further reading on some of the above subjects:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;The &lt;a href="https://www.owasp.org/index.php/Main_Page"&gt;Open Web Application Security Project (OWASP)&lt;/a&gt; has tons of information about web application security. Its top 10 is no doubt the most famous, but it's just a tiny part of what they do.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The book &lt;a href="http://swsec.com"&gt;&lt;em&gt;Software Security - Building Security In&lt;/em&gt;&lt;/a&gt; by security veteran Gary McGraw is over a decade old but, except for a few parts that focus on code level issues, is still relevant today.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Australian &lt;a href="https://www.troyhunt.com"&gt;Troy Hunt&lt;/a&gt; writes and talks a lot about security, and has many excellent introductory articles or training videos.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;This post was previously published at &lt;a href="https://www.rijksictgilde.nl/actueel/weblogs/blog/2018/2-pragmatische-privacy-voor-programmeurs"&gt;Rijks ICT Gilde&lt;/a&gt; (in Dutch)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Photo by &lt;a href="https://unsplash.com/photos/8yYAaguVDgY"&gt;Jason Blackeye&lt;/a&gt; on &lt;a href="https://unsplash.com"&gt;Unsplash&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>privacy</category>
      <category>security</category>
      <category>agile</category>
    </item>
    <item>
      <title>Pragmatic Privacy for Programmers (Part 1)</title>
      <dc:creator>Jeroen Heijmans</dc:creator>
      <pubDate>Fri, 14 Dec 2018 06:37:42 +0000</pubDate>
      <link>https://dev.to/rijks-ict-gilde/pragmatic-privacy-for-programmers-part-1-2gh4</link>
      <guid>https://dev.to/rijks-ict-gilde/pragmatic-privacy-for-programmers-part-1-2gh4</guid>
      <description>&lt;p&gt;As software developers, we have to make sure that the applications we build have the right functionality, we also have to ensure they meet various non-functional requirements. Our apps better be secure against hackers, be fast enough not to annoy users, quickly scale and not crash when there's a peak in usage. As of 2018, it's unavoidable that privacy is one of these concerns. If it wasn't already, it's the enforcement of the &lt;a href="https://eur-lex.europa.eu/legal-content/EN/TXT/PDF/?uri=CELEX:32016R0679&amp;amp;qid=1541482324985&amp;amp;from=EN" rel="noopener noreferrer"&gt;General Data Protection Regulation&lt;/a&gt; (GDPR) back in May 2018 which made it a concern for most developers.&lt;/p&gt;

&lt;p&gt;One way to deal with GDPR is to throw your hands up in the air and block everybody from the EU. That sounds drastic, but &lt;a href="https://econsultancy.com/gdpr-which-websites-are-blocking-visitors-from-the-eu-2/" rel="noopener noreferrer"&gt;some sites and companies&lt;/a&gt; have actually done that. If you don't have that option, say because you actually live in the EU (like me) or have users or customers there, you'll need to take care of this privacy thing. And even if you don't have to deal with GDPR, it's quite likely you'll have to adhere to &lt;a href="https://privacypolicies.com/blog/privacy-law-by-country/" rel="noopener noreferrer"&gt;other privacy laws or regulations&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Perhaps some of us are lucky to work for a large organization where there's a privacy expert available to tell us what to do. If we're really lucky, there might even be a &lt;a href="https://en.wikipedia.org/wiki/Privacy_engineering" rel="noopener noreferrer"&gt;privacy engineer&lt;/a&gt; who knows enough about software engineering to take care of the work. But in many cases, such experts aren't around or available to our projects. That means we will largely need to address it ourselves. But how can we go about this? We don't have the time to become privacy experts!&lt;/p&gt;

&lt;p&gt;In this article (and following parts) I'll outline a pragmatic approach for dealing privacy as a programmer. Since I'm in the EU, I'll use GDPR as a guideline for this, but it should be applicable regardless of the specific laws you need to adhere to. Before we can get to the practical stuff, it's necessary to have some basic definition of what privacy is about. &lt;/p&gt;

&lt;p&gt;&lt;em&gt;Since this is a legal topic, please take the below as a generic approach, but not as a specific solution for your apps. It may contain incorrect assumptions, does not take into account your specific situation and is intended to be an illustration.&lt;/em&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  A bit of theory
&lt;/h1&gt;

&lt;p&gt;When talking about software, privacy is about &lt;em&gt;protection of personal data&lt;/em&gt;. At first blush that may seem clear, but some closer inspection doesn't hurt:&lt;/p&gt;

&lt;p&gt;First, what is personal data? If we follow GDPR, personal data is &lt;em&gt;information that relates to a person that's identifiable&lt;/em&gt;. That's a pretty broad definition, and also a bit vague. There's no reference list of what constitutes personal data, and neither is it possible to create it, as it depends on context. Let's take hair colour, for example. The information clearly relates to a person. But is that person also identifiable? On a global scale, no. But with additional information, we may be able to indirectly identify the person. For example, if we know the person works at your company, or lives in your street, just knowing the hair colour could be enough to identify. In such cases, hair colour is personal data that falls under GDPR.&lt;/p&gt;

&lt;p&gt;Secondly, the apps we build should protect personal data. We should protect personal data against everybody: people with technical access to the application (that's us), other people in our organization, collaborators and outsiders. Doing this correctly will require us to perform a number of duties. For starters, we need to have a valid reason (lawful purpose) for processing personal data. Next, we can only use it for that reason (purpose limitation), and so on. The people the personal data relates to also have rights that we need to guarantee. Examples of owner rights include knowing when personal data is processed (right of information) and being able to see what personal data is processed (right of access). &lt;/p&gt;

&lt;p&gt;So in summary, privacy is about:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Personal Data:&lt;br&gt;
a. information that relates to a person&lt;br&gt;
b. a person that is identifiable&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Protection:&lt;br&gt;
c. Duties&lt;br&gt;
d. Owner Rights&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h1&gt;
  
  
  Compliance the pragmatic way
&lt;/h1&gt;

&lt;p&gt;Under GDPR, it's up to the processor of personal data - us - to show that they're compliant with the regulations. Compliance sounds very legal, but it's not so far from what we as developers do: we use automated tests to show that our code is "compliant" with our functional requirements, and monitoring to show that our app is "compliant" with our performance demands. Let's try to build something like this for our privacy requirements.&lt;/p&gt;

&lt;p&gt;Using the theory from the previous section, a first version of what we build might look like this:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Information Related To Person&lt;/th&gt;
&lt;th&gt;Person identifiable?&lt;/th&gt;
&lt;th&gt;Duties fulfilled?&lt;/th&gt;
&lt;th&gt;Owner Rights supported?&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Foo&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;N/A&lt;/td&gt;
&lt;td&gt;N/A&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Bar&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;It's basically a list of personal data candidates. If it's actually personal data (the person is identifiable), we'll need to confirm that we've fulfilled our duties and supported the rights of the users. If it's not personal data, it's still useful to keep it on the list to document that we don't consider this personal data. &lt;/p&gt;

&lt;p&gt;We can maintain this document anywhere we want, but it makes sense to have it in a central, easily accessible place. If you're using a tool like GitHub, putting it in the &lt;code&gt;README.md&lt;/code&gt; or wiki makes sense. That also has the advantage of being able to embed links/images from automated checks, in case we are able to do that.&lt;/p&gt;

&lt;p&gt;Let's put this proposed approach to the test and build a simple application. We'll build it in a few increments to show the approach works well when doing agile. Since the app will have all kinds of features to demonstrate the approach, let's call it &lt;a href="https://en.wiktionary.org/wiki/everything_but_the_kitchen_sink#English" rel="noopener noreferrer"&gt;Kitchen Sink&lt;/a&gt;.&lt;/p&gt;

&lt;h1&gt;
  
  
  Increment 1: avoiding personal data.
&lt;/h1&gt;

&lt;p&gt;In the first increment we're going to build a very basic static website with &lt;a href="https://unsplash.com/photos/TuW3Ip1m2Oo" rel="noopener noreferrer"&gt;a picture of a kitchen sink&lt;/a&gt;. We're going to put it on a server we happen to have running. The server already has Apache (or NGINX) installed on it, so let's put some static HTML in there.&lt;/p&gt;

&lt;p&gt;Not much to do here about privacy in a static web page, right? Actually, we're already collecting personal data. People will visit your static website. And Apache is registering every visit in its log files. Are page visits personal data? They absolutely relate to a person (some companies are paying good money to know which sites you are visiting). Is the person also identifiable? The log file &lt;a href="https://en.wikipedia.org/wiki/Common_Log_Format" rel="noopener noreferrer"&gt;usually records the visitor's IP address&lt;/a&gt;. While that doesn't give you a person's name, the IP address often allows you to identify a person across websites, which is enough to make the personal data identifiable. When you combine the IP address with other information that's easily available (to see what's possible, look into &lt;a href="https://www.eff.org/deeplinks/2018/06/gdpr-and-browser-fingerprinting-how-it-changes-game-sneakiest-web-trackers" rel="noopener noreferrer"&gt;browser fingerprinting&lt;/a&gt;), it becomes even clearer this is really personal data. &lt;/p&gt;

&lt;p&gt;So, after putting up this static page, our checklist looks like this:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Information Related To Person&lt;/th&gt;
&lt;th&gt;Person identifiable?&lt;/th&gt;
&lt;th&gt;Duties fulfilled?&lt;/th&gt;
&lt;th&gt;Owner Rights supported?&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Website visit&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;TBD&lt;/td&gt;
&lt;td&gt;TBD&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;But, do we really need this personal data? Well, we'd like to have the data to do statistical analysis such as visitor counts and origin, but we don't really need the person behind it to be identifiable. If we can achieve that, it's no longer personal data and doesn't need to be protected according to the GDPR.&lt;/p&gt;

&lt;p&gt;There are a number of ways to de-personalize data:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Don't store the data at all, or remove the identifiers. This is by far the simplest approach, but of course has the disadvantage that we cannot use them in any way.&lt;/li&gt;
&lt;li&gt;Aggregate the data and/or identifiers. This means summarizing it in such a way that individual records are no longer present. In our case, this could mean directly feeding it into our access file analysis tools.&lt;/li&gt;
&lt;li&gt;Anonymize identifiers. By obscuring identifiers from the data, it is no longer personal data. This would allow us keep the log files for future goals if we desire so.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Let's go with anonymization. Or actually, we're going to take a slightly weaker form: data masking. Instead of fully anonymizing the IP address, we will mask the last octet of the IP(v4) address. So &lt;code&gt;192.168.11.12&lt;/code&gt; will be masked to &lt;code&gt;192.168.11.x&lt;/code&gt;, or if we want to keep it a valid IP address, &lt;code&gt;192.168.11.0&lt;/code&gt;. It might be argued that this is insufficient, but it is &lt;a href="https://support.google.com/analytics/answer/2763052" rel="noopener noreferrer"&gt;what Google Analytics is doing&lt;/a&gt;, so let's consider that sufficient for now. It can be done with &lt;a href="https://stackoverflow.com/questions/19452624/apply-a-mask-to-ip-with-logformat" rel="noopener noreferrer"&gt;a few rules configuration&lt;/a&gt;, or by installing a &lt;a href="https://github.com/webfactory/mod_log_ipmask" rel="noopener noreferrer"&gt;module&lt;/a&gt;. And the same goes for &lt;a href="https://stackoverflow.com/questions/6477239/anonymize-ip-logging-in-nginx" rel="noopener noreferrer"&gt;NGINX&lt;/a&gt;, and other web servers.&lt;/p&gt;

&lt;p&gt;It seems valuable to register this choice of de-personalization in our "compliance" table, so we can see why we don't consider website visits as personal data. Let's add a column:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Information Related To Person&lt;/th&gt;
&lt;th&gt;Person identifiable?&lt;/th&gt;
&lt;th&gt;Depersonalized?&lt;/th&gt;
&lt;th&gt;Duties fulfilled?&lt;/th&gt;
&lt;th&gt;Owner Rights supported?&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Website visit&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;Yes (Masking)&lt;/td&gt;
&lt;td&gt;NA&lt;/td&gt;
&lt;td&gt;NA&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;We aren't fully done yet. We claim to mask identifiers here, but saying that doesn't make it true. If we botch the configuration at some point, we'll never know. So, we should make a test to see if we're still compliant here. How to do this will depend on our setup. An elegant approach might be to use a log analysis tool, such as &lt;a href="https://www.splunk.com" rel="noopener noreferrer"&gt;Splunk&lt;/a&gt;, &lt;a href="https://www.elastic.co/products" rel="noopener noreferrer"&gt;Elastic stack&lt;/a&gt; or &lt;a href="https://papertrailapp.com" rel="noopener noreferrer"&gt;Papertrail&lt;/a&gt;. With these tools, you can create a search of your access logs for the presence of unmasked IP addresses. If that unlikely event occurs, you can register that, or get notified, or &lt;a href="https://help.papertrailapp.com/kb/how-it-works/web-hooks" rel="noopener noreferrer"&gt;send a web hook&lt;/a&gt; to a different application. &lt;/p&gt;

&lt;p&gt;With that check, we get our final privacy overview for this iteration:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Information Related To Person&lt;/th&gt;
&lt;th&gt;Person identifiable?&lt;/th&gt;
&lt;th&gt;Depersonalized?&lt;/th&gt;
&lt;th&gt;Duties fulfilled?&lt;/th&gt;
&lt;th&gt;Owner Rights supported?&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Website visit&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;Yes (Masking) ✅&lt;/td&gt;
&lt;td&gt;NA&lt;/td&gt;
&lt;td&gt;NA&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Please join me soon for the next part, where I will expand the Kitchen Sink app to see if we can also fulfill our duties as processor of personal data. &lt;/p&gt;

&lt;p&gt;If you'd like to read more on related subjects:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The UK Information Commissioner's Office has a &lt;a href="https://ico.org.uk/for-organisations/guide-to-the-general-data-protection-regulation-gdpr/" rel="noopener noreferrer"&gt;thorough explanation of GDPR and how it works&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;The book &lt;a href="http://evolutionaryarchitecture.com" rel="noopener noreferrer"&gt;&lt;em&gt;Building Evolutionary Architectures&lt;/em&gt;&lt;/a&gt; defines the term "architectural fitness function", which has a lot of overlap with the approach above.&lt;/li&gt;
&lt;li&gt;Good anonymization of data is notoriously hard, as &lt;a href="https://tech.vijayp.ca/of-taxis-and-rainbows-f6bc289679a1" rel="noopener noreferrer"&gt;demonstrated here using taxis&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;This post was previously published at &lt;a href="https://www.rijksictgilde.nl/actueel/weblogs/blog/2018/1-pragmatische-privacy-voor-programmeurs" rel="noopener noreferrer"&gt;Rijks ICT Gilde&lt;/a&gt; (in Dutch)&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Photo by &lt;a href="https://unsplash.com/@dtopkin1" rel="noopener noreferrer"&gt;Dayne Topkin&lt;/a&gt; on &lt;a href="https://unsplash.com" rel="noopener noreferrer"&gt;Unsplash&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>privacy</category>
      <category>security</category>
      <category>agile</category>
    </item>
  </channel>
</rss>
