Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Doc encryption with symmetric key #2731

Merged

Conversation

islamaliev
Copy link
Contributor

@islamaliev islamaliev commented Jun 17, 2024

Relevant issue(s)

Resolves #2711 #2808

Description

This change introduces doc encryption. Upon creation of a document the user can pass the encryption flag which will signal to db to create a new symmetric key using AES-GCM and will store it locally.
With the encryption flag all doc fields (deltas) being stored in the DAG encrypted. The datastore will still store data as plain text, as for it's encryption we can use encryption-at-rest.
Decryption is not used at the moment, as it is relevant only p2p environment and we don't have yet key exchange mechanism. All peers sync encrypted data.

This PR also adds 2 new parameters to GraphQL create_ mutation:

  1. inputs: a list of documents to be created
  2. encrypt: flag that indicates if document(s) need to be encrypted.

@islamaliev islamaliev self-assigned this Jun 17, 2024
@islamaliev islamaliev added security Related to security area/datastore Related to the datastore / storage engine system area/collections Related to the collections system labels Jun 17, 2024
@islamaliev islamaliev added this to the DefraDB v0.12 milestone Jun 17, 2024
cli/collection_create.go Outdated Show resolved Hide resolved
internal/db/db.go Outdated Show resolved Hide resolved
Copy link
Collaborator

@fredcarle fredcarle left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall I think you're going in the right direction. I have 2 main critiques at this stage. The first, as mentioned in an other comment, is the passing of a key on document create. I think we should avoid doing this and let Defra create a new key when needed. The second is the use of the context for the encryption key and store. It feels like it's making it more complex than it needs to be. We can discuss it some more in the standup or in a separate call if you want.

@islamaliev islamaliev force-pushed the feat/simple-doc-encryption branch 2 times, most recently from 49fa643 to 045d85a Compare June 24, 2024 10:27
Copy link

codecov bot commented Jun 24, 2024

Codecov Report

Attention: Patch coverage is 76.28032% with 88 lines in your changes missing coverage. Please review.

Project coverage is 78.69%. Comparing base (ea77dc2) to head (8bc56c7).

Additional details and impacted files

Impacted file tree graph

@@             Coverage Diff             @@
##           develop    #2731      +/-   ##
===========================================
- Coverage    78.99%   78.69%   -0.30%     
===========================================
  Files          315      318       +3     
  Lines        23873    24128     +255     
===========================================
+ Hits         18858    18987     +129     
- Misses        3649     3772     +123     
- Partials      1366     1369       +3     
Flag Coverage Δ
all-tests 78.69% <76.28%> (-0.30%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files Coverage Δ
client/document.go 70.50% <ø> (-1.30%) ⬇️
client/request/mutation.go 100.00% <ø> (ø)
datastore/multi.go 92.00% <100.00%> (+1.09%) ⬆️
http/client.go 55.97% <100.00%> (+0.18%) ⬆️
internal/core/block/block.go 90.65% <100.00%> (-0.57%) ⬇️
internal/db/collection.go 72.02% <100.00%> (-0.41%) ⬇️
internal/db/context.go 100.00% <100.00%> (ø)
internal/db/fetcher/fetcher.go 79.18% <100.00%> (-0.63%) ⬇️
internal/db/fetcher/versioned.go 68.46% <100.00%> (ø)
internal/encryption/context.go 100.00% <100.00%> (ø)
... and 24 more

... and 12 files with indirect coverage changes


Continue to review full report in Codecov by Sentry.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update ea77dc2...8bc56c7. Read the comment docs.

@islamaliev islamaliev marked this pull request as ready for review June 25, 2024 13:34
@islamaliev islamaliev force-pushed the feat/simple-doc-encryption branch 4 times, most recently from a21c890 to fd6893b Compare July 1, 2024 05:17
Copy link
Member

@nasdf nasdf left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good! Just a few small things to clear up.

http/client_collection.go Outdated Show resolved Hide resolved
http/handler_collection.go Outdated Show resolved Hide resolved
http/client.go Outdated Show resolved Hide resolved
cli/collection_create.go Show resolved Hide resolved
@islamaliev islamaliev requested a review from nasdf July 2, 2024 08:00
client/document.go Outdated Show resolved Hide resolved
Copy link
Contributor

@AndrewSisley AndrewSisley left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Part way through my review but need to get some food - looks good so far :)

tests/integration/encryption/utils.go Show resolved Hide resolved
tests/integration/utils2.go Outdated Show resolved Hide resolved
tests/integration/utils2.go Outdated Show resolved Hide resolved
tests/integration/utils2.go Outdated Show resolved Hide resolved
tests/integration/utils2.go Outdated Show resolved Hide resolved
internal/planner/create.go Outdated Show resolved Hide resolved
cli/collection_create.go Show resolved Hide resolved
tests/integration/encryption/query_test.go Outdated Show resolved Hide resolved
tests/integration/encryption/peer_test.go Show resolved Hide resolved
tests/integration/encryption/commit_test.go Outdated Show resolved Hide resolved
Copy link
Contributor

@AndrewSisley AndrewSisley left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks really good, just a handful of smaller comments for you before merge :)

if len(n.docs) == 1 {
err = n.collection.Create(n.p.ctx, n.docs[0])
} else {
err = n.collection.CreateMany(n.p.ctx, n.docs)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

todo: I do disagree with creating docs in Start - it feels like it is very much in the wrong place and may trip us up in the future (if not by being technically annoying for some future change, it seems likely to cause 'surprise').

Please either move this call into Next, or discuss in in discord/standup (for greater visibility).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I understand your concern. I had similar feelings but thought it was highly unlikely and having a nicer code was worth it. If you think otherwise, I will move it to Next. No problem.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks Islam, sorry about the bother, and I understand it is a bit 'abstract' in this case, but I do think it is in the wrong place atm. Ideally we would remove the Start/Init funcs anyway, and conceptually I very much think the 'creating' part of a 'create' iterator should be done in the iteration funcs (next/value).

@@ -103,6 +103,8 @@ type Block struct {
Delta crdt.CRDT
// Links are the links to other blocks in the DAG.
Links []DAGLink
// IsEncrypted is a flag that indicates if the block's delta is encrypted.
IsEncrypted *bool
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

todo: Please don't use a pointer for a boolean, it feels very wasteful and confusing - suggesting that it's pointerness may be used for odd mutation reasons. If you want it to be optional, please use immutable.Option instead, it is much cheaper, less confusing, and wont contribute to GC pressure.

If you have a very specific reason for using a pointer here, please document it.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

documented

datastore/store.go Show resolved Hide resolved
Copy link
Contributor

@AndrewSisley AndrewSisley left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM Islam :) And thanks for the random little cleanups you made along the way :)

@islamaliev islamaliev merged commit 24fa14f into sourcenetwork:develop Jul 4, 2024
39 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area/collections Related to the collections system area/datastore Related to the datastore / storage engine system security Related to security
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Doc. Encryption: Enable doc encryption with symmetric keys
5 participants