SlideShare a Scribd company logo
Title of slide to go here 
RelateIQ @ MongoSF
RelateIQ @ MongoSF 
Blog 
blog.relateiq.com 
RelateIQ Twitter 
@relateiq 
{ 
name: “Jón Tómas Grétarsson”, 
pretty_description: “Early Engineer”, 
email: “jon@relateiq.com”, 
twitter: @jontomas 
}
1. MongoDB at RelateIQ 
2. Encryption at Rest 
3. Golden Horde (Oplog) 
4.Q&A 
Agenda
MongoDB usage at RelateIQ 
Our stack 
● Multiple consumers 
● Distributed services 
● Batch and stream processing 
We speak JSON 
● Cross-language compatibility 
● Engineer-debuggable 
● Easy to test! 
MongoDB 
● Strong Java support via morphia 
o Lifecycle methods!
Lifecycle methods 
Golden Horde
At-Rest Encryption 
@preLoad 
Called before mapping the datastore object to the 
entity (POJO); the DBObject is passed as an 
argument (you can add/remove/change values) 
You have 
● The DBObject 
● A class definition (reflection!) 
You don’t have 
● That POJO with all the 
convenience methods 
@preSave 
Called right before DBCollection.save() is called. 
Changes made to the entity (POJO) will not be 
persisted; the DBObject can be passed as an 
argument (you can add/remove/change values) 
You have 
● The original POJO, including class 
definitions and convenience 
methods
At-Rest Encryption 
SadPojo.java 
public class SadPojo { 
public String clientId; 
public String secret; 
}; 
SadDAO.java 
public class SadDAO 
extends BasicDAO<SadPojo> { 
@Inject 
public SadDAO(Datastore ds) { 
super(SadPojo.class, ds); 
} 
};
At-Rest Encryption 
Command Line 
> db.SadPojo.findOne() 
{ 
"_id": ObjectId("5445dd2b7830e8d4dff439d9"), 
"clientId": "Dr. No", 
"secret": "What follows are my evil plans to take over the 
world..." 
}
SketchyPojo.java 
public class SketchyPojo { 
public String clientId; 
public String secretKey; 
public String secret; 
@PreSave 
public void preSave(DBObject obj) { 
obj.put(“secret”, encryptWithSecret(secretKey, secret); 
} 
@PreLoad 
public void preLoad(DBObject obj) { 
try { 
obj.put(“secret”, decryptWithSecret(obj.get(“secretKey”), obj.get(“secret”)); 
} catch (EncryptionException e) {} 
} 
}; 
At-Rest Encryption (Take One)
At-Rest Encryption (Take One) 
Command Line 
> db.SketchyPojo.findOne() 
{ 
"_id": ObjectId("5445dd2b7830e8d4dff439d9"), 
"clientId": "Dr. No", 
"secretKey": "<BASE64-encoded byte string>", 
"secret": "APu5vPONiaLD4- 
ykkgG6gG7hlN7reB_XY3rqLGkQ5aBTZBXveUqH_jJwRSjNCMCjrT0rFSe0ZCyrUAxPvjzV 
idKs5JIbtvwX0SQqGmKf_853a-L_CkoyCRgJfPwzf81XM1dpGR8Kp9hMNAvkrdbco- 
GdZgE6HENRnXcLzmoYTVhUIhwSCi3rX_8w9_Wn_GVLGI3EF-s- 
0r7bqElxn0CB2l4W80sjDTlom_0nbZfwF92Xq9cctnnWghgLYaVEWxL3Va2tQL-BJtybcMiJd- 
DnxXjHxlRPRB4jtIP8eJMagW7hCh7aDEOC5s0SEiZs5fLRt-dExKgbwxjz" 
}
SketchyPojo.java 
public class SketchyPojo { 
public String clientId; 
public String secretKey; 
public String secret; 
@PreSave 
public void preSave(DBObject obj) { 
obj.put(“secret”, encryptWithSecret(secretKey, secret); 
} 
@PreLoad 
public void preLoad(DBObject obj) { 
try { 
obj.put(“secret”, decryptWithSecret(obj.get(“secretKey”), obj.get(“secret”)); 
} catch (EncryptionException e) {} 
} 
}; 
At-Rest Encryption (Take One)
At-Rest Encryption (Take Two) 
LessSketchyDAO.java 
public class LessSketchyDAO extends BasicDAO<LessSketchyPojo> { 
@Inject 
public LessSketchyDAO(Datastore ds) { 
super(LessSketchyPojo.class, ds); 
} 
@PreSave 
public void preSave(LessSketchyPojo pojo, DBObject obj) { 
obj.put(“secret”, encryptWithSecret(pojo.secretKey, pojo.secret); 
} 
@PreLoad 
public void preLoad(DBObject obj) { 
try { 
obj.put(“secret”, decryptWithSecret(obj.get(“secretKey”), obj.get(“secret”)); 
} catch (EncryptionException e) {} 
} 
};
At-Rest Encryption (Take Two) 
Command Line 
> db.LessSketchyPojo.findOne() 
{ 
"_id": ObjectId("5445dd2b7830e8d4dff439d9"), 
"clientId": "Dr. No", 
"secretKey": "<BASE64-encoded byte string>", 
"secret": "APu5vPONiaLD4- 
ykkgG6gG7hlN7reB_XY3rqLGkQ5aBTZBXveUqH_jJwRSjNCMCjrT0rFSe0ZCyrUAxPvjzV 
idKs5JIbtvwX0SQqGmKf_853a-L_CkoyCRgJfPwzf81XM1dpGR8Kp9hMNAvkrdbco- 
GdZgE6HENRnXcLzmoYTVhUIhwSCi3rX_8w9_Wn_GVLGI3EF-s- 
0r7bqElxn0CB2l4W80sjDTlom_0nbZfwF92Xq9cctnnWghgLYaVEWxL3Va2tQL-BJtybcMiJd- 
DnxXjHxlRPRB4jtIP8eJMagW7hCh7aDEOC5s0SEiZs5fLRt-dExKgbwxjz" 
}
At-Rest Encryption (Take Two) 
LessSketchyDAO.java 
public class LessSketchyDAO extends BasicDAO<LessSketchyPojo> { 
@Inject 
public LessSketchyDAO(Datastore ds) { 
super(LessSketchyPojo.class, ds); 
} 
@PreSave 
public void preSave(LessSketchyPojo pojo, DBObject obj) { 
obj.put(“secret”, encryptWithSecret(pojo.secretKey, pojo.secret); 
} 
@PreLoad 
public void preLoad(DBObject obj) { 
try { 
obj.put(“secret”, decryptWithSecret(obj.get(“secretKey”), obj.get(“secret”)); 
} catch (EncryptionException e) {} 
} 
};
At-Rest Encryption (Take Three) 
HappyPojo.java 
public class HappyPojo { 
@EncryptionScope public String clientId; 
@EncryptAtRest public String secret; 
};
At-Rest Encryption (Take Three) 
Command Line 
> db.HappyPojo.findOne() 
{ 
"_id": ObjectId("5445dd2b7830e8d4dff439d9"), 
"clientId": "Dr. No", 
"secret": "APu5vPONiaLD4- 
ykkgG6gG7hlN7reB_XY3rqLGkQ5aBTZBXveUqH_jJwRSjNCMCjrT0rFSe0ZCyrUAxPvjzVidKs5JIbtvwX0SQqGmK 
f_853a-L_CkoyCRgJfPwzf81XM1dpGR8Kp9hMNAvkrdbco- 
GdZgE6HENRnXcLzmoYTVhUIhwSCi3rX_8w9_Wn_GVLGI3EF-s- 
0r7bqElxn0CB2l4W80sjDTlom_0nbZfwF92Xq9cctnnWghgLYaVEWxL3Va2tQL-BJtybcMiJd- 
DnxXjHxlRPRB4jtIP8eJMagW7hCh7aDEOC5s0SEiZs5fLRt-dExKgbwxjz" 
}
At-Rest Encryption (Take Three) 
Command Line 
> db.HappyPojo.findOne() 
{ 
"_id": ObjectId("5445dd2b7830e8d4dff439d9"), 
"clientId": "Dr. No", 
"secret": "APu5vPONiaLD4- 
ykkgG6gG7hlN7reB_XY3rqLGkQ5aBTZBXveUqH_jJwRSjNCMCjrT0rFSe0ZCyrUAxPvjzVidKs5JIbtvwX0SQqGmK 
f_853a-L_CkoyCRgJfPwzf81XM1dpGR8Kp9hMNAvkrdbco- 
GdZgE6HENRnXcLzmoYTVhUIhwSCi3rX_8w9_Wn_GVLGI3EF-s- 
0r7bqElxn0CB2l4W80sjDTlom_0nbZfwF92Xq9cctnnWghgLYaVEWxL3Va2tQL-BJtybcMiJd- 
DnxXjHxlRPRB4jtIP8eJMagW7hCh7aDEOC5s0SEiZs5fLRt-dExKgbwxjz" 
} 
> db.ScopedKeys.find({_id : "Dr. No"}) 
{ 
"_id": "Dr. No", 
"metadata": "{ < some JSON describing a Keyczar DECRYPT_AND_ENCRYPT keyring > }", 
"secrets": [ 
"0": "{"aesKeyString": "22mM-utDU_LSzhhwus3cuA","mode":"CBC","size":128}", 
"1": "{"aesKeyString": "22mM-utDU_LSzhhwus3cuA","mode":"CBC","size":128}" 
] 
}
At-Rest Encryption (Take Three) 
MongoModule.java 
public class MongoModule extends AbstractModule { 
@Provides 
public Morphia providesMorphia(CrypterFactory crypterFactory) { 
Morphia morphia = new Morphia(); 
... 
morphia.getMapper().addInterceptor( 
new EncryptAtRestInterceptor(crypterFactory)); 
return morphia; 
};
Encrypt-At-Rest like the boss 
Key Takeaways 
1. Don’t Repeat Yourself. 
2. Morphia’s lifecycle handling is incredibly useful, when used properly. 
3. Don’t Repeat Yourself! 
4. Encryption is a scary word, but we can make it as natural as annotating a POJO. 
5. Use OSS to DRY your code 
https://github.com/relateiq/EncryptAtRestInterceptor 
1. Pull requests appreciated!
The Oplog 
Golden Horde
Golden Horde 
Lifecycle Methods are Awesome 
● So why don’t we use it to ETL 
changes to the database for 
analytics and data warehousing? 
● Better, how about we transform 
documents and feed them back into 
the system!?
Golden Horde 
Lifecycle Methods are Awesome 
● So why don’t we use it to ETL 
changes to the database? 
Okay… awesome-”ish” 
● It only takes one guy with CLI 
access, or a buggy service.
Golden Horde 
Lifecycle Methods are Awesome 
● So why don’t we use it to ETL 
changes to the database? 
Okay… awesome-”ish” 
● It only takes one guy with CLI 
access, or a buggy service. 
Oplog to the rescue! 
● We can rely on the same system 
that Mongo uses internally for 
tracking and updating repls.
Golden Horde
Closing Arguments 
Golden Horde
Q & A 
Golden Horde

More Related Content

What's hot (20)

PPTX
Hack ASP.NET website
Positive Hack Days
 
PDF
支撐英雄聯盟戰績網的那條巨蟒
Toki Kanno
 
PDF
Philipp Krenn | Make Your Data FABulous | Codemotion Madrid 2018
Codemotion
 
PDF
Elasticsearch at Dailymotion
Cédric Hourcade
 
PDF
Password Security
CSCJournals
 
PPTX
Grokking Grok: Monitorama PDX 2015
GregMefford
 
PPTX
OWASP AppSecCali 2015 - Marshalling Pickles
Christopher Frohoff
 
PPTX
The Art of JVM Profiling
Andrei Pangin
 
PPTX
Passwords presentation
Greg MacPherson
 
PDF
Elastic search 검색
HyeonSeok Choi
 
PDF
MongoDB World 2016: Deciphering .explain() Output
MongoDB
 
PDF
Philipp Krenn "Make Your Data FABulous"
Fwdays
 
PDF
Monitoring MongoDB (MongoSV)
Boxed Ice
 
PDF
Password (in)security
Enrico Zimuel
 
PDF
Search Evolution - Von Lucene zu Solr und ElasticSearch
Florian Hopf
 
PDF
MongoDB Performance Tuning
Puneet Behl
 
PDF
Bang-Bang, you have been hacked - Yonatan Levin, KolGene
DroidConTLV
 
PDF
ドキュメントデータベースとして MySQLを使う!? ~MySQL JSON UDF~
yoyamasaki
 
PDF
What's new in Liferay Mobile SDK 2.0 for Android
Silvio Gustavo de Oliveira Santos
 
PDF
0 to 31337 Real Quick: Lessons Learned by Reversing the Flare-On Challenge
Blaine Stancill
 
Hack ASP.NET website
Positive Hack Days
 
支撐英雄聯盟戰績網的那條巨蟒
Toki Kanno
 
Philipp Krenn | Make Your Data FABulous | Codemotion Madrid 2018
Codemotion
 
Elasticsearch at Dailymotion
Cédric Hourcade
 
Password Security
CSCJournals
 
Grokking Grok: Monitorama PDX 2015
GregMefford
 
OWASP AppSecCali 2015 - Marshalling Pickles
Christopher Frohoff
 
The Art of JVM Profiling
Andrei Pangin
 
Passwords presentation
Greg MacPherson
 
Elastic search 검색
HyeonSeok Choi
 
MongoDB World 2016: Deciphering .explain() Output
MongoDB
 
Philipp Krenn "Make Your Data FABulous"
Fwdays
 
Monitoring MongoDB (MongoSV)
Boxed Ice
 
Password (in)security
Enrico Zimuel
 
Search Evolution - Von Lucene zu Solr und ElasticSearch
Florian Hopf
 
MongoDB Performance Tuning
Puneet Behl
 
Bang-Bang, you have been hacked - Yonatan Levin, KolGene
DroidConTLV
 
ドキュメントデータベースとして MySQLを使う!? ~MySQL JSON UDF~
yoyamasaki
 
What's new in Liferay Mobile SDK 2.0 for Android
Silvio Gustavo de Oliveira Santos
 
0 to 31337 Real Quick: Lessons Learned by Reversing the Flare-On Challenge
Blaine Stancill
 

Similar to Hacking MongoDB at RelateIQ, A Salesforce Company (20)

PDF
[C12]元気Hadoop! OracleをHadoopで分析しちゃうぜ by Daisuke Hirama
Insight Technology, Inc.
 
PDF
Appsec usa2013 js_libinsecurity_stefanodipaola
drewz lin
 
PPTX
JWTs and JOSE in a flash
Evan J Johnson (Not a CISSP)
 
PDF
JSLT: JSON querying and transformation
Lars Marius Garshol
 
PPTX
ORM in Go. Internals, tips & tricks
Dmytro Istratkin
 
PDF
Ts archiving
Confiz
 
PPTX
DevOps Fest 2019. Сергей Марченко. Terraform: a novel about modules, provider...
DevOps_Fest
 
PPTX
NoSQL Endgame LWJUG 2021
Thodoris Bais
 
PPTX
REST with Eve and Python
PiXeL16
 
PDF
Fast as C: How to Write Really Terrible Java
Charles Nutter
 
PPTX
Django cryptography
Erik LaBianca
 
PDF
marko_go_in_badoo
Marko Kevac
 
PDF
Crystal & Kemal: Simply Fast
Serdar Dogruyol
 
PDF
ActiveJDBC - ActiveRecord implementation in Java
ipolevoy
 
PDF
Questioning the status quo
Ivano Pagano
 
PPTX
Attack monitoring using ElasticSearch Logstash and Kibana
Prajal Kulkarni
 
KEY
Php Code Audits (PHP UK 2010)
Damien Seguy
 
PDF
Jsonsaga 100605143125-phpapp02
Ramamohan Chokkam
 
PDF
[CB20] Vulnerabilities of Machine Learning Infrastructure by Sergey Gordeychik
CODE BLUE
 
PDF
ZODB Tips and Tricks
Carlos de la Guardia
 
[C12]元気Hadoop! OracleをHadoopで分析しちゃうぜ by Daisuke Hirama
Insight Technology, Inc.
 
Appsec usa2013 js_libinsecurity_stefanodipaola
drewz lin
 
JWTs and JOSE in a flash
Evan J Johnson (Not a CISSP)
 
JSLT: JSON querying and transformation
Lars Marius Garshol
 
ORM in Go. Internals, tips & tricks
Dmytro Istratkin
 
Ts archiving
Confiz
 
DevOps Fest 2019. Сергей Марченко. Terraform: a novel about modules, provider...
DevOps_Fest
 
NoSQL Endgame LWJUG 2021
Thodoris Bais
 
REST with Eve and Python
PiXeL16
 
Fast as C: How to Write Really Terrible Java
Charles Nutter
 
Django cryptography
Erik LaBianca
 
marko_go_in_badoo
Marko Kevac
 
Crystal & Kemal: Simply Fast
Serdar Dogruyol
 
ActiveJDBC - ActiveRecord implementation in Java
ipolevoy
 
Questioning the status quo
Ivano Pagano
 
Attack monitoring using ElasticSearch Logstash and Kibana
Prajal Kulkarni
 
Php Code Audits (PHP UK 2010)
Damien Seguy
 
Jsonsaga 100605143125-phpapp02
Ramamohan Chokkam
 
[CB20] Vulnerabilities of Machine Learning Infrastructure by Sergey Gordeychik
CODE BLUE
 
ZODB Tips and Tricks
Carlos de la Guardia
 

More from MongoDB (20)

PDF
MongoDB SoCal 2020: Migrate Anything* to MongoDB Atlas
MongoDB
 
PDF
MongoDB SoCal 2020: Go on a Data Safari with MongoDB Charts!
MongoDB
 
PDF
MongoDB SoCal 2020: Using MongoDB Services in Kubernetes: Any Platform, Devel...
MongoDB
 
PDF
MongoDB SoCal 2020: A Complete Methodology of Data Modeling for MongoDB
MongoDB
 
PDF
MongoDB SoCal 2020: From Pharmacist to Analyst: Leveraging MongoDB for Real-T...
MongoDB
 
PDF
MongoDB SoCal 2020: Best Practices for Working with IoT and Time-series Data
MongoDB
 
PDF
MongoDB SoCal 2020: MongoDB Atlas Jump Start
MongoDB
 
PDF
MongoDB .local San Francisco 2020: Powering the new age data demands [Infosys]
MongoDB
 
PDF
MongoDB .local San Francisco 2020: Using Client Side Encryption in MongoDB 4.2
MongoDB
 
PDF
MongoDB .local San Francisco 2020: Using MongoDB Services in Kubernetes: any ...
MongoDB
 
PDF
MongoDB .local San Francisco 2020: Go on a Data Safari with MongoDB Charts!
MongoDB
 
PDF
MongoDB .local San Francisco 2020: From SQL to NoSQL -- Changing Your Mindset
MongoDB
 
PDF
MongoDB .local San Francisco 2020: MongoDB Atlas Jumpstart
MongoDB
 
PDF
MongoDB .local San Francisco 2020: Tips and Tricks++ for Querying and Indexin...
MongoDB
 
PDF
MongoDB .local San Francisco 2020: Aggregation Pipeline Power++
MongoDB
 
PDF
MongoDB .local San Francisco 2020: A Complete Methodology of Data Modeling fo...
MongoDB
 
PDF
MongoDB .local San Francisco 2020: MongoDB Atlas Data Lake Technical Deep Dive
MongoDB
 
PDF
MongoDB .local San Francisco 2020: Developing Alexa Skills with MongoDB & Golang
MongoDB
 
PDF
MongoDB .local Paris 2020: Realm : l'ingrédient secret pour de meilleures app...
MongoDB
 
PDF
MongoDB .local Paris 2020: Upply @MongoDB : Upply : Quand le Machine Learning...
MongoDB
 
MongoDB SoCal 2020: Migrate Anything* to MongoDB Atlas
MongoDB
 
MongoDB SoCal 2020: Go on a Data Safari with MongoDB Charts!
MongoDB
 
MongoDB SoCal 2020: Using MongoDB Services in Kubernetes: Any Platform, Devel...
MongoDB
 
MongoDB SoCal 2020: A Complete Methodology of Data Modeling for MongoDB
MongoDB
 
MongoDB SoCal 2020: From Pharmacist to Analyst: Leveraging MongoDB for Real-T...
MongoDB
 
MongoDB SoCal 2020: Best Practices for Working with IoT and Time-series Data
MongoDB
 
MongoDB SoCal 2020: MongoDB Atlas Jump Start
MongoDB
 
MongoDB .local San Francisco 2020: Powering the new age data demands [Infosys]
MongoDB
 
MongoDB .local San Francisco 2020: Using Client Side Encryption in MongoDB 4.2
MongoDB
 
MongoDB .local San Francisco 2020: Using MongoDB Services in Kubernetes: any ...
MongoDB
 
MongoDB .local San Francisco 2020: Go on a Data Safari with MongoDB Charts!
MongoDB
 
MongoDB .local San Francisco 2020: From SQL to NoSQL -- Changing Your Mindset
MongoDB
 
MongoDB .local San Francisco 2020: MongoDB Atlas Jumpstart
MongoDB
 
MongoDB .local San Francisco 2020: Tips and Tricks++ for Querying and Indexin...
MongoDB
 
MongoDB .local San Francisco 2020: Aggregation Pipeline Power++
MongoDB
 
MongoDB .local San Francisco 2020: A Complete Methodology of Data Modeling fo...
MongoDB
 
MongoDB .local San Francisco 2020: MongoDB Atlas Data Lake Technical Deep Dive
MongoDB
 
MongoDB .local San Francisco 2020: Developing Alexa Skills with MongoDB & Golang
MongoDB
 
MongoDB .local Paris 2020: Realm : l'ingrédient secret pour de meilleures app...
MongoDB
 
MongoDB .local Paris 2020: Upply @MongoDB : Upply : Quand le Machine Learning...
MongoDB
 

Recently uploaded (20)

PDF
The Rise of AI and IoT in Mobile App Tech.pdf
IMG Global Infotech
 
PPTX
Q2 FY26 Tableau User Group Leader Quarterly Call
lward7
 
PDF
IoT-Powered Industrial Transformation – Smart Manufacturing to Connected Heal...
Rejig Digital
 
PDF
CIFDAQ Token Spotlight for 9th July 2025
CIFDAQ
 
PDF
Blockchain Transactions Explained For Everyone
CIFDAQ
 
PPTX
AUTOMATION AND ROBOTICS IN PHARMA INDUSTRY.pptx
sameeraaabegumm
 
PDF
"AI Transformation: Directions and Challenges", Pavlo Shaternik
Fwdays
 
PDF
Using FME to Develop Self-Service CAD Applications for a Major UK Police Force
Safe Software
 
PDF
Biography of Daniel Podor.pdf
Daniel Podor
 
PDF
NewMind AI - Journal 100 Insights After The 100th Issue
NewMind AI
 
PDF
CIFDAQ Weekly Market Wrap for 11th July 2025
CIFDAQ
 
PPTX
Webinar: Introduction to LF Energy EVerest
DanBrown980551
 
PDF
POV_ Why Enterprises Need to Find Value in ZERO.pdf
darshakparmar
 
PDF
Bitcoin for Millennials podcast with Bram, Power Laws of Bitcoin
Stephen Perrenod
 
PDF
Chris Elwell Woburn, MA - Passionate About IT Innovation
Chris Elwell Woburn, MA
 
PDF
Exolore The Essential AI Tools in 2025.pdf
Srinivasan M
 
PDF
"Beyond English: Navigating the Challenges of Building a Ukrainian-language R...
Fwdays
 
PDF
Fl Studio 24.2.2 Build 4597 Crack for Windows Free Download 2025
faizk77g
 
PDF
DevBcn - Building 10x Organizations Using Modern Productivity Metrics
Justin Reock
 
PDF
July Patch Tuesday
Ivanti
 
The Rise of AI and IoT in Mobile App Tech.pdf
IMG Global Infotech
 
Q2 FY26 Tableau User Group Leader Quarterly Call
lward7
 
IoT-Powered Industrial Transformation – Smart Manufacturing to Connected Heal...
Rejig Digital
 
CIFDAQ Token Spotlight for 9th July 2025
CIFDAQ
 
Blockchain Transactions Explained For Everyone
CIFDAQ
 
AUTOMATION AND ROBOTICS IN PHARMA INDUSTRY.pptx
sameeraaabegumm
 
"AI Transformation: Directions and Challenges", Pavlo Shaternik
Fwdays
 
Using FME to Develop Self-Service CAD Applications for a Major UK Police Force
Safe Software
 
Biography of Daniel Podor.pdf
Daniel Podor
 
NewMind AI - Journal 100 Insights After The 100th Issue
NewMind AI
 
CIFDAQ Weekly Market Wrap for 11th July 2025
CIFDAQ
 
Webinar: Introduction to LF Energy EVerest
DanBrown980551
 
POV_ Why Enterprises Need to Find Value in ZERO.pdf
darshakparmar
 
Bitcoin for Millennials podcast with Bram, Power Laws of Bitcoin
Stephen Perrenod
 
Chris Elwell Woburn, MA - Passionate About IT Innovation
Chris Elwell Woburn, MA
 
Exolore The Essential AI Tools in 2025.pdf
Srinivasan M
 
"Beyond English: Navigating the Challenges of Building a Ukrainian-language R...
Fwdays
 
Fl Studio 24.2.2 Build 4597 Crack for Windows Free Download 2025
faizk77g
 
DevBcn - Building 10x Organizations Using Modern Productivity Metrics
Justin Reock
 
July Patch Tuesday
Ivanti
 

Hacking MongoDB at RelateIQ, A Salesforce Company

  • 1. Title of slide to go here RelateIQ @ MongoSF
  • 2. RelateIQ @ MongoSF Blog blog.relateiq.com RelateIQ Twitter @relateiq { name: “Jón Tómas Grétarsson”, pretty_description: “Early Engineer”, email: “[email protected]”, twitter: @jontomas }
  • 3. 1. MongoDB at RelateIQ 2. Encryption at Rest 3. Golden Horde (Oplog) 4.Q&A Agenda
  • 4. MongoDB usage at RelateIQ Our stack ● Multiple consumers ● Distributed services ● Batch and stream processing We speak JSON ● Cross-language compatibility ● Engineer-debuggable ● Easy to test! MongoDB ● Strong Java support via morphia o Lifecycle methods!
  • 6. At-Rest Encryption @preLoad Called before mapping the datastore object to the entity (POJO); the DBObject is passed as an argument (you can add/remove/change values) You have ● The DBObject ● A class definition (reflection!) You don’t have ● That POJO with all the convenience methods @preSave Called right before DBCollection.save() is called. Changes made to the entity (POJO) will not be persisted; the DBObject can be passed as an argument (you can add/remove/change values) You have ● The original POJO, including class definitions and convenience methods
  • 7. At-Rest Encryption SadPojo.java public class SadPojo { public String clientId; public String secret; }; SadDAO.java public class SadDAO extends BasicDAO<SadPojo> { @Inject public SadDAO(Datastore ds) { super(SadPojo.class, ds); } };
  • 8. At-Rest Encryption Command Line > db.SadPojo.findOne() { "_id": ObjectId("5445dd2b7830e8d4dff439d9"), "clientId": "Dr. No", "secret": "What follows are my evil plans to take over the world..." }
  • 9. SketchyPojo.java public class SketchyPojo { public String clientId; public String secretKey; public String secret; @PreSave public void preSave(DBObject obj) { obj.put(“secret”, encryptWithSecret(secretKey, secret); } @PreLoad public void preLoad(DBObject obj) { try { obj.put(“secret”, decryptWithSecret(obj.get(“secretKey”), obj.get(“secret”)); } catch (EncryptionException e) {} } }; At-Rest Encryption (Take One)
  • 10. At-Rest Encryption (Take One) Command Line > db.SketchyPojo.findOne() { "_id": ObjectId("5445dd2b7830e8d4dff439d9"), "clientId": "Dr. No", "secretKey": "<BASE64-encoded byte string>", "secret": "APu5vPONiaLD4- ykkgG6gG7hlN7reB_XY3rqLGkQ5aBTZBXveUqH_jJwRSjNCMCjrT0rFSe0ZCyrUAxPvjzV idKs5JIbtvwX0SQqGmKf_853a-L_CkoyCRgJfPwzf81XM1dpGR8Kp9hMNAvkrdbco- GdZgE6HENRnXcLzmoYTVhUIhwSCi3rX_8w9_Wn_GVLGI3EF-s- 0r7bqElxn0CB2l4W80sjDTlom_0nbZfwF92Xq9cctnnWghgLYaVEWxL3Va2tQL-BJtybcMiJd- DnxXjHxlRPRB4jtIP8eJMagW7hCh7aDEOC5s0SEiZs5fLRt-dExKgbwxjz" }
  • 11. SketchyPojo.java public class SketchyPojo { public String clientId; public String secretKey; public String secret; @PreSave public void preSave(DBObject obj) { obj.put(“secret”, encryptWithSecret(secretKey, secret); } @PreLoad public void preLoad(DBObject obj) { try { obj.put(“secret”, decryptWithSecret(obj.get(“secretKey”), obj.get(“secret”)); } catch (EncryptionException e) {} } }; At-Rest Encryption (Take One)
  • 12. At-Rest Encryption (Take Two) LessSketchyDAO.java public class LessSketchyDAO extends BasicDAO<LessSketchyPojo> { @Inject public LessSketchyDAO(Datastore ds) { super(LessSketchyPojo.class, ds); } @PreSave public void preSave(LessSketchyPojo pojo, DBObject obj) { obj.put(“secret”, encryptWithSecret(pojo.secretKey, pojo.secret); } @PreLoad public void preLoad(DBObject obj) { try { obj.put(“secret”, decryptWithSecret(obj.get(“secretKey”), obj.get(“secret”)); } catch (EncryptionException e) {} } };
  • 13. At-Rest Encryption (Take Two) Command Line > db.LessSketchyPojo.findOne() { "_id": ObjectId("5445dd2b7830e8d4dff439d9"), "clientId": "Dr. No", "secretKey": "<BASE64-encoded byte string>", "secret": "APu5vPONiaLD4- ykkgG6gG7hlN7reB_XY3rqLGkQ5aBTZBXveUqH_jJwRSjNCMCjrT0rFSe0ZCyrUAxPvjzV idKs5JIbtvwX0SQqGmKf_853a-L_CkoyCRgJfPwzf81XM1dpGR8Kp9hMNAvkrdbco- GdZgE6HENRnXcLzmoYTVhUIhwSCi3rX_8w9_Wn_GVLGI3EF-s- 0r7bqElxn0CB2l4W80sjDTlom_0nbZfwF92Xq9cctnnWghgLYaVEWxL3Va2tQL-BJtybcMiJd- DnxXjHxlRPRB4jtIP8eJMagW7hCh7aDEOC5s0SEiZs5fLRt-dExKgbwxjz" }
  • 14. At-Rest Encryption (Take Two) LessSketchyDAO.java public class LessSketchyDAO extends BasicDAO<LessSketchyPojo> { @Inject public LessSketchyDAO(Datastore ds) { super(LessSketchyPojo.class, ds); } @PreSave public void preSave(LessSketchyPojo pojo, DBObject obj) { obj.put(“secret”, encryptWithSecret(pojo.secretKey, pojo.secret); } @PreLoad public void preLoad(DBObject obj) { try { obj.put(“secret”, decryptWithSecret(obj.get(“secretKey”), obj.get(“secret”)); } catch (EncryptionException e) {} } };
  • 15. At-Rest Encryption (Take Three) HappyPojo.java public class HappyPojo { @EncryptionScope public String clientId; @EncryptAtRest public String secret; };
  • 16. At-Rest Encryption (Take Three) Command Line > db.HappyPojo.findOne() { "_id": ObjectId("5445dd2b7830e8d4dff439d9"), "clientId": "Dr. No", "secret": "APu5vPONiaLD4- ykkgG6gG7hlN7reB_XY3rqLGkQ5aBTZBXveUqH_jJwRSjNCMCjrT0rFSe0ZCyrUAxPvjzVidKs5JIbtvwX0SQqGmK f_853a-L_CkoyCRgJfPwzf81XM1dpGR8Kp9hMNAvkrdbco- GdZgE6HENRnXcLzmoYTVhUIhwSCi3rX_8w9_Wn_GVLGI3EF-s- 0r7bqElxn0CB2l4W80sjDTlom_0nbZfwF92Xq9cctnnWghgLYaVEWxL3Va2tQL-BJtybcMiJd- DnxXjHxlRPRB4jtIP8eJMagW7hCh7aDEOC5s0SEiZs5fLRt-dExKgbwxjz" }
  • 17. At-Rest Encryption (Take Three) Command Line > db.HappyPojo.findOne() { "_id": ObjectId("5445dd2b7830e8d4dff439d9"), "clientId": "Dr. No", "secret": "APu5vPONiaLD4- ykkgG6gG7hlN7reB_XY3rqLGkQ5aBTZBXveUqH_jJwRSjNCMCjrT0rFSe0ZCyrUAxPvjzVidKs5JIbtvwX0SQqGmK f_853a-L_CkoyCRgJfPwzf81XM1dpGR8Kp9hMNAvkrdbco- GdZgE6HENRnXcLzmoYTVhUIhwSCi3rX_8w9_Wn_GVLGI3EF-s- 0r7bqElxn0CB2l4W80sjDTlom_0nbZfwF92Xq9cctnnWghgLYaVEWxL3Va2tQL-BJtybcMiJd- DnxXjHxlRPRB4jtIP8eJMagW7hCh7aDEOC5s0SEiZs5fLRt-dExKgbwxjz" } > db.ScopedKeys.find({_id : "Dr. No"}) { "_id": "Dr. No", "metadata": "{ < some JSON describing a Keyczar DECRYPT_AND_ENCRYPT keyring > }", "secrets": [ "0": "{"aesKeyString": "22mM-utDU_LSzhhwus3cuA","mode":"CBC","size":128}", "1": "{"aesKeyString": "22mM-utDU_LSzhhwus3cuA","mode":"CBC","size":128}" ] }
  • 18. At-Rest Encryption (Take Three) MongoModule.java public class MongoModule extends AbstractModule { @Provides public Morphia providesMorphia(CrypterFactory crypterFactory) { Morphia morphia = new Morphia(); ... morphia.getMapper().addInterceptor( new EncryptAtRestInterceptor(crypterFactory)); return morphia; };
  • 19. Encrypt-At-Rest like the boss Key Takeaways 1. Don’t Repeat Yourself. 2. Morphia’s lifecycle handling is incredibly useful, when used properly. 3. Don’t Repeat Yourself! 4. Encryption is a scary word, but we can make it as natural as annotating a POJO. 5. Use OSS to DRY your code https://github.com/relateiq/EncryptAtRestInterceptor 1. Pull requests appreciated!
  • 21. Golden Horde Lifecycle Methods are Awesome ● So why don’t we use it to ETL changes to the database for analytics and data warehousing? ● Better, how about we transform documents and feed them back into the system!?
  • 22. Golden Horde Lifecycle Methods are Awesome ● So why don’t we use it to ETL changes to the database? Okay… awesome-”ish” ● It only takes one guy with CLI access, or a buggy service.
  • 23. Golden Horde Lifecycle Methods are Awesome ● So why don’t we use it to ETL changes to the database? Okay… awesome-”ish” ● It only takes one guy with CLI access, or a buggy service. Oplog to the rescue! ● We can rely on the same system that Mongo uses internally for tracking and updating repls.
  • 26. Q & A Golden Horde

Editor's Notes

  • #3: Who We Are I’m a DevOps guys these days, and my passion is turning engineering productivity up to 11. Core part of RelateIQ culture is the Hack Day, and I thought I would take this opportunity to talk to you about some of the mongo-specific projects that I’ve had the privilege of working on over the last couple of years.
  • #4: Don’t need to sell MongoDB!
  • #5: Asynchronous deployment cycles for iOS, Android, Web and API requires a common communication A persistent queue like kafka requires that messages be “backwards compatible” to withstand deployments
  • #7: Asynchronous deployment cycles for iOS, Android, Web and API requires a common communication A persistent queue like kafka requires that messages be “backwards compatible” to withstand deployments, and
  • #8: Asynchronous deployment cycles for iOS, Android, Web and API requires a common communication A persistent queue like kafka requires that messages be “backwards compatible” to withstand deployments, and
  • #9: Asynchronous deployment cycles for iOS, Android, Web and API requires a common communication A persistent queue like kafka requires that messages be “backwards compatible” to withstand deployments, and
  • #10: Lots of DRY code, tricky to remember, need to remember the *actual* DBObject key for every encrypted value
  • #11: Lots of DRY code, tricky to remember, need to remember the *actual* DBObject key for every encrypted value
  • #12: Lots of DRY code, tricky to remember, need to remember the *actual* DBObject key for every encrypted value
  • #13: Lots of DRY code, tricky to remember, need to remember the *actual* DBObject key for every encrypted value
  • #14: Lots of DRY code, tricky to remember, need to remember the *actual* DBObject key for every encrypted value
  • #15: Lots of DRY code, tricky to remember, need to remember the *actual* DBObject key for every encrypted value
  • #16: Asynchronous deployment cycles for iOS, Android, Web and API requires a common communication A persistent queue like kafka requires that messages be “backwards compatible” to withstand deployments, and OSS EncryptAtRest
  • #17: Asynchronous deployment cycles for iOS, Android, Web and API requires a common communication A persistent queue like kafka requires that messages be “backwards compatible” to withstand deployments, and OSS EncryptAtRest
  • #18: Asynchronous deployment cycles for iOS, Android, Web and API requires a common communication A persistent queue like kafka requires that messages be “backwards compatible” to withstand deployments, and OSS EncryptAtRest
  • #19: Asynchronous deployment cycles for iOS, Android, Web and API requires a common communication A persistent queue like kafka requires that messages be “backwards compatible” to withstand deployments, and
  • #22: Asynchronous deployment cycles for iOS, Android, Web and API requires a common communication A persistent queue like kafka requires that messages be “backwards compatible” to withstand deployments
  • #23: Asynchronous deployment cycles for iOS, Android, Web and API requires a common communication A persistent queue like kafka requires that messages be “backwards compatible” to withstand deployments
  • #24: Asynchronous deployment cycles for iOS, Android, Web and API requires a common communication A persistent queue like kafka requires that messages be “backwards compatible” to withstand deployments
  • #25: Evolution in thinking-style presentation. Application-level code failed to capture developers changing things from the command line Hack Day —> Iteration One —> Kafka —> Awesome-sauce
  • #26: There were some bumps along the road, but we stuck with it and it was totally worth it. Bumps in the road Document-level locking (finally!) Write-consistency quorum
  • #27: 7 minutes!