To be compliant with privacy regulations you may need to ensure that a user's data is deleted when they delete their account.
This library contains a Cloud Function triggered by account deletion. It wipes out all the data in the Firebase Realtime Database that belongs to the user that was deleted.
To determine what data belonged to the user, the Cloud Function analyzes the app's Security Rules, considering any data that can only be written by a particular user to belong to that user.
Also included here is a simple demo app showing how the library works.
The instructions below explain how to use this library. If you want to contribute to the library, or are just curious about how it is built, please see the overview Design Doc and the detailed explanation of Auto Rules Extraction.
See file functions/wipeout.js for the data cleanup code.
When a user deletes their account, their data in the database will be deleted automatically. The function needs configuration to find according user data. The configuration can be specified in local file functions/wipeout_config.json. If the file doesn't exists or doesn't contain a valid configuration object, the function will go ahead and infer the configuration from Firebase database authorization rules (verification of the inferred rules will be in the next release).
The configuration is a json object and its wipeout
filed is a list of objects.
Each object in the list has a string field called path
specifying a path where
user data is stored. The path string could use variable $WIPEOUT_UID
which
will be replaced by UID of the deleted user account when triggered.
Please don't change the WIPEOUT_CONFIG
object in functions/index.js
unless
you want to customize the function and know the code well.
The dependencies are listed in functions/package.json.
When a user signs-in we write some sample personal data of the following form:
/functions-project-12345
/users
$uid : "Some user data"
When the user delete their account a Function will trigger and automatically delete the corresponding user data in the realtime database.
The function triggers on user account deletions. While a developer confirmation is needed before the trigger stats to work, see step 9 in Deploy and test for details.
This sample comes with a Function and web-based UI for testing the function. To configure it:
- Create a Firebase Project using the Firebase Console.
- Enable Google Auth. In the Firebase Console open the Authentication section > SIGN IN METHOD tab you need to enable the Google Sign-in Provider and click SAVE.
- Clone or download this repo and open the
user-data-cleanup
directory. - You must have the Firebase CLI installed. If you don't have it install it
with
npm install -g firebase-tools
and then configure it withfirebase login
. - Configure the CLI locally by using
firebase use --add
and select your project in the list. - Install dependencies locally by running:
cd functions; npm install; cd -
- Run local tests using
cd functions; npm test
- Deploy your project using
firebase deploy
, and note the showWipeoutConfig URL printed out. - Visit the showWipeoutConfig URL in a browser and Initialized the library for this database by clicking the "INITIALIZE" button.
- Go to the showWipeoutConfig URL again to verify the wipeout rules. The webpage will show the source of these wipeout rules, either loaded from local config or generated from security rules.
- The format of wipeout rules are described in the next section. If the rules are correct, click the "CONFIRM DEPLOYMENT" button, or else change the local configuration file functions/wipeout_config.json and redeploy. Note a developer confirmation is required after every deployment.
- Open the app using
firebase open hosting:site
, this will open a browser. - Sign in using Google Sign-In and delete the account using the provided button. You can check at each step of the way if the data has been deleted using the Firebase console.
The wipepout rules is a list of JSON object, each of them describes a pattern of user data storage. When a user account is deleted, the library go through every config to remove any match with these patterns. A sinlge config rule can have four fields:
path
: Mandatory field. A String indicating a location of user data. A path can include place holder variables#WIPEOUT_UID
which will be replaced byauth.uid
at execution time. It can also include free variables which starts with$
. A simple examplepath
is/users/#WIPEOUT_UID
, and an examplepath
field for a chat app is/chat/$room
.authVar
: Optional field, List of data references. Besides the locations marked by#WIPEOUT_UID
inpath
, authVar is a list of values/data references which should equals to the authentication uid. For example, the previous chat app example could haveauthVar: ['val(rules,chat,$room,creator)']
(see data reference below for format details). This will restrict the free variable$room
to the set of chat rooms created by the user who just deleted the account because it requires data at/chat/$room/creator
to beauth.uid
.condition
: Optional field, string. Any additional restriction on the path which is not related to authentication. Logic&&
and||
supported, free variable not supported. An example condition:#WIPTOUT_UID !== someID && val(rules,user,#WIPEOUT_UID,creatYear) > 2016
.except
: Optional field. Subpath which doesn't belong to a single user, shouldn't be removed at account deletion. For example, shared data under a user data folder. Currently only subpaths which are one level deeper than its parent path is supported. An exampleexcept
for/chat/$room/
is/chat/$room/members
.
Data reference: A string representing the value or existence of data at a
location in the database. The string format is a call of val()
or exists()
,
and the list of arguments stands for the path to the location. The root of the
path is always 'rules'. e.g. val(rules,chat,$room,creator)
stands for the
value at location /chat/$room/creator
.
At execution time, a config will go through the following process to get a set of materialized absolute paths in the database:
- Swap
#WIPEOUT_UID
place holder withauth.uid
of deleted account. - Evaluate condition, filter out any config with a false condition.
- Evaluate authVar, retrieve values for variables in path.
- Evaluate exception,
- Remove any remaining trailing free variables since they represent wildcard values in paths. After the removal, any path which still have free variable is not supported for deletion and will be ignored.
After these steps, we'll have a list of concrete deletion path. The library goes
ahead and deletes the data and record the the paths together with a timestamp at
/wipeout/history/#WIPEOUT_UID
in the realtime database.