SlideShare a Scribd company logo
1 of 94
Download to read offline
How to go serverless and
not violate the GDPR
Sebastian Schmidt and Rachel Myers
Berlin | November 20 - 21, 2018
GDPR
11 Chapters that regulate:
● Rights of data subjects
● Responsibilities for data controllers/processors
● Data transfers
● Penalties
GDPR
11 Chapters that regulate:
● Rights of data subjects
● Responsibilities for data controllers/processors
● Data transfers
● Penalties
Your users!
You!
Not giving
legal advice
Global Privacy Regulations
Global Privacy Regulations
Global Privacy Regulations
Develop
Grow
Realtime
Database
Authentication
Cloud Storage
Cloud
Firestore
Hosting
Cloud
Functions
Crashlytics
Performance
Test Lab
Analytics
Dynamic Links
Invites
App Indexing
Cloud
Messaging
Remote
Config
AdMob
AdWords
Predictions
Serverless
Concerns
Privacy
Concerns
Serverless
Concerns
Privacy
Concerns
User privacy
built on Serverless
Reduce the user data that you store
Manage user data with Cloud Functions:
Delete data you no longer need
Export data on request
Security Rules!
Inform users about data collection:
Storage Retention Policies
Firebase Instance IDs
Storing Privacy Settings
Keeping an Activity Log
Reduce the user data that you store
Manage user data with Cloud Functions:
Delete data you no longer need
Export data on request
Security Rules!
Inform users about data collection:
Storage Retention Policies
Firebase Instance IDs
Storing Privacy Settings
Keeping an Activity Log
Read your Horoscope!
(You have to be an EU citizen and 18+)
Username
Birthday
Country
sebastian
April 28th, 1990
Czech Republic
Read your Horoscope!
(You have to be an EU citizen and 18+)
Username
Birthday
Country
sebastian
April 28th, 1990
Czech Republic
← Open source
1. Account
information
1. Account
information
2. Photos
1. Account
information
2. Photos
3. Social data
Save only what you need.
Only as long as you
need.
SELECT COUNT(*)
FROM users
WHERE age BETWEEN (18, 25)
Keep the count. Don’t keep the data!
Reduce the user data that you store
Manage user data with Cloud Functions:
Delete data you no longer need
Export data on request
Security Rules!
Inform users about data collection:
Storage Retention Policies
Firebase Instance IDs
Storing Privacy Settings
Keeping an Activity Log
Delete user data
● When your app no longer needs the data
● When a user deletes their account
Not in
your
control
Not in
your
control
Cloud Functions for Firebase
programmatically connect
Firebase and Cloud
How does it work?
Event
emitted
Your code
executed
Function
triggered
How does it work?
Event
emitted
Your code
executed
Function
triggered
firestore.document(‘posts/a’).delete(
)
deleteData() function
We only
display the
top five!
No need to
save the
rest!
Delete the
rest!
Manage User Data
Privacy with Cloud
Functions
link.firebase.events/h1
App Engine lets you
invoke Cloud Functions
periodically!
link.firebase.events/h2
Remove user data
● When your app no longer needs the data
● When a user deletes their account
link.firebase.events/h
3
// functions/index.js
// Paths to user data to export or delete
exports.clearData = functions.auth.user().onDelete((event) => {
const uid = event.data.uid;
const dbPromise = clearDatabaseData(uid);
const storagePromise = clearStorageData(uid);
const firestorePromise = clearFirestoreData(uid);
const promises = [dbPromise, storagePromise, firestorePromise];
return Promise.all(promises).then(() =>
console.log(`Successfully removed data for user ${uid}.`)
);
});
link.firebase.events/h4
// functions/index.js
// Paths to user data to export or delete
exports.clearData = functions.auth.user().onDelete((event) => {
const uid = event.data.uid;
const dbPromise = clearDatabaseData(uid);
const storagePromise = clearStorageData(uid);
const firestorePromise = clearFirestoreData(uid);
const promises = [dbPromise, storagePromise, firestorePromise];
return Promise.all(promises).then(() =>
console.log(`Successfully removed data for user ${uid}.`)
);
});
link.firebase.events/h4
// functions/user_privacy.json
// Paths to user data to export or delete
{
"storage": {
"clearData": [
["myproject.appspot.com", "UID/sample_data.json"],
["myproject.appspot.com", "UID/avatar"]
],
},
"firestore": {
"clearData": [
{"collection": "users", "doc": "UID", "field": "last_name"},
{"collection": "admins", "doc": "UID"}
]
}
}
link.firebase.events/h4
// functions/index.js
// Paths to user data to export or delete
exports.clearData = functions.auth.user().onDelete((event) => {
const uid = event.data.uid;
const dbPromise = clearDatabaseData(uid);
const storagePromise = clearStorageData(uid);
const firestorePromise = clearFirestoreData(uid);
const promises = [dbPromise, storagePromise, firestorePromise];
return Promise.all(promises).then(() =>
console.log(`Successfully removed data for user ${uid}.`)
);
});
link.firebase.events/h4
// functions/user_privacy.json
// Paths to user data to export or delete
exports.clearData = functions.auth.user().onDelete((event) => {
const uid = event.data.uid;
const dbPromise = clearDatabaseData(uid);
const storagePromise = clearStorageData(uid);
const firestorePromise = clearFirestoreData(uid);
const promises = [dbPromise, storagePromise, firestorePromise];
return Promise.all(promises).then(() =>
console.log(`Successfully removed data for user ${uid}.`)
);
});
link.firebase.events/h4
// functions/index.js
// Deletes user data from the RealTime Database
const clearDatabaseData = (uid) => {
const paths = userPrivacyPaths.database.clearData;
const promises = [];
for (let i = 0; i < paths.length; i++) {
const path = replaceUID(paths[i], uid);
promises.push(db.ref(path).remove().catch((error) => {
// Avoid execution interuption.
console.error('Error deleting data at ', path, error);
}));
}
return Promise.all(promises).then(() => uid);
};
link.firebase.events/h4
// functions/index.js
// Deletes user data from the RealTime Database
const clearDatabaseData = (uid) => {
const paths = userPrivacyPaths.database.clearData;
const promises = [];
for (let i = 0; i < paths.length; i++) {
const path = replaceUID(paths[i], uid);
promises.push(db.ref(path).remove().catch((error) => {
// Avoid execution interuption.
console.error('Error deleting data at ', path, error);
}));
}
return Promise.all(promises).then(() => uid);
};
link.firebase.events/h4
// functions/index.js
// Deletes user data from the RealTime Database
const clearDatabaseData = (uid) => {
const paths = userPrivacyPaths.database.clearData;
const promises = [];
for (let i = 0; i < paths.length; i++) {
const path = replaceUID(paths[i], uid);
promises.push(db.ref(path).remove().catch((error) => {
// Avoid execution interuption.
console.error('Error deleting data at ', path, error);
}));
}
return Promise.all(promises).then(() => uid);
};
link.firebase.events/h4
Reduce the user data that you store
Manage user data with Cloud Functions:
Delete data you no longer need
Export data on request
Security Rules!
Inform users about data collection:
Storage Retention Policies
Firebase Instance IDs
Storing Privacy Settings
Keeping an Activity Log
// functions/index.js
// Exports user data
exports.exportData = functions.https.onRequest((req, res) => {
const uid = JSON.parse(req.body).uid;
const exportData = {};
const dbProm = exportDatabaseData(uid).then((dbData) => {
exportData.database = dbData;
});
const fsProm = exportFirestoreData(uid).then((fsData) => {
exportData.firestore = fsData;
});
const storageProm = exportStorageData(uid).then((storageRefs) => {
exportData.storage = storageRefs;
});
return Promise.all([dbProm, fsProm, storageProm]).then(() => {
console.log(`Success! Completed export for user ${uid}.`);
return uploadToStorage(uid, exportData);
}).then(() => res.json({exportComplete: true}));
});
link.firebase.events/h4
// functions/index.js
// Exports user data
exports.exportData = functions.https.onRequest((req, res) => {
const uid = JSON.parse(req.body).uid;
const exportData = {};
const dbProm = exportDatabaseData(uid).then((dbData) => {
exportData.database = dbData;
});
const fsProm = exportFirestoreData(uid).then((fsData) => {
exportData.firestore = fsData;
});
const storageProm = exportStorageData(uid).then((storageRefs) => {
exportData.storage = storageRefs;
});
return Promise.all([dbProm, fsProm, storageProm]).then(() => {
console.log(`Success! Completed export for user ${uid}.`);
return uploadToStorage(uid, exportData);
}).then(() => res.json({exportComplete: true}));
});
link.firebase.events/h4
// functions/index.js
// Exports user data
exports.exportData = functions.https.onRequest((req, res) => {
const uid = JSON.parse(req.body).uid;
const exportData = {};
const dbProm = exportDatabaseData(uid).then((dbData) => {
exportData.database = dbData;
});
const fsProm = exportFirestoreData(uid).then((fsData) => {
exportData.firestore = fsData;
});
const storageProm = exportStorageData(uid).then((storageRefs) => {
exportData.storage = storageRefs;
});
return Promise.all([dbProm, fsProm, storageProm]).then(() => {
console.log(`Success! Completed export for user ${uid}.`);
return uploadToStorage(uid, exportData);
}).then(() => res.json({exportComplete: true}));
});
link.firebase.events/h4
// functions/index.js
// Helper function that exports user data from RealTime Database.
const exportDatabaseData = (uid) => {
const paths = userPrivacyPaths.database.exportData;
const promises = [];
const exportData = {};
for (let i = 0; i < paths.length; i++) {
const path = replaceUID(paths[i], uid);
promises.push(db.ref(path).once('value').then((snapshot) => {
const read = snapshot.val();
if (read !== null) {
exportData[snapshot.key] = read;
}
}).catch((err) => {
console.error('Error exporting data: ', err);
}));
};
return Promise.all(promises).then(() => exportData);
};
link.firebase.events/h4
// functions/index.js
// Helper function that exports user data from RealTime Database.
const exportDatabaseData = (uid) => {
const paths = userPrivacyPaths.database.exportData;
const promises = [];
const exportData = {};
for (let i = 0; i < paths.length; i++) {
const path = replaceUID(paths[i], uid);
promises.push(db.ref(path).once('value').then((snapshot) => {
const read = snapshot.val();
if (read !== null) {
exportData[snapshot.key] = read;
}
}).catch((err) => {
console.error('Error exporting data: ', err);
}));
};
return Promise.all(promises).then(() => exportData);
};
firebase.events/q4
// functions/index.js
// Exports user data
exports.exportData = functions.https.onRequest((req, res) => {
const uid = JSON.parse(req.body).uid;
const exportData = {};
const dbProm = exportDatabaseData(uid).then((dbData) => {
exportData.database = dbData;
});
const fsProm = exportFirestoreData(uid).then((fsData) => {
exportData.firestore = fsData;
});
const storageProm = exportStorageData(uid).then((storageRefs) => {
exportData.storage = storageRefs;
});
return Promise.all([dbProm, fsProm, storageProm]).then(() => {
console.log(`Success! Completed export for user ${uid}.`);
return uploadToStorage(uid, exportData);
}).then(() => res.json({exportComplete: true}));
});
link.firebase.events/h4
service firebase.storage {
match /b/{bucket}/o {
match /exportData {
// Only allow access to exported data by the user
// who requested an export
match /{uid} {
allow read, write: if request.auth.uid == uid
}
match /{uid}/{path=**} {
allow read, write: if request.auth.uid == uid
}
}
}
}
firebase.events/q4
Remember that rules are ORed together.
✔
Simulated data access allowed
Delete and export are easier when
data’s nested under a user’s UID
$ firebase deploy ...
Done.
Manage User Data
Privacy with Cloud
Functions
link.firebase.events/h4
Reduce the user data that you store
Manage user data with Cloud Functions:
Delete data you no longer need
Export data on request
Security Rules!
Inform users about data collection:
Storage Retention Policies
Firebase Instance IDs
Storing Privacy Settings
Keeping an Activity Log
Client Application Storage
Client Application Storage
Client Storage
Client Storage
Security Rules
Security Rules Simulator
Security Rules
Emulators
link.firebase.events/h5
Security Rules Schema
Messages
PUBLIC
USER 2USER 1
Friends
Private
Messages
Friends
Private
ACTIVITY
USER 2USER 1
Log Log
Entry EntryEntry Entry
Messages
Rules Takeaways
● Never trust data from client apps
● Write rules with the Security Simulator
● Test rules with the Security Rules Emulator
Reduce the user data that you store
Manage user data with Cloud Functions:
Delete data you no longer need
Export data on request
Security Rules!
Inform users about data collection:
Storage Retention Policies
Firebase Instance IDs
Storing Privacy Settings
Keeping an Activity Log
Take a look at our data
retention policies
link.firebase.events/h6
Take a look at our data
retention policies
link.firebase.events/h7
Reduce the user data that you store
Manage user data with Cloud Functions:
Delete data you no longer need
Export data on request
Security Rules!
Inform users about data collection:
Storage Retention Policies
Firebase Instance IDs
Storing Privacy Settings
Keeping an Activity Log
Instance IDs
Unique for each app installation
123 234 345
Instance IDs
Same ID across restarts
123123 123
MON TUE
3rd 4th 5th
WED
Delete Instance ID data
with the Admin SDKs
link.firebase.events/h8
Backend stores data
for 2 weeks
Client keeps
data for 1 week
Backend keeps
backup for 2 weeks
Client keeps
data for 1 week
We will keep your data for 2 weeks.
AGREEDISAGREE
Unchecked
boxes
Comments
enabled
Comments
disabled
Reduce the user data that you store
Manage user data with Cloud Functions:
Delete data you no longer need
Export data on request
Security Rules!
Inform users about data collection:
Storage Retention Policies
Firebase Instance IDs
Storing Privacy Settings
Keeping an Activity Log
Separate Public
from
Private Dataservice cloud.firestore {
match /databases/{database}/documents {
match /users/{uid}/public {
allow read, write;
}
match /users/{uid}/private {
allow read, write:
if request.auth.uid == uid;
}
}
}
service cloud.firestore {
match /databases/{database}/documents {
match /public/{uid} {
allow read, write;
}
match /private/{uid} {
allow read, write:
if request.auth.uid == uid;
}
}
}
Separate Public
from
Private Data
Reduce the user data that you store
Manage user data with Cloud Functions:
Delete data you no longer need
Export data on request
Security Rules!
Inform users about data collection:
Storage Retention Policies
Firebase Instance IDs
Storing Privacy Settings
Keeping an Activity Log
const firestore = admin.firestore();
exports.activityLog = functions.firestore
.document('privacy/{uid}').onWrite(snap => {
const uid = context.params.uid;
const settings = snap.data();
settings['udpate_time'] =
admin.firestore.FieldValue.serverTimestamp();
firestore.collection(
`activity_log/${uid}/entries`
).add(settings);
});
link.firebase.events/h8
const firestore = admin.firestore();
exports.activityLog = functions.firestore
.document('privacy/{uid}').onWrite(snap => {
const uid = context.params.uid;
const settings = snap.data();
settings['udpate_time'] =
admin.firestore.FieldValue.serverTimestamp();
firestore.collection(
`activity_log/${uid}/entries`
).add(settings);
});
link.firebase.events/h8
match /activity_log/{uid} {
allow create: if request.auth.uid == uid;
allow update: if request.auth.uid == uid && resource == null;
allow delete: if false;
}
link.firebase.events/h9
Storing Privacy
Settings
with Firebaselink.firebase.events/h9
Let’s treat our users well!
● Respect user data
● Offer clear data policies
● Limit data intake
● Let users decide how to handle data
Thank you!
Rachel Myers, Firebase
GitHub & Twitter: @rachelmyers
Sebastian Schmidt, Firebase
GitHub: @schmidt-sebastian

More Related Content

What's hot

Event-Driven Systems With MongoDB
Event-Driven Systems With MongoDBEvent-Driven Systems With MongoDB
Event-Driven Systems With MongoDBAndrii Litvinov
 
Michael Hackstein - NoSQL meets Microservices - NoSQL matters Dublin 2015
Michael Hackstein - NoSQL meets Microservices - NoSQL matters Dublin 2015Michael Hackstein - NoSQL meets Microservices - NoSQL matters Dublin 2015
Michael Hackstein - NoSQL meets Microservices - NoSQL matters Dublin 2015NoSQLmatters
 
Users' Data Security in iOS Applications
Users' Data Security in iOS ApplicationsUsers' Data Security in iOS Applications
Users' Data Security in iOS ApplicationsStanfy
 
google drive and the google drive sdk
google drive and the google drive sdkgoogle drive and the google drive sdk
google drive and the google drive sdkfirenze-gtug
 
APIs, APIs Everywhere!
APIs, APIs Everywhere!APIs, APIs Everywhere!
APIs, APIs Everywhere!BIWUG
 
Utilizing Microsoft Graph API and Office 365 Management Activity API during s...
Utilizing Microsoft Graph API and Office 365 Management Activity API during s...Utilizing Microsoft Graph API and Office 365 Management Activity API during s...
Utilizing Microsoft Graph API and Office 365 Management Activity API during s...Kirill Bogdanov
 
CQRS & event sourcing in the wild
CQRS & event sourcing in the wildCQRS & event sourcing in the wild
CQRS & event sourcing in the wildMichiel Rook
 
PistonHead's use of MongoDB for Analytics
PistonHead's use of MongoDB for AnalyticsPistonHead's use of MongoDB for Analytics
PistonHead's use of MongoDB for AnalyticsAndrew Morgan
 
Engage 2013 - Why Upgrade to v10 Tag
Engage 2013 - Why Upgrade to v10 TagEngage 2013 - Why Upgrade to v10 Tag
Engage 2013 - Why Upgrade to v10 TagWebtrends
 
SharePoint Conference 2018 - APIs, APIs everywhere!
SharePoint Conference 2018 - APIs, APIs everywhere!SharePoint Conference 2018 - APIs, APIs everywhere!
SharePoint Conference 2018 - APIs, APIs everywhere!Sébastien Levert
 
MongoDB .local Munich 2019: New Encryption Capabilities in MongoDB 4.2: A Dee...
MongoDB .local Munich 2019: New Encryption Capabilities in MongoDB 4.2: A Dee...MongoDB .local Munich 2019: New Encryption Capabilities in MongoDB 4.2: A Dee...
MongoDB .local Munich 2019: New Encryption Capabilities in MongoDB 4.2: A Dee...MongoDB
 
SwiftUI and Combine All the Things
SwiftUI and Combine All the ThingsSwiftUI and Combine All the Things
SwiftUI and Combine All the ThingsScott Gardner
 
Mongo db updatedocumentusecases
Mongo db updatedocumentusecasesMongo db updatedocumentusecases
Mongo db updatedocumentusecaseszarigatongy
 
HTML5 Gaming Payment Platforms
HTML5 Gaming Payment PlatformsHTML5 Gaming Payment Platforms
HTML5 Gaming Payment PlatformsJonathan LeBlanc
 
Getting Started with Combine And SwiftUI
Getting Started with Combine And SwiftUIGetting Started with Combine And SwiftUI
Getting Started with Combine And SwiftUIScott Gardner
 
Ajax for dummies, and not only.
Ajax for dummies, and not only.Ajax for dummies, and not only.
Ajax for dummies, and not only.Nerd Tzanetopoulos
 

What's hot (20)

Event-Driven Systems With MongoDB
Event-Driven Systems With MongoDBEvent-Driven Systems With MongoDB
Event-Driven Systems With MongoDB
 
Michael Hackstein - NoSQL meets Microservices - NoSQL matters Dublin 2015
Michael Hackstein - NoSQL meets Microservices - NoSQL matters Dublin 2015Michael Hackstein - NoSQL meets Microservices - NoSQL matters Dublin 2015
Michael Hackstein - NoSQL meets Microservices - NoSQL matters Dublin 2015
 
Users' Data Security in iOS Applications
Users' Data Security in iOS ApplicationsUsers' Data Security in iOS Applications
Users' Data Security in iOS Applications
 
google drive and the google drive sdk
google drive and the google drive sdkgoogle drive and the google drive sdk
google drive and the google drive sdk
 
APIs, APIs Everywhere!
APIs, APIs Everywhere!APIs, APIs Everywhere!
APIs, APIs Everywhere!
 
Utilizing Microsoft Graph API and Office 365 Management Activity API during s...
Utilizing Microsoft Graph API and Office 365 Management Activity API during s...Utilizing Microsoft Graph API and Office 365 Management Activity API during s...
Utilizing Microsoft Graph API and Office 365 Management Activity API during s...
 
Git as NoSQL
Git as NoSQLGit as NoSQL
Git as NoSQL
 
CQRS & event sourcing in the wild
CQRS & event sourcing in the wildCQRS & event sourcing in the wild
CQRS & event sourcing in the wild
 
PistonHead's use of MongoDB for Analytics
PistonHead's use of MongoDB for AnalyticsPistonHead's use of MongoDB for Analytics
PistonHead's use of MongoDB for Analytics
 
Engage 2013 - Why Upgrade to v10 Tag
Engage 2013 - Why Upgrade to v10 TagEngage 2013 - Why Upgrade to v10 Tag
Engage 2013 - Why Upgrade to v10 Tag
 
SharePoint Conference 2018 - APIs, APIs everywhere!
SharePoint Conference 2018 - APIs, APIs everywhere!SharePoint Conference 2018 - APIs, APIs everywhere!
SharePoint Conference 2018 - APIs, APIs everywhere!
 
MongoDB .local Munich 2019: New Encryption Capabilities in MongoDB 4.2: A Dee...
MongoDB .local Munich 2019: New Encryption Capabilities in MongoDB 4.2: A Dee...MongoDB .local Munich 2019: New Encryption Capabilities in MongoDB 4.2: A Dee...
MongoDB .local Munich 2019: New Encryption Capabilities in MongoDB 4.2: A Dee...
 
Form1.vb
Form1.vbForm1.vb
Form1.vb
 
SwiftUI and Combine All the Things
SwiftUI and Combine All the ThingsSwiftUI and Combine All the Things
SwiftUI and Combine All the Things
 
Mongo db for C# Developers
Mongo db for C# DevelopersMongo db for C# Developers
Mongo db for C# Developers
 
Docker & Azure
Docker & AzureDocker & Azure
Docker & Azure
 
Mongo db updatedocumentusecases
Mongo db updatedocumentusecasesMongo db updatedocumentusecases
Mongo db updatedocumentusecases
 
HTML5 Gaming Payment Platforms
HTML5 Gaming Payment PlatformsHTML5 Gaming Payment Platforms
HTML5 Gaming Payment Platforms
 
Getting Started with Combine And SwiftUI
Getting Started with Combine And SwiftUIGetting Started with Combine And SwiftUI
Getting Started with Combine And SwiftUI
 
Ajax for dummies, and not only.
Ajax for dummies, and not only.Ajax for dummies, and not only.
Ajax for dummies, and not only.
 

Similar to Sebastian Schmidt, Rachel Myers - How To Go Serverless And Not Violate The GDPR - Codemotion Berlin 2018

IndexedDB and Push Notifications in Progressive Web Apps
IndexedDB and Push Notifications in Progressive Web AppsIndexedDB and Push Notifications in Progressive Web Apps
IndexedDB and Push Notifications in Progressive Web AppsAdégòkè Obasá
 
SharePoint Saturday Belgium 2018 - APIs, APIs everywhere!
SharePoint Saturday Belgium 2018 - APIs, APIs everywhere!SharePoint Saturday Belgium 2018 - APIs, APIs everywhere!
SharePoint Saturday Belgium 2018 - APIs, APIs everywhere!Sébastien Levert
 
Android architecture components with cloud firestore
Android architecture components with cloud firestoreAndroid architecture components with cloud firestore
Android architecture components with cloud firestorePankaj Rai
 
Android app development basics
Android app development basicsAndroid app development basics
Android app development basicsAnton Narusberg
 
The Best Way to Become an Android Developer Expert with Android Jetpack
The Best Way to Become an Android Developer Expert  with Android JetpackThe Best Way to Become an Android Developer Expert  with Android Jetpack
The Best Way to Become an Android Developer Expert with Android JetpackAhmad Arif Faizin
 
BlackBerry DevCon 2011 - PhoneGap and WebWorks
BlackBerry DevCon 2011 - PhoneGap and WebWorksBlackBerry DevCon 2011 - PhoneGap and WebWorks
BlackBerry DevCon 2011 - PhoneGap and WebWorksmwbrooks
 
MongoDB.local Atlanta: Introduction to Serverless MongoDB
MongoDB.local Atlanta: Introduction to Serverless MongoDBMongoDB.local Atlanta: Introduction to Serverless MongoDB
MongoDB.local Atlanta: Introduction to Serverless MongoDBMongoDB
 
Big Data for each one of us
Big Data for each one of usBig Data for each one of us
Big Data for each one of usOSCON Byrum
 
Build Location Based App on bada
Build Location Based App on badaBuild Location Based App on bada
Build Location Based App on badaCheng Luo
 
BP204 - Take a REST and put your data to work with APIs!
BP204 - Take a REST and put your data to work with APIs!BP204 - Take a REST and put your data to work with APIs!
BP204 - Take a REST and put your data to work with APIs!Craig Schumann
 
Introducing Rendr: Run your Backbone.js apps on the client and server
Introducing Rendr: Run your Backbone.js apps on the client and serverIntroducing Rendr: Run your Backbone.js apps on the client and server
Introducing Rendr: Run your Backbone.js apps on the client and serverSpike Brehm
 
Introduction to Firebase on Android
Introduction to Firebase on AndroidIntroduction to Firebase on Android
Introduction to Firebase on Androidamsanjeev
 
#NewMeetup Performance
#NewMeetup Performance#NewMeetup Performance
#NewMeetup PerformanceJustin Cataldo
 
JavaScript para Graficos y Visualizacion de Datos
JavaScript para Graficos y Visualizacion de DatosJavaScript para Graficos y Visualizacion de Datos
JavaScript para Graficos y Visualizacion de Datosphilogb
 
JavaScript para Graficos y Visualizacion de Datos - BogotaJS
JavaScript para Graficos y Visualizacion de Datos - BogotaJSJavaScript para Graficos y Visualizacion de Datos - BogotaJS
JavaScript para Graficos y Visualizacion de Datos - BogotaJSphilogb
 
Data Binding: Is It the Next Big Thing?
Data Binding: Is It the Next Big Thing?Data Binding: Is It the Next Big Thing?
Data Binding: Is It the Next Big Thing?GlobalLogic Ukraine
 
Evolving your Data Access with MongoDB Stitch
Evolving your Data Access with MongoDB StitchEvolving your Data Access with MongoDB Stitch
Evolving your Data Access with MongoDB StitchMongoDB
 

Similar to Sebastian Schmidt, Rachel Myers - How To Go Serverless And Not Violate The GDPR - Codemotion Berlin 2018 (20)

Android Froyo
Android FroyoAndroid Froyo
Android Froyo
 
IndexedDB and Push Notifications in Progressive Web Apps
IndexedDB and Push Notifications in Progressive Web AppsIndexedDB and Push Notifications in Progressive Web Apps
IndexedDB and Push Notifications in Progressive Web Apps
 
SharePoint Saturday Belgium 2018 - APIs, APIs everywhere!
SharePoint Saturday Belgium 2018 - APIs, APIs everywhere!SharePoint Saturday Belgium 2018 - APIs, APIs everywhere!
SharePoint Saturday Belgium 2018 - APIs, APIs everywhere!
 
Android architecture components with cloud firestore
Android architecture components with cloud firestoreAndroid architecture components with cloud firestore
Android architecture components with cloud firestore
 
Android app development basics
Android app development basicsAndroid app development basics
Android app development basics
 
The Best Way to Become an Android Developer Expert with Android Jetpack
The Best Way to Become an Android Developer Expert  with Android JetpackThe Best Way to Become an Android Developer Expert  with Android Jetpack
The Best Way to Become an Android Developer Expert with Android Jetpack
 
BlackBerry DevCon 2011 - PhoneGap and WebWorks
BlackBerry DevCon 2011 - PhoneGap and WebWorksBlackBerry DevCon 2011 - PhoneGap and WebWorks
BlackBerry DevCon 2011 - PhoneGap and WebWorks
 
MongoDB.local Atlanta: Introduction to Serverless MongoDB
MongoDB.local Atlanta: Introduction to Serverless MongoDBMongoDB.local Atlanta: Introduction to Serverless MongoDB
MongoDB.local Atlanta: Introduction to Serverless MongoDB
 
Big Data for each one of us
Big Data for each one of usBig Data for each one of us
Big Data for each one of us
 
Build Location Based App on bada
Build Location Based App on badaBuild Location Based App on bada
Build Location Based App on bada
 
Reduxing like a pro
Reduxing like a proReduxing like a pro
Reduxing like a pro
 
BP204 - Take a REST and put your data to work with APIs!
BP204 - Take a REST and put your data to work with APIs!BP204 - Take a REST and put your data to work with APIs!
BP204 - Take a REST and put your data to work with APIs!
 
Introducing Rendr: Run your Backbone.js apps on the client and server
Introducing Rendr: Run your Backbone.js apps on the client and serverIntroducing Rendr: Run your Backbone.js apps on the client and server
Introducing Rendr: Run your Backbone.js apps on the client and server
 
Introduction to Firebase on Android
Introduction to Firebase on AndroidIntroduction to Firebase on Android
Introduction to Firebase on Android
 
#NewMeetup Performance
#NewMeetup Performance#NewMeetup Performance
#NewMeetup Performance
 
JavaScript para Graficos y Visualizacion de Datos
JavaScript para Graficos y Visualizacion de DatosJavaScript para Graficos y Visualizacion de Datos
JavaScript para Graficos y Visualizacion de Datos
 
JavaScript para Graficos y Visualizacion de Datos - BogotaJS
JavaScript para Graficos y Visualizacion de Datos - BogotaJSJavaScript para Graficos y Visualizacion de Datos - BogotaJS
JavaScript para Graficos y Visualizacion de Datos - BogotaJS
 
Data Binding: Is It the Next Big Thing?
Data Binding: Is It the Next Big Thing?Data Binding: Is It the Next Big Thing?
Data Binding: Is It the Next Big Thing?
 
SOLID Principles
SOLID PrinciplesSOLID Principles
SOLID Principles
 
Evolving your Data Access with MongoDB Stitch
Evolving your Data Access with MongoDB StitchEvolving your Data Access with MongoDB Stitch
Evolving your Data Access with MongoDB Stitch
 

More from Codemotion

Fuzz-testing: A hacker's approach to making your code more secure | Pascal Ze...
Fuzz-testing: A hacker's approach to making your code more secure | Pascal Ze...Fuzz-testing: A hacker's approach to making your code more secure | Pascal Ze...
Fuzz-testing: A hacker's approach to making your code more secure | Pascal Ze...Codemotion
 
Pompili - From hero to_zero: The FatalNoise neverending story
Pompili - From hero to_zero: The FatalNoise neverending storyPompili - From hero to_zero: The FatalNoise neverending story
Pompili - From hero to_zero: The FatalNoise neverending storyCodemotion
 
Pastore - Commodore 65 - La storia
Pastore - Commodore 65 - La storiaPastore - Commodore 65 - La storia
Pastore - Commodore 65 - La storiaCodemotion
 
Pennisi - Essere Richard Altwasser
Pennisi - Essere Richard AltwasserPennisi - Essere Richard Altwasser
Pennisi - Essere Richard AltwasserCodemotion
 
Michel Schudel - Let's build a blockchain... in 40 minutes! - Codemotion Amst...
Michel Schudel - Let's build a blockchain... in 40 minutes! - Codemotion Amst...Michel Schudel - Let's build a blockchain... in 40 minutes! - Codemotion Amst...
Michel Schudel - Let's build a blockchain... in 40 minutes! - Codemotion Amst...Codemotion
 
Richard Süselbeck - Building your own ride share app - Codemotion Amsterdam 2019
Richard Süselbeck - Building your own ride share app - Codemotion Amsterdam 2019Richard Süselbeck - Building your own ride share app - Codemotion Amsterdam 2019
Richard Süselbeck - Building your own ride share app - Codemotion Amsterdam 2019Codemotion
 
Eward Driehuis - What we learned from 20.000 attacks - Codemotion Amsterdam 2019
Eward Driehuis - What we learned from 20.000 attacks - Codemotion Amsterdam 2019Eward Driehuis - What we learned from 20.000 attacks - Codemotion Amsterdam 2019
Eward Driehuis - What we learned from 20.000 attacks - Codemotion Amsterdam 2019Codemotion
 
Francesco Baldassarri - Deliver Data at Scale - Codemotion Amsterdam 2019 -
Francesco Baldassarri  - Deliver Data at Scale - Codemotion Amsterdam 2019 - Francesco Baldassarri  - Deliver Data at Scale - Codemotion Amsterdam 2019 -
Francesco Baldassarri - Deliver Data at Scale - Codemotion Amsterdam 2019 - Codemotion
 
Martin Förtsch, Thomas Endres - Stereoscopic Style Transfer AI - Codemotion A...
Martin Förtsch, Thomas Endres - Stereoscopic Style Transfer AI - Codemotion A...Martin Förtsch, Thomas Endres - Stereoscopic Style Transfer AI - Codemotion A...
Martin Förtsch, Thomas Endres - Stereoscopic Style Transfer AI - Codemotion A...Codemotion
 
Melanie Rieback, Klaus Kursawe - Blockchain Security: Melting the "Silver Bul...
Melanie Rieback, Klaus Kursawe - Blockchain Security: Melting the "Silver Bul...Melanie Rieback, Klaus Kursawe - Blockchain Security: Melting the "Silver Bul...
Melanie Rieback, Klaus Kursawe - Blockchain Security: Melting the "Silver Bul...Codemotion
 
Angelo van der Sijpt - How well do you know your network stack? - Codemotion ...
Angelo van der Sijpt - How well do you know your network stack? - Codemotion ...Angelo van der Sijpt - How well do you know your network stack? - Codemotion ...
Angelo van der Sijpt - How well do you know your network stack? - Codemotion ...Codemotion
 
Lars Wolff - Performance Testing for DevOps in the Cloud - Codemotion Amsterd...
Lars Wolff - Performance Testing for DevOps in the Cloud - Codemotion Amsterd...Lars Wolff - Performance Testing for DevOps in the Cloud - Codemotion Amsterd...
Lars Wolff - Performance Testing for DevOps in the Cloud - Codemotion Amsterd...Codemotion
 
Sascha Wolter - Conversational AI Demystified - Codemotion Amsterdam 2019
Sascha Wolter - Conversational AI Demystified - Codemotion Amsterdam 2019Sascha Wolter - Conversational AI Demystified - Codemotion Amsterdam 2019
Sascha Wolter - Conversational AI Demystified - Codemotion Amsterdam 2019Codemotion
 
Michele Tonutti - Scaling is caring - Codemotion Amsterdam 2019
Michele Tonutti - Scaling is caring - Codemotion Amsterdam 2019Michele Tonutti - Scaling is caring - Codemotion Amsterdam 2019
Michele Tonutti - Scaling is caring - Codemotion Amsterdam 2019Codemotion
 
Pat Hermens - From 100 to 1,000+ deployments a day - Codemotion Amsterdam 2019
Pat Hermens - From 100 to 1,000+ deployments a day - Codemotion Amsterdam 2019Pat Hermens - From 100 to 1,000+ deployments a day - Codemotion Amsterdam 2019
Pat Hermens - From 100 to 1,000+ deployments a day - Codemotion Amsterdam 2019Codemotion
 
James Birnie - Using Many Worlds of Compute Power with Quantum - Codemotion A...
James Birnie - Using Many Worlds of Compute Power with Quantum - Codemotion A...James Birnie - Using Many Worlds of Compute Power with Quantum - Codemotion A...
James Birnie - Using Many Worlds of Compute Power with Quantum - Codemotion A...Codemotion
 
Don Goodman-Wilson - Chinese food, motor scooters, and open source developmen...
Don Goodman-Wilson - Chinese food, motor scooters, and open source developmen...Don Goodman-Wilson - Chinese food, motor scooters, and open source developmen...
Don Goodman-Wilson - Chinese food, motor scooters, and open source developmen...Codemotion
 
Pieter Omvlee - The story behind Sketch - Codemotion Amsterdam 2019
Pieter Omvlee - The story behind Sketch - Codemotion Amsterdam 2019Pieter Omvlee - The story behind Sketch - Codemotion Amsterdam 2019
Pieter Omvlee - The story behind Sketch - Codemotion Amsterdam 2019Codemotion
 
Dave Farley - Taking Back “Software Engineering” - Codemotion Amsterdam 2019
Dave Farley - Taking Back “Software Engineering” - Codemotion Amsterdam 2019Dave Farley - Taking Back “Software Engineering” - Codemotion Amsterdam 2019
Dave Farley - Taking Back “Software Engineering” - Codemotion Amsterdam 2019Codemotion
 
Joshua Hoffman - Should the CTO be Coding? - Codemotion Amsterdam 2019
Joshua Hoffman - Should the CTO be Coding? - Codemotion Amsterdam 2019Joshua Hoffman - Should the CTO be Coding? - Codemotion Amsterdam 2019
Joshua Hoffman - Should the CTO be Coding? - Codemotion Amsterdam 2019Codemotion
 

More from Codemotion (20)

Fuzz-testing: A hacker's approach to making your code more secure | Pascal Ze...
Fuzz-testing: A hacker's approach to making your code more secure | Pascal Ze...Fuzz-testing: A hacker's approach to making your code more secure | Pascal Ze...
Fuzz-testing: A hacker's approach to making your code more secure | Pascal Ze...
 
Pompili - From hero to_zero: The FatalNoise neverending story
Pompili - From hero to_zero: The FatalNoise neverending storyPompili - From hero to_zero: The FatalNoise neverending story
Pompili - From hero to_zero: The FatalNoise neverending story
 
Pastore - Commodore 65 - La storia
Pastore - Commodore 65 - La storiaPastore - Commodore 65 - La storia
Pastore - Commodore 65 - La storia
 
Pennisi - Essere Richard Altwasser
Pennisi - Essere Richard AltwasserPennisi - Essere Richard Altwasser
Pennisi - Essere Richard Altwasser
 
Michel Schudel - Let's build a blockchain... in 40 minutes! - Codemotion Amst...
Michel Schudel - Let's build a blockchain... in 40 minutes! - Codemotion Amst...Michel Schudel - Let's build a blockchain... in 40 minutes! - Codemotion Amst...
Michel Schudel - Let's build a blockchain... in 40 minutes! - Codemotion Amst...
 
Richard Süselbeck - Building your own ride share app - Codemotion Amsterdam 2019
Richard Süselbeck - Building your own ride share app - Codemotion Amsterdam 2019Richard Süselbeck - Building your own ride share app - Codemotion Amsterdam 2019
Richard Süselbeck - Building your own ride share app - Codemotion Amsterdam 2019
 
Eward Driehuis - What we learned from 20.000 attacks - Codemotion Amsterdam 2019
Eward Driehuis - What we learned from 20.000 attacks - Codemotion Amsterdam 2019Eward Driehuis - What we learned from 20.000 attacks - Codemotion Amsterdam 2019
Eward Driehuis - What we learned from 20.000 attacks - Codemotion Amsterdam 2019
 
Francesco Baldassarri - Deliver Data at Scale - Codemotion Amsterdam 2019 -
Francesco Baldassarri  - Deliver Data at Scale - Codemotion Amsterdam 2019 - Francesco Baldassarri  - Deliver Data at Scale - Codemotion Amsterdam 2019 -
Francesco Baldassarri - Deliver Data at Scale - Codemotion Amsterdam 2019 -
 
Martin Förtsch, Thomas Endres - Stereoscopic Style Transfer AI - Codemotion A...
Martin Förtsch, Thomas Endres - Stereoscopic Style Transfer AI - Codemotion A...Martin Förtsch, Thomas Endres - Stereoscopic Style Transfer AI - Codemotion A...
Martin Förtsch, Thomas Endres - Stereoscopic Style Transfer AI - Codemotion A...
 
Melanie Rieback, Klaus Kursawe - Blockchain Security: Melting the "Silver Bul...
Melanie Rieback, Klaus Kursawe - Blockchain Security: Melting the "Silver Bul...Melanie Rieback, Klaus Kursawe - Blockchain Security: Melting the "Silver Bul...
Melanie Rieback, Klaus Kursawe - Blockchain Security: Melting the "Silver Bul...
 
Angelo van der Sijpt - How well do you know your network stack? - Codemotion ...
Angelo van der Sijpt - How well do you know your network stack? - Codemotion ...Angelo van der Sijpt - How well do you know your network stack? - Codemotion ...
Angelo van der Sijpt - How well do you know your network stack? - Codemotion ...
 
Lars Wolff - Performance Testing for DevOps in the Cloud - Codemotion Amsterd...
Lars Wolff - Performance Testing for DevOps in the Cloud - Codemotion Amsterd...Lars Wolff - Performance Testing for DevOps in the Cloud - Codemotion Amsterd...
Lars Wolff - Performance Testing for DevOps in the Cloud - Codemotion Amsterd...
 
Sascha Wolter - Conversational AI Demystified - Codemotion Amsterdam 2019
Sascha Wolter - Conversational AI Demystified - Codemotion Amsterdam 2019Sascha Wolter - Conversational AI Demystified - Codemotion Amsterdam 2019
Sascha Wolter - Conversational AI Demystified - Codemotion Amsterdam 2019
 
Michele Tonutti - Scaling is caring - Codemotion Amsterdam 2019
Michele Tonutti - Scaling is caring - Codemotion Amsterdam 2019Michele Tonutti - Scaling is caring - Codemotion Amsterdam 2019
Michele Tonutti - Scaling is caring - Codemotion Amsterdam 2019
 
Pat Hermens - From 100 to 1,000+ deployments a day - Codemotion Amsterdam 2019
Pat Hermens - From 100 to 1,000+ deployments a day - Codemotion Amsterdam 2019Pat Hermens - From 100 to 1,000+ deployments a day - Codemotion Amsterdam 2019
Pat Hermens - From 100 to 1,000+ deployments a day - Codemotion Amsterdam 2019
 
James Birnie - Using Many Worlds of Compute Power with Quantum - Codemotion A...
James Birnie - Using Many Worlds of Compute Power with Quantum - Codemotion A...James Birnie - Using Many Worlds of Compute Power with Quantum - Codemotion A...
James Birnie - Using Many Worlds of Compute Power with Quantum - Codemotion A...
 
Don Goodman-Wilson - Chinese food, motor scooters, and open source developmen...
Don Goodman-Wilson - Chinese food, motor scooters, and open source developmen...Don Goodman-Wilson - Chinese food, motor scooters, and open source developmen...
Don Goodman-Wilson - Chinese food, motor scooters, and open source developmen...
 
Pieter Omvlee - The story behind Sketch - Codemotion Amsterdam 2019
Pieter Omvlee - The story behind Sketch - Codemotion Amsterdam 2019Pieter Omvlee - The story behind Sketch - Codemotion Amsterdam 2019
Pieter Omvlee - The story behind Sketch - Codemotion Amsterdam 2019
 
Dave Farley - Taking Back “Software Engineering” - Codemotion Amsterdam 2019
Dave Farley - Taking Back “Software Engineering” - Codemotion Amsterdam 2019Dave Farley - Taking Back “Software Engineering” - Codemotion Amsterdam 2019
Dave Farley - Taking Back “Software Engineering” - Codemotion Amsterdam 2019
 
Joshua Hoffman - Should the CTO be Coding? - Codemotion Amsterdam 2019
Joshua Hoffman - Should the CTO be Coding? - Codemotion Amsterdam 2019Joshua Hoffman - Should the CTO be Coding? - Codemotion Amsterdam 2019
Joshua Hoffman - Should the CTO be Coding? - Codemotion Amsterdam 2019
 

Recently uploaded

Next-generation AAM aircraft unveiled by Supernal, S-A2
Next-generation AAM aircraft unveiled by Supernal, S-A2Next-generation AAM aircraft unveiled by Supernal, S-A2
Next-generation AAM aircraft unveiled by Supernal, S-A2Hyundai Motor Group
 
Benefits Of Flutter Compared To Other Frameworks
Benefits Of Flutter Compared To Other FrameworksBenefits Of Flutter Compared To Other Frameworks
Benefits Of Flutter Compared To Other FrameworksSoftradix Technologies
 
SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024Scott Keck-Warren
 
Slack Application Development 101 Slides
Slack Application Development 101 SlidesSlack Application Development 101 Slides
Slack Application Development 101 Slidespraypatel2
 
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j
 
Key Features Of Token Development (1).pptx
Key  Features Of Token  Development (1).pptxKey  Features Of Token  Development (1).pptx
Key Features Of Token Development (1).pptxLBM Solutions
 
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...shyamraj55
 
Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Scott Keck-Warren
 
Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Allon Mureinik
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking MenDelhi Call girls
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreternaman860154
 
How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonetsnaman860154
 
Pigging Solutions in Pet Food Manufacturing
Pigging Solutions in Pet Food ManufacturingPigging Solutions in Pet Food Manufacturing
Pigging Solutions in Pet Food ManufacturingPigging Solutions
 
AI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsAI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsMemoori
 
Human Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsHuman Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsMark Billinghurst
 
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024BookNet Canada
 
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticsKotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticscarlostorres15106
 
CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):comworks
 

Recently uploaded (20)

Next-generation AAM aircraft unveiled by Supernal, S-A2
Next-generation AAM aircraft unveiled by Supernal, S-A2Next-generation AAM aircraft unveiled by Supernal, S-A2
Next-generation AAM aircraft unveiled by Supernal, S-A2
 
Benefits Of Flutter Compared To Other Frameworks
Benefits Of Flutter Compared To Other FrameworksBenefits Of Flutter Compared To Other Frameworks
Benefits Of Flutter Compared To Other Frameworks
 
The transition to renewables in India.pdf
The transition to renewables in India.pdfThe transition to renewables in India.pdf
The transition to renewables in India.pdf
 
SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024
 
Slack Application Development 101 Slides
Slack Application Development 101 SlidesSlack Application Development 101 Slides
Slack Application Development 101 Slides
 
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
 
Key Features Of Token Development (1).pptx
Key  Features Of Token  Development (1).pptxKey  Features Of Token  Development (1).pptx
Key Features Of Token Development (1).pptx
 
Vulnerability_Management_GRC_by Sohang Sengupta.pptx
Vulnerability_Management_GRC_by Sohang Sengupta.pptxVulnerability_Management_GRC_by Sohang Sengupta.pptx
Vulnerability_Management_GRC_by Sohang Sengupta.pptx
 
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
 
Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024
 
Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreter
 
How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonets
 
Pigging Solutions in Pet Food Manufacturing
Pigging Solutions in Pet Food ManufacturingPigging Solutions in Pet Food Manufacturing
Pigging Solutions in Pet Food Manufacturing
 
AI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsAI as an Interface for Commercial Buildings
AI as an Interface for Commercial Buildings
 
Human Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsHuman Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR Systems
 
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
 
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticsKotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
 
CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):
 

Sebastian Schmidt, Rachel Myers - How To Go Serverless And Not Violate The GDPR - Codemotion Berlin 2018

  • 1. How to go serverless and not violate the GDPR Sebastian Schmidt and Rachel Myers Berlin | November 20 - 21, 2018
  • 2.
  • 3. GDPR 11 Chapters that regulate: ● Rights of data subjects ● Responsibilities for data controllers/processors ● Data transfers ● Penalties
  • 4. GDPR 11 Chapters that regulate: ● Rights of data subjects ● Responsibilities for data controllers/processors ● Data transfers ● Penalties Your users! You!
  • 9.
  • 10.
  • 15.
  • 16. User privacy built on Serverless
  • 17. Reduce the user data that you store Manage user data with Cloud Functions: Delete data you no longer need Export data on request Security Rules! Inform users about data collection: Storage Retention Policies Firebase Instance IDs Storing Privacy Settings Keeping an Activity Log
  • 18. Reduce the user data that you store Manage user data with Cloud Functions: Delete data you no longer need Export data on request Security Rules! Inform users about data collection: Storage Retention Policies Firebase Instance IDs Storing Privacy Settings Keeping an Activity Log
  • 19. Read your Horoscope! (You have to be an EU citizen and 18+) Username Birthday Country sebastian April 28th, 1990 Czech Republic
  • 20. Read your Horoscope! (You have to be an EU citizen and 18+) Username Birthday Country sebastian April 28th, 1990 Czech Republic
  • 25. Save only what you need. Only as long as you need.
  • 26. SELECT COUNT(*) FROM users WHERE age BETWEEN (18, 25) Keep the count. Don’t keep the data!
  • 27. Reduce the user data that you store Manage user data with Cloud Functions: Delete data you no longer need Export data on request Security Rules! Inform users about data collection: Storage Retention Policies Firebase Instance IDs Storing Privacy Settings Keeping an Activity Log
  • 28. Delete user data ● When your app no longer needs the data ● When a user deletes their account
  • 29.
  • 32. Cloud Functions for Firebase programmatically connect Firebase and Cloud
  • 33. How does it work? Event emitted Your code executed Function triggered
  • 34. How does it work? Event emitted Your code executed Function triggered firestore.document(‘posts/a’).delete( ) deleteData() function
  • 35. We only display the top five! No need to save the rest!
  • 37. Manage User Data Privacy with Cloud Functions link.firebase.events/h1
  • 38. App Engine lets you invoke Cloud Functions periodically! link.firebase.events/h2
  • 39. Remove user data ● When your app no longer needs the data ● When a user deletes their account
  • 41. // functions/index.js // Paths to user data to export or delete exports.clearData = functions.auth.user().onDelete((event) => { const uid = event.data.uid; const dbPromise = clearDatabaseData(uid); const storagePromise = clearStorageData(uid); const firestorePromise = clearFirestoreData(uid); const promises = [dbPromise, storagePromise, firestorePromise]; return Promise.all(promises).then(() => console.log(`Successfully removed data for user ${uid}.`) ); }); link.firebase.events/h4
  • 42. // functions/index.js // Paths to user data to export or delete exports.clearData = functions.auth.user().onDelete((event) => { const uid = event.data.uid; const dbPromise = clearDatabaseData(uid); const storagePromise = clearStorageData(uid); const firestorePromise = clearFirestoreData(uid); const promises = [dbPromise, storagePromise, firestorePromise]; return Promise.all(promises).then(() => console.log(`Successfully removed data for user ${uid}.`) ); }); link.firebase.events/h4
  • 43. // functions/user_privacy.json // Paths to user data to export or delete { "storage": { "clearData": [ ["myproject.appspot.com", "UID/sample_data.json"], ["myproject.appspot.com", "UID/avatar"] ], }, "firestore": { "clearData": [ {"collection": "users", "doc": "UID", "field": "last_name"}, {"collection": "admins", "doc": "UID"} ] } } link.firebase.events/h4
  • 44. // functions/index.js // Paths to user data to export or delete exports.clearData = functions.auth.user().onDelete((event) => { const uid = event.data.uid; const dbPromise = clearDatabaseData(uid); const storagePromise = clearStorageData(uid); const firestorePromise = clearFirestoreData(uid); const promises = [dbPromise, storagePromise, firestorePromise]; return Promise.all(promises).then(() => console.log(`Successfully removed data for user ${uid}.`) ); }); link.firebase.events/h4
  • 45. // functions/user_privacy.json // Paths to user data to export or delete exports.clearData = functions.auth.user().onDelete((event) => { const uid = event.data.uid; const dbPromise = clearDatabaseData(uid); const storagePromise = clearStorageData(uid); const firestorePromise = clearFirestoreData(uid); const promises = [dbPromise, storagePromise, firestorePromise]; return Promise.all(promises).then(() => console.log(`Successfully removed data for user ${uid}.`) ); }); link.firebase.events/h4
  • 46. // functions/index.js // Deletes user data from the RealTime Database const clearDatabaseData = (uid) => { const paths = userPrivacyPaths.database.clearData; const promises = []; for (let i = 0; i < paths.length; i++) { const path = replaceUID(paths[i], uid); promises.push(db.ref(path).remove().catch((error) => { // Avoid execution interuption. console.error('Error deleting data at ', path, error); })); } return Promise.all(promises).then(() => uid); }; link.firebase.events/h4
  • 47. // functions/index.js // Deletes user data from the RealTime Database const clearDatabaseData = (uid) => { const paths = userPrivacyPaths.database.clearData; const promises = []; for (let i = 0; i < paths.length; i++) { const path = replaceUID(paths[i], uid); promises.push(db.ref(path).remove().catch((error) => { // Avoid execution interuption. console.error('Error deleting data at ', path, error); })); } return Promise.all(promises).then(() => uid); }; link.firebase.events/h4
  • 48. // functions/index.js // Deletes user data from the RealTime Database const clearDatabaseData = (uid) => { const paths = userPrivacyPaths.database.clearData; const promises = []; for (let i = 0; i < paths.length; i++) { const path = replaceUID(paths[i], uid); promises.push(db.ref(path).remove().catch((error) => { // Avoid execution interuption. console.error('Error deleting data at ', path, error); })); } return Promise.all(promises).then(() => uid); }; link.firebase.events/h4
  • 49. Reduce the user data that you store Manage user data with Cloud Functions: Delete data you no longer need Export data on request Security Rules! Inform users about data collection: Storage Retention Policies Firebase Instance IDs Storing Privacy Settings Keeping an Activity Log
  • 50. // functions/index.js // Exports user data exports.exportData = functions.https.onRequest((req, res) => { const uid = JSON.parse(req.body).uid; const exportData = {}; const dbProm = exportDatabaseData(uid).then((dbData) => { exportData.database = dbData; }); const fsProm = exportFirestoreData(uid).then((fsData) => { exportData.firestore = fsData; }); const storageProm = exportStorageData(uid).then((storageRefs) => { exportData.storage = storageRefs; }); return Promise.all([dbProm, fsProm, storageProm]).then(() => { console.log(`Success! Completed export for user ${uid}.`); return uploadToStorage(uid, exportData); }).then(() => res.json({exportComplete: true})); }); link.firebase.events/h4
  • 51. // functions/index.js // Exports user data exports.exportData = functions.https.onRequest((req, res) => { const uid = JSON.parse(req.body).uid; const exportData = {}; const dbProm = exportDatabaseData(uid).then((dbData) => { exportData.database = dbData; }); const fsProm = exportFirestoreData(uid).then((fsData) => { exportData.firestore = fsData; }); const storageProm = exportStorageData(uid).then((storageRefs) => { exportData.storage = storageRefs; }); return Promise.all([dbProm, fsProm, storageProm]).then(() => { console.log(`Success! Completed export for user ${uid}.`); return uploadToStorage(uid, exportData); }).then(() => res.json({exportComplete: true})); }); link.firebase.events/h4
  • 52. // functions/index.js // Exports user data exports.exportData = functions.https.onRequest((req, res) => { const uid = JSON.parse(req.body).uid; const exportData = {}; const dbProm = exportDatabaseData(uid).then((dbData) => { exportData.database = dbData; }); const fsProm = exportFirestoreData(uid).then((fsData) => { exportData.firestore = fsData; }); const storageProm = exportStorageData(uid).then((storageRefs) => { exportData.storage = storageRefs; }); return Promise.all([dbProm, fsProm, storageProm]).then(() => { console.log(`Success! Completed export for user ${uid}.`); return uploadToStorage(uid, exportData); }).then(() => res.json({exportComplete: true})); }); link.firebase.events/h4
  • 53. // functions/index.js // Helper function that exports user data from RealTime Database. const exportDatabaseData = (uid) => { const paths = userPrivacyPaths.database.exportData; const promises = []; const exportData = {}; for (let i = 0; i < paths.length; i++) { const path = replaceUID(paths[i], uid); promises.push(db.ref(path).once('value').then((snapshot) => { const read = snapshot.val(); if (read !== null) { exportData[snapshot.key] = read; } }).catch((err) => { console.error('Error exporting data: ', err); })); }; return Promise.all(promises).then(() => exportData); }; link.firebase.events/h4
  • 54. // functions/index.js // Helper function that exports user data from RealTime Database. const exportDatabaseData = (uid) => { const paths = userPrivacyPaths.database.exportData; const promises = []; const exportData = {}; for (let i = 0; i < paths.length; i++) { const path = replaceUID(paths[i], uid); promises.push(db.ref(path).once('value').then((snapshot) => { const read = snapshot.val(); if (read !== null) { exportData[snapshot.key] = read; } }).catch((err) => { console.error('Error exporting data: ', err); })); }; return Promise.all(promises).then(() => exportData); }; firebase.events/q4
  • 55. // functions/index.js // Exports user data exports.exportData = functions.https.onRequest((req, res) => { const uid = JSON.parse(req.body).uid; const exportData = {}; const dbProm = exportDatabaseData(uid).then((dbData) => { exportData.database = dbData; }); const fsProm = exportFirestoreData(uid).then((fsData) => { exportData.firestore = fsData; }); const storageProm = exportStorageData(uid).then((storageRefs) => { exportData.storage = storageRefs; }); return Promise.all([dbProm, fsProm, storageProm]).then(() => { console.log(`Success! Completed export for user ${uid}.`); return uploadToStorage(uid, exportData); }).then(() => res.json({exportComplete: true})); }); link.firebase.events/h4
  • 56. service firebase.storage { match /b/{bucket}/o { match /exportData { // Only allow access to exported data by the user // who requested an export match /{uid} { allow read, write: if request.auth.uid == uid } match /{uid}/{path=**} { allow read, write: if request.auth.uid == uid } } } } firebase.events/q4
  • 57. Remember that rules are ORed together. ✔ Simulated data access allowed
  • 58. Delete and export are easier when data’s nested under a user’s UID
  • 59. $ firebase deploy ... Done.
  • 60. Manage User Data Privacy with Cloud Functions link.firebase.events/h4
  • 61. Reduce the user data that you store Manage user data with Cloud Functions: Delete data you no longer need Export data on request Security Rules! Inform users about data collection: Storage Retention Policies Firebase Instance IDs Storing Privacy Settings Keeping an Activity Log
  • 69. Security Rules Schema Messages PUBLIC USER 2USER 1 Friends Private Messages Friends Private ACTIVITY USER 2USER 1 Log Log Entry EntryEntry Entry Messages
  • 70. Rules Takeaways ● Never trust data from client apps ● Write rules with the Security Simulator ● Test rules with the Security Rules Emulator
  • 71. Reduce the user data that you store Manage user data with Cloud Functions: Delete data you no longer need Export data on request Security Rules! Inform users about data collection: Storage Retention Policies Firebase Instance IDs Storing Privacy Settings Keeping an Activity Log
  • 72. Take a look at our data retention policies link.firebase.events/h6
  • 73. Take a look at our data retention policies link.firebase.events/h7
  • 74. Reduce the user data that you store Manage user data with Cloud Functions: Delete data you no longer need Export data on request Security Rules! Inform users about data collection: Storage Retention Policies Firebase Instance IDs Storing Privacy Settings Keeping an Activity Log
  • 75. Instance IDs Unique for each app installation 123 234 345
  • 76. Instance IDs Same ID across restarts 123123 123 MON TUE 3rd 4th 5th WED
  • 77. Delete Instance ID data with the Admin SDKs link.firebase.events/h8
  • 78. Backend stores data for 2 weeks Client keeps data for 1 week
  • 79. Backend keeps backup for 2 weeks Client keeps data for 1 week We will keep your data for 2 weeks. AGREEDISAGREE
  • 82. Reduce the user data that you store Manage user data with Cloud Functions: Delete data you no longer need Export data on request Security Rules! Inform users about data collection: Storage Retention Policies Firebase Instance IDs Storing Privacy Settings Keeping an Activity Log
  • 83. Separate Public from Private Dataservice cloud.firestore { match /databases/{database}/documents { match /users/{uid}/public { allow read, write; } match /users/{uid}/private { allow read, write: if request.auth.uid == uid; } } }
  • 84. service cloud.firestore { match /databases/{database}/documents { match /public/{uid} { allow read, write; } match /private/{uid} { allow read, write: if request.auth.uid == uid; } } } Separate Public from Private Data
  • 85.
  • 86.
  • 87. Reduce the user data that you store Manage user data with Cloud Functions: Delete data you no longer need Export data on request Security Rules! Inform users about data collection: Storage Retention Policies Firebase Instance IDs Storing Privacy Settings Keeping an Activity Log
  • 88. const firestore = admin.firestore(); exports.activityLog = functions.firestore .document('privacy/{uid}').onWrite(snap => { const uid = context.params.uid; const settings = snap.data(); settings['udpate_time'] = admin.firestore.FieldValue.serverTimestamp(); firestore.collection( `activity_log/${uid}/entries` ).add(settings); }); link.firebase.events/h8
  • 89. const firestore = admin.firestore(); exports.activityLog = functions.firestore .document('privacy/{uid}').onWrite(snap => { const uid = context.params.uid; const settings = snap.data(); settings['udpate_time'] = admin.firestore.FieldValue.serverTimestamp(); firestore.collection( `activity_log/${uid}/entries` ).add(settings); }); link.firebase.events/h8
  • 90. match /activity_log/{uid} { allow create: if request.auth.uid == uid; allow update: if request.auth.uid == uid && resource == null; allow delete: if false; } link.firebase.events/h9
  • 92. Let’s treat our users well!
  • 93. ● Respect user data ● Offer clear data policies ● Limit data intake ● Let users decide how to handle data
  • 94. Thank you! Rachel Myers, Firebase GitHub & Twitter: @rachelmyers Sebastian Schmidt, Firebase GitHub: @schmidt-sebastian