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

Database keystore #3

Open
wants to merge 10 commits into
base: main
Choose a base branch
from
Open

Database keystore #3

wants to merge 10 commits into from

Conversation

whs
Copy link

@whs whs commented Jun 12, 2022

This PR implements envelope encryption by adding model to store Keysets. This PR build on top of #2.

  • In configuration, db_key is added to point to keyset stored using the provided model.
  • Keys are stored in binary protobuf format, encrypted with EncryptedBinaryField which use the db_keyset named encryption keyset configuration.
    • Unfortunately due to how EncryptedField is implemented, I don't think it is possible to make keyset name user configurable.
    • In my use case I plan to point the default encryption key to cloud provider's KMS. One of the design goal here is to try as much as possible to only decrypt each stored key once to reduce costly call to KMS API.
  • Internal API is refactored to no longer use tink.KeysetHandle, instead using primitives directly. KeysetHandle is heavily opinionated in safe key handling in file-based formats (eg. there is no public API to save plaintext key material at all)
  • The database-backed keysets are represented to Tink as tink.core.PrimitiveSet instances. This allow for key versions to be lazily-loaded, reducing KMS API calls.
  • Since we now no longer use Keyset API, management via Tinkey CLI is no longer possible. Instead, a new manage.py tink management command is added. It contains
    • python manage.py tink create-keyset keyset-name AES256_GCM - Create keyset and a default key from key template (only aead/daead supported) (tinkey create-keyset --in keyset.json --key-template AES256_GCM)
    • python manage.py tink add-key keyset-name AES256_GCM - Create new key in keyset (tinkey add-key --in keyset.json --key-template AES256_GCM)
    • python manage.py tink promote-key keyset-name key-id - Promote key in keyset (tinkey promote-key --in keyset.json --key-id key-id)
    • python manage.py tink list-keyset keyset-name - List keys in keyset (tinkey list-keyset --in keyset.json)
    • python manage.py tink delete-keyset keyset-name - Delete keyset and associated keys
    • python manage.py tink unsafe-export-keyset keyset-name - Export keyset to Tinkey-compatible format (will include key material!)
    • Note that key_id is also database primary key, so I didn't implement import from tinkey operation as ID may collide.

Other non blocking improvements (not sure if I will implement, the PR is already feature complete as-is)

  • Import from Keyset JSON/PB

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

1 participant