-
Notifications
You must be signed in to change notification settings - Fork 89
ENG-2857 Use callable for encryption key #7588
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
Changes from all commits
eaf7142
e484e26
b0a36e0
2270927
eebec4b
007e68e
df7a648
8cadc03
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,4 @@ | ||
| type: Changed | ||
| description: Centralized encryption column definitions behind an encrypted_type() factory with callable key | ||
| pr: 7588 | ||
| labels: [] |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,53 @@ | ||
| from typing import Union | ||
|
|
||
| from loguru import logger | ||
| from sqlalchemy import Text | ||
| from sqlalchemy.types import TypeEngine | ||
| from sqlalchemy_utils.types.encrypted.encrypted_type import ( | ||
| AesGcmEngine, | ||
| StringEncryptedType, | ||
| ) | ||
|
|
||
| from fides.config import CONFIG | ||
|
|
||
| _cached_dek: str | None = None | ||
|
|
||
|
|
||
| def get_encryption_key() -> str: | ||
| """ | ||
| Return the encryption key set in CONFIG.security.app_encryption_key. | ||
| Cached for the lifetime of the process (called on every encrypt/decrypt). | ||
|
|
||
| TODO: implement support for other key managers like AWS KMS | ||
| """ | ||
| global _cached_dek | ||
| if _cached_dek is not None: | ||
| return _cached_dek | ||
|
|
||
| _cached_dek = CONFIG.security.app_encryption_key | ||
| if not _cached_dek: | ||
| logger.warning( | ||
| "App encryption key is empty, this may lead to unexpected issues" | ||
| ) | ||
|
|
||
| return _cached_dek | ||
|
erosselli marked this conversation as resolved.
Comment on lines
+23
to
+33
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Cache is ineffective and warning is skipped when encryption key is None. If
This causes repeated config reads and no warning for a 🔧 Proposed fix using a sentinel value+_NOT_SET = object() # sentinel to distinguish "not cached" from "cached as None"
-_cached_dek: str | None = None
+_cached_dek: str | None | object = _NOT_SET
def get_encryption_key() -> str:
"""
Return the encryption key set in CONFIG.security.app_encryption_key.
Cached for the lifetime of the process (called on every encrypt/decrypt).
TODO: implement support for other key managers like AWS KMS
"""
global _cached_dek
- if _cached_dek is not None:
+ if _cached_dek is not _NOT_SET:
return _cached_dek
_cached_dek = CONFIG.security.app_encryption_key
- if _cached_dek == "":
+ if not _cached_dek: # catches both None and empty string
logger.warning(
"App encryption key is empty, this may lead to unexpected issues"
)
return _cached_dek🤖 Prompt for AI Agents |
||
|
|
||
|
|
||
| def _reset_encryption_key_cache() -> None: | ||
| """Reset the cached encryption key. For testing only.""" | ||
| global _cached_dek | ||
| _cached_dek = None | ||
|
Comment on lines
+13
to
+39
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Don't freeze the encryption key after first use.
🤖 Prompt for AI Agents |
||
|
|
||
|
|
||
| def encrypted_type( | ||
| type_in: Union[type[TypeEngine], TypeEngine, None] = None, | ||
| ) -> StringEncryptedType: | ||
| """Build a StringEncryptedType with a callable key.""" | ||
| if type_in is None: | ||
| type_in = Text() | ||
| return StringEncryptedType( | ||
| type_in=type_in, | ||
| key=get_encryption_key, # callable, NOT called | ||
| engine=AesGcmEngine, | ||
| padding="pkcs5", | ||
| ) | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Everytime I see a TODO (sorry) - I have to ask, do we have this ticketed?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes we do! we have a whole epic for the encryption changes :)