Django caching plugin for django-redis that adds a Serializer class and configuration to support transparent,
symmetrical encryption of cached values using the python cryptography library.
This plugin also provides encryption for django-rq jobs by simply using the @secure_redis.secure_rq.job
decorator to annotate the task method instead of using @django_rq.job
Before using this library, make sure that you really need it. By using it, put in mind:
- You are loosing atomic functionalities like
incr()
- The values stored to redis are now bigger
- Will take more time to set and retrieve data from redis
- Use
pip install
to get this library - In
settings.py
in your project, go toCACHE
settings and ensure you put the following:
- Add
secure_redis
toINSTALLED_APPS
- Provide
REDIS_SECRET_KEY
to be used in the encryption - Configure the
SERIALIZER
setting to usesecure_redis.serializer.SecureSerializer
CACHES = {
'default': {
'BACKEND': 'django_redis.cache.RedisCache',
'LOCATION': REDIS_URL,
'OPTIONS': {
# "SOCKET_CONNECT_TIMEOUT": 5, # in seconds
'DB': REDIS_DB,
'PARSER_CLASS': 'redis.connection.HiredisParser',
'REDIS_SECRET_KEY': 'kPEDO_pSrPh3qGJVfGAflLZXKAh4AuHU64tTlP-f_PY=',
'SERIALIZER': 'secure_redis.serializer.SecureSerializer',
},
'KEY_PREFIX': 'app1:secure',
'TIMEOUT': 60 * 60 * 24, # 1 day
},
'insecure': {
'BACKEND': 'django_redis.cache.RedisCache',
'LOCATION': REDIS_URL,
'OPTIONS': {
# "SOCKET_CONNECT_TIMEOUT": 5, # in seconds
'DB': REDIS_DB,
'PARSER_CLASS': 'redis.connection.HiredisParser',
},
'KEY_PREFIX': 'app1',
'TIMEOUT': 60 * 60 * 24, # 1 day
},
}
If you already have an existing data in your redis, you might need to consider data migration for un-encrypted values, you are free to handle this case as you want, we would suggest to use django management command to handle this case:
- Keep old redis cache settings and add your new secure django redis cache configuration
- Make sure your new secure django redis cache settings has different
KEY_PREFIX
- Make sure old configutation still point at the correct
REDIS_URL
andREDIS_DB
- You can see an example configuration in the previous section of
Settings sample
- Make sure either to delete old keys or make sure your redis can holds the new values
- Code sinppet for sample command is shown below:
from __future__ import unicode_literals
from django.core.management.base import BaseCommand
from django.core import cache
class Command(BaseCommand):
def handle(self, *args, **options):
new_cache_name = 'default'
old_cache_name = 'insecure'
old_key_prefix = 'app1'
new_prefix = 'app1:secure'
delete_old_keys = False
old_cache = cache.caches[old_cache_name]
new_cache = cache.caches[new_cache_name]
# Use low level api to access full key name
existing_keys = old_cache.client.get_client().keys('{}*'.format(old_key_prefix))
for key in existing_keys:
if new_prefix not in key:
actual_key = old_cache.client.reverse_key(key)
unencrypted_val = old_cache.get(actual_key)
if new_cache.set(actual_key, unencrypted_val):
if delete_old_keys:
old_cache.delete(actual_key)
This library also provides additional functionality for that encrypts the payload of RQ jobs. To make use of this functionality, first ensure that DJANGO_REDIS_SECURE_CACHE_NAME
is defined in your settings (if not set, this setting will default to using the default
cache). Once configured, replace all instances of the django_rq.job
decorator with @secure_redis.secure_rq.job
. The @secure_redis.secure_rq.job
provides the following functionality:
- A
delay
method, which can be used when calling the task method (ex:my_task.delay()
). This method has the same functionality asdjango_rq.job.delay
- An
enqueue_at
method, which can be used when calling the task method (ex:my_job.enqueue_at()
). This method has the same functionality asdjango_rq.Scheduler.enqueue_at
- A
schedule_once
method, which can be used when calling the task method (ex:my_job.schedule_once()
). This method has the same functionality asdjango_rq.Scheduler.schedule
, but will check if the method already exists and will not add it to the scheduler a second time.
When using the @secure_redis.secure_rq.job decorator
, the method name displayed in the Django admin will be that of the wrapped proxy method instead of the actual task method name. If you want to see the actual task method name in the Django admin, you must use secure_redis.urls
instead of django_rq.urls
when installing RQ into the Django admin in your urls.py
file.