Key backends¶
django-ca allows you to store private keys of certificate authorities as files (on the file system or any other system supported via the Django file storage API) or in a hardware security module (HSM) using the #PKCS 11 protocol.
You can even write your own backend for storing private keys to handle private keys in more unique ways, see writing custom backends for more information.
Default configuration¶
The default configuration is to store private keys on the file system. This works on any system, but is not the most secure method possible.
# The "django-ca" storage alias is mandatory. Added by default in full project
# setups (from source, or with Docker or Docker Compose), but must be set if
# used as Django app. In full project setups, you can also just set CA_DIR to
# change the storage directory.
STORAGES = {
"default": {
"BACKEND": "django.core.files.storage.FileSystemStorage",
},
"staticfiles": {
"BACKEND": "django.contrib.staticfiles.storage.StaticFilesStorage",
},
"django-ca": {
"BACKEND": "django.core.files.storage.FileSystemStorage",
"OPTIONS": {
"location": "files/",
"file_permissions_mode": 0o600,
"directory_permissions_mode": 0o700,
},
},
}
CA_KEY_BACKENDS = {
"default": {
"BACKEND": "django_ca.key_backends.storages.StoragesBackend",
"OPTIONS": {"storage_alias": "django-ca"},
}
}
# The "django-ca" storage alias is mandatory. Added by default in full project
# setups (from source, or with Docker or Docker Compose), but must be set if
# used as Django app. In full project setups, you can also just set CA_DIR to
# change the storage directory.
STORAGES:
default:
BACKEND: django.core.files.storage.FileSystemStorage
staticfiles:
BACKEND: django.contrib.staticfiles.storage.StaticFilesStorage
django-ca:
BACKEND: django.core.files.storage.FileSystemStorage
OPTIONS:
directory_permissions_mode: 0700
file_permissions_mode: 0600
location: files/
CA_KEY_BACKENDS:
default:
BACKEND: django_ca.key_backends.storages.StoragesBackend
OPTIONS:
storage_alias: django-ca
Multiple backends¶
You can configure multiple backends using the CA_KEY_BACKENDS setting. For example, if you want to be able to store private keys on the file system, but also in a hardware security module (HSM):
STORAGES = { # type: ignore[var-annotated]
# ... see default configuration
}
CA_KEY_BACKENDS = {
"default": {
"BACKEND": "django_ca.key_backends.storages.StoragesBackend",
"OPTIONS": {"storage_alias": "django-ca"},
},
"hsm": {
"BACKEND": "django_ca.key_backends.hsm.HSMBackend",
"OPTIONS": {
"library_path": "/usr/lib/softhsm/libsofthsm2.so",
"token": "my_token_label",
"user_pin": "secret_user_pin",
},
},
}
STORAGES:
# ... see default configuration
CA_KEY_BACKENDS:
default:
BACKEND: django_ca.key_backends.storages.StoragesBackend
OPTIONS:
storage_alias: django-ca
hsm:
BACKEND: django_ca.key_backends.hsm.HSMBackend
OPTIONS:
library_path: /usr/lib/softhsm/libsofthsm2.so
token: my_token_label
user_pin: secret_user_pin
Command-line options added by any backend that is not named “default” will be prefixed with the name of the
backend. In the above example, you can use the --password option normally (which is added by the default
backend), but you must use --hsm-user-pin etc. when using the HSM key backend:
user@host:~$ python manage.py init_ca --password=mypassword CAInDefaultKeyBackend CN=Default
user@host:~$ python manage.py init_ca --key-backend=hsm \
> --hsm-key-label=my_key_label --hsm-user-pin=1234 \
> CAInHSM CN=HSM
If you run any command with --help, you’ll see all currently valid options.
Supported backends¶
Storages backend¶
The most common use case for this key backend is to store keys on the local file system. However, you can use any custom Django storage system, for example from django-storages.
This backend takes a single option, storage_alias. It defines the storage system (as defined in
STORAGES) to use.
The default configuration is a good example:
# The "django-ca" storage alias is mandatory. Added by default in full project
# setups (from source, or with Docker or Docker Compose), but must be set if
# used as Django app. In full project setups, you can also just set CA_DIR to
# change the storage directory.
STORAGES = {
"default": {
"BACKEND": "django.core.files.storage.FileSystemStorage",
},
"staticfiles": {
"BACKEND": "django.contrib.staticfiles.storage.StaticFilesStorage",
},
"django-ca": {
"BACKEND": "django.core.files.storage.FileSystemStorage",
"OPTIONS": {
"location": "files/",
"file_permissions_mode": 0o600,
"directory_permissions_mode": 0o700,
},
},
}
CA_KEY_BACKENDS = {
"default": {
"BACKEND": "django_ca.key_backends.storages.StoragesBackend",
"OPTIONS": {"storage_alias": "django-ca"},
}
}
# The "django-ca" storage alias is mandatory. Added by default in full project
# setups (from source, or with Docker or Docker Compose), but must be set if
# used as Django app. In full project setups, you can also just set CA_DIR to
# change the storage directory.
STORAGES:
default:
BACKEND: django.core.files.storage.FileSystemStorage
staticfiles:
BACKEND: django.contrib.staticfiles.storage.StaticFilesStorage
django-ca:
BACKEND: django.core.files.storage.FileSystemStorage
OPTIONS:
directory_permissions_mode: 0700
file_permissions_mode: 0600
location: files/
CA_KEY_BACKENDS:
default:
BACKEND: django_ca.key_backends.storages.StoragesBackend
OPTIONS:
storage_alias: django-ca
HSM (Hardware Security Module) backend¶
The HSM backend provides the ability to store private keys in a Hardware Security Module (HSM) via the PKCS 11 protocol and python-pkcs11.
When using Docker or docker-compose, you need to make sure that the PKCS 11 library as well as the hardware device is available in the Docker container.
When using django-ca as a Django app or if you installed from source, you have to install django-ca with the hsm extra, e.g.
user@host:~$ pip install django-ca[hsm]
This backend has several mandatory options:
library_path specifies the path to the PKCS11 library (e.g.
/usr/lib/softhsm/libsofthsm2.sofor SoftHSM2 on Debian/Ubuntu).token to specify the token to use.
Either an so_pin or user_pin (can be overwritten on the command-line).
For example:
CA_KEY_BACKENDS = {
"default": {
"BACKEND": "django_ca.key_backends.hsm.HSMBackend",
"OPTIONS": {
"library_path": "/usr/lib/softhsm/libsofthsm2.so",
"token": "my_token_label",
"user_pin": "secret_user_pin",
},
},
}
CA_KEY_BACKENDS:
default:
BACKEND: django_ca.key_backends.hsm.HSMBackend
OPTIONS:
library_path: /usr/lib/softhsm/libsofthsm2.so
token: my_token_label
user_pin: secret_user_pin
Usage via the command-line¶
Assuming the HSM backend is the default backend, you can create a certificate authority and sign a certificate like this:
user@host:~$ python manage.py init_ca --key-label=my-key-label --user-pin=1234 CAInHSM CN=ca.example.com
user@host:~$ python manage.py sign_cert --ca=... --alt=example.com
If the HSM backend is not the default backend but uses the name "hsm", you have to explicitly name the key
backend and prefix options accordingly:
user@host:~$ python manage.py init_ca \
> --key-backend=hsm --hsm-key-label=my-key-label --hsm-user-pin=1234 \
> CAInHSM CN=ca.example.com
user@host:~$ python manage.py sign_cert --ca=... --alt=example.com
HSM pin handling¶
Any operation must either use an SO pin or a user pin. The configuration in CA_KEY_BACKENDS should
provide the pin required for signing operations, usually the user pin.
If creating a new certificate authority requires an SO pin instead, you can specify it on the command line. However, you must also disable the user pin in this case. For example (assuming the HSM backend is your default backend):
user@host:~$ python manage.py init_ca --so-pin=1234 --user-pin="" ...