Contribute

We're thrilled that you want to contribute to PrivacySpy. This guide will explain how to contribute policies, corrections, suggestions, and code changes.

Note that all contributions to PrivacySpy will take place in our GitHub repository. If you don't have a GitHub account already, you'll need to sign up for one to participate.

To see all of PrivacySpy's existing contributors, check out our contributors page.

Table of Contents

Sharing suggestions and requests

If you have an idea for PrivacySpy, think you found an error, or just want to bring something up with the team, feel free to create an issue in our GitHub repository. Creating issues in the GitHub repository is the best way to share feedback and comments.

If your issue is a suggestion—such as a request to add a new product to our database or to fix an error—consider making the change yourself and submitting your modifications as a pull request (see changing an existing policy below to learn how). If you're not comfortable implementing the change yourself or don't know how, though, feel free to just create an issue.

Submitting a new product

Submitting a new product to PrivacySpy isn't too hard. The first step is to fork PrivacySpy so that you can submit changes as a pull request—if you're unsure what this means, you can learn about pull requests here.

Once you have a version of PrivacySpy on your own GitHub account, here are the general steps you need to take to add a new product:

  1. Create a new file in the products/ directory called <product slug>.toml. (A slug is a short and unique ID.) For example, if you were adding DuckDuckGo, the name of the file would be duckduckgo.toml. TOML is the file format we use for writing policies; if you're unfamiliar with it, you can learn more about TOML here.

  2. Add an icon for your new product to the icons/ directory. The name of the icon file should correspond to the product slug from Step 1; for example, for DuckDuckGo, you'd want to name the icon file duckduckgo.png or duckduckgo.jpg. Icon images should be square and smaller than 30kb. You may use our script that helps you add icons quickly; to use it, simply run npm run icons and manually check if the icon has been downloaded and is correct.

  3. Add yourself to CONTRIBUTORS.toml if you haven't already. Fill out as much or as little information as you want. For information about how this file works, refer to the contributors file guide below.

  4. Fill in all the necessary info in the <product slug>.toml file. Refer to the product assessment guide below to learn about how this file works.

  5. Make sure all tests pass. You can run tests using the npm test command. To ensure high-quality content, PrivacySpy has an automated system to check whether changes are appropriate. While it won't catch all issues, the automated testing system will let you know if you've made any obvious mistakes.

  6. Once all tests pass, submit a pull request! To add your changes back to PrivacySpy, submit a pull request. (Be sure to follow the instructions in the Pull Request message template.) Once you do, a member of the PrivacySpy team will look over your changes and either merge or request revisions. Don't worry if your changes aren't accepted on the first try—mistakes are inevitable. Just implement the requested changes, then resubmit the pull request!

  7. That's it! Congratulations—you've contributed a policy to PrivacySpy!

Changing an existing product

To change an existing product on PrivacySpy—to submit a correction or an update—you'll need to submit a pull request. Fortunately, this process is quite simple: just edit the product file in the products/ directory! To edit Google's entry, for example, simply edit the file at products/google.toml. Then, run the npm test command and make sure all tests pass. Finally, submit your changes as a pull request. (Be sure to follow the instructions in the Pull Request message template.)

To learn about how the product TOML file works, review the product assessment guide below.

Product assessment guide

Each product on PrivacySpy is stored in the products/ directory as a TOML file. If you're unfamiliar with the TOML file format, you can learn about it here. In short, it's a flexible data serialization format like JSON or YAML that's designed to be written and understood by humans. You can check if your TOML file is valid using this online tool.

If you're ever confused about the file format for products, you can always look at another existing product file for reference (such as this one).

Product metadata

Metadata about the product—the name, description, and hostnames, for example—belongs at the top of the product file. For metadata, we use a simple key = "value" format.


Example metadata TOML

name = "Twitter"
description = "Twitter is a microblogging social network and is popular among American public figures."
slug = "twitter"
hostnames = [ "twitter.com" ]
sources = [ "https://twitter.com/en/privacy" ]
contributors = [ "milesmcc" ]

Product grading (rubric)

The next section of the product file is the rubric. This is where we encode the score of the product across each of the rubric questions.

Each question is included in the file with the following structure:

[rubric.<question ID>]
value = "<answer ID>"
citations = [
  # Direct quotes from the sources that support the value, if applicable. (Strings.)
]
notes = [
  # Any special notes you want to include about the selection. (Strings.)
]

Each question has an ID (<question id>, also known as the question's slug), and each possible value of that question also has an ID. For example, the question that assesses whether the product uses behavioral marketing has the id behavioral-marketing, and the IDs of the answers are yes, yes-opt-out (yes, but you can opt-out), yes-opt-in (yes, but you must opt-in), and no.

Note that all questions must be graded, and each grade must have at least one citation or note (as shown above).

Questions & options


behavioral-marketing — Does the policy allow personally-targeted or behavioral marketing?

yes

Yes (0%)

yes-opt-out

Yes, but you may opt-out (35%)

yes-opt-in

Yes, but you must opt-in (70%)

no

No (100%)

Sample TOML section
[rubric.behavioral-marketing]
value = "yes" / "yes-opt-out" / "yes-opt-in" / "no" 
citations = ["Citations, if applicable"]
notes = ["Any notes, if applicable"]

data-breaches — Does the policy require users to be notified in case of a data breach?

Note that all companies operating in the EU are subject to Art. 33 of the GDPR, which requires companies to notify their data protection authority of a data breach within 72 hours of discovering it.

no

Not necessarily (0%)

eventually

Yes, eventually (70%)

Users will be notified in case of a data breach but within an unspecified amount of time.

yes-72

Yes, within 72 hours (100%)

na

N/A (100%)

The service collects so little personal data that notification would not be possible.

Sample TOML section
[rubric.data-breaches]
value = "no" / "eventually" / "yes-72" / "na" 
citations = ["Citations, if applicable"]
notes = ["Any notes, if applicable"]

data-collection-reasoning — Is it clear why the service collects the personal data that it does?

no

No (0%)

somewhat

Somewhat (30%)

mostly

Mostly (70%)

yes

Yes (100%)

na

N/A (100%)

The service doesn't collect any personal information.

Sample TOML section
[rubric.data-collection-reasoning]
value = "no" / "somewhat" / "mostly" / "yes" / "na" 
citations = ["Citations, if applicable"]
notes = ["Any notes, if applicable"]

data-deletion — Does the service allow you to permanently delete your personal data?

Even if there is a reasonable delay before the data is fully deleted (as is common), the data still counts as "permanently deleted" and satisfies the parameters for this question.

no

No (0%)

yes-contact

Yes, by contacting someone (60%)

yes-automated

Yes, using an automated mechanism (100%)

na

N/A (100%)

The service doesn't collect any personal information.

Sample TOML section
[rubric.data-deletion]
value = "no" / "yes-contact" / "yes-automated" / "na" 
citations = ["Citations, if applicable"]
notes = ["Any notes, if applicable"]

history — Is the policy's history made available?

no

No (0%)

last-modified

Only the date it was last modified (50%)

yes

Yes, with revisions or a changelog (100%)

Sample TOML section
[rubric.history]
value = "no" / "last-modified" / "yes" 
citations = ["Citations, if applicable"]
notes = ["Any notes, if applicable"]

law-enforcement — When does the policy allow law enforcement access to personal data?

always

Always (0%)

This includes cases in which law enforcement either runs the service or has a known backdoor into (or relationship with) the service.

unspecified

Not specified (0%)

reasonable

When reasonably requested (60%)

strict

Only when required by a court order or subpoena (80%)

na

N/A (no personal data to share) (100%)

The service would have no personal data to share with law enforcement.

never

Never (special legal jurisdiction) (100%)

The service operates in a jurisdiction in which sharing data with law enforcement is never required.

Sample TOML section
[rubric.law-enforcement]
value = "always" / "unspecified" / "reasonable" / "strict" / "na" / "never" 
citations = ["Citations, if applicable"]
notes = ["Any notes, if applicable"]

list-collected — Does the policy list the personal data it collects?

no

No (0%)

The policy does not claim to not collect personal data, but it also doesn't provide any meaningful insight into the types of personal data it collects.

summarily

Only summarily (30%)

The policy uses overly vague language to provide a summary of the types of collected personal data.

generally

Yes, generally (70%)

All general categories of collected personal data are listed, though not all types of personal data are explicitly mentioned (for example, the list might use a phrase like 'such as' when listing types of personal data).

exhaustively

Yes, exhaustively (100%)

All types of collected personal data are listed specifically

na

N/A (no personal data is collected) (100%)

Sample TOML section
[rubric.list-collected]
value = "no" / "summarily" / "generally" / "exhaustively" / "na" 
citations = ["Citations, if applicable"]
notes = ["Any notes, if applicable"]

noncritical-purposes — Does the service allow the user to control whether personal data is collected or used for non-critical purposes?

Some services allow users to opt-out or opt-in to of non-critical collection or use of personal data, such as collecting data for personalized advertisements.

no

No (0%)

opt-out-some

On an opt-out basis, but only for some non-critical data/uses (30%)

opt-out-all

On an opt-out basis, for all non-critical data/uses (60%)

opt-in

On an opt-in basis (60%)

na

N/A (no data used for non-critical purposes) (100%)

Sample TOML section
[rubric.noncritical-purposes]
value = "no" / "opt-out-some" / "opt-out-all" / "opt-in" / "na" 
citations = ["Citations, if applicable"]
notes = ["Any notes, if applicable"]

revision-notify — Will affected users be notified when the policy is meaningfully changed?

no

No (0%)

yes

Yes (100%)

na

N/A (100%)

The policy doesn't collect any personal data, so notification would be impossible.

Sample TOML section
[rubric.revision-notify]
value = "no" / "yes" / "na" 
citations = ["Citations, if applicable"]
notes = ["Any notes, if applicable"]

security — Does the policy outline the service's general security practices?

no

No (0%)

somewhat

Somewhat (30%)

The policy provides only a very vague overview of its security practices.

yes

Yes (60%)

yes-audits

Yes, including audits (80%)

"Reviews," "monitoring," etc. also count as audits.

yes-independent-audits

Yes, including independent audits (100%)

Independent "reviews," "monitoring," etc. also count as independent audits.

na

N/A (100%)

The service doesn't collect any personal information.

Sample TOML section
[rubric.security]
value = "no" / "somewhat" / "yes" / "yes-audits" / "yes-independent-audits" / "na" 
citations = ["Citations, if applicable"]
notes = ["Any notes, if applicable"]

third-party-access — Does the service allow third-party access to private personal data?

This may come in the form of outright data sharing or by using local third-party analytics software (such as Google Analytics, which collects a plethora of user information).

Note that whether the policy allows sharing aggregated user data does not affect this question.

If the personal data is encrypted when it passes through the third-party, it does not count as third-party access (as the data is inaccessible to that party).

If personal data has been made public by, for example, posting it to a blog, it does not count as private personal information (and is therefore not considered by this question).

yes-unspecified

Yes (0%)

The policy allows sharing personal data with third parties (not just critical service providers), and does not explicitly list the third parties.

yes-specified-noncritical

Yes, all parties specified (including non-critical service providers such as advertisers) (30%)

yes-unspecified-critical

Yes, not all parties specified (but only to critical service providers) (70%)

yes-specified-critical

Yes, all parties specified (only to critical service providers) (80%)

no

No (100%)

Sample TOML section
[rubric.third-party-access]
value = "yes-unspecified" / "yes-specified-noncritical" / "yes-unspecified-critical" / "yes-specified-critical" / "no" 
citations = ["Citations, if applicable"]
notes = ["Any notes, if applicable"]

third-party-collection — Does the service collect personal data from third parties?

This includes the use of data brokers and independent verification authorities (such as background check providers).

yes

Yes (0%)

critical-only

Yes, but for critical data only (70%)

For example, a blog providing user avatars or a bank conducting identity verification would count.

no

No (100%)

Sample TOML section
[rubric.third-party-collection]
value = "yes" / "critical-only" / "no" 
citations = ["Citations, if applicable"]
notes = ["Any notes, if applicable"]

Updates

Whenever a product has a major privacy-related event (such as a data breach, an overhaul of their privacy policy, or anything else of this nature), we try to include it as an update on PrivacySpy.

Each product has an array of update objects. An update object (inside the updates array) looks like this:

[[updates]]
title = "Data Breach"
description = "More than 540 million records about Facebook users were publicly exposed on Amazon's cloud computing service, according to a cybersecurity research firm."
date = 2019-08-28
sources = [ "https://www.cbsnews.com/news/millions-facebook-user-records-exposed-amazon-cloud-server/" ]

As you can probably gather, title is a string that represents the title of the update; description is a string that explains what happened (in full sentences); date is the date of the update; and sources is an array of URLs that provide information about the update.

Note that to insert the update into the updates array, we put [[update]] on top of the object, as per the TOML spec.

Contributors file guide

Contributors like you deserve to be recognized for your additions to PrivacySpy. That's why we maintain the CONTRIBUTORS.toml file (in the root of the repository) where each contributor is listed with some minimal biographical information.

You aren't required to add any biographical information to the CONTRIBUTORS.toml file if you don't want to.

Here's a template for what to put in the file:

[your_slug] # usually the same as your GitHub username
name = "Your Name" # optional
website = "http://example.com" # optional
github = "example" # optional
email = "example@example.com" # optional

The only required element is [your_slug]. You can think of your_slug as your PrivacySpy "username"—it's what you'd add to the contributors array in policies you contribute to.