Skip to content

Commit

Permalink
crypto: fix race conditions when creating self-signed certificates on…
Browse files Browse the repository at this point in the history
… startup (#7344)

Signed-off-by: Jens Langhammer <jens@goauthentik.io>
  • Loading branch information
BeryJu authored Oct 27, 2023
1 parent 15d7175 commit ad9f500
Showing 1 changed file with 26 additions and 19 deletions.
45 changes: 26 additions & 19 deletions authentik/crypto/apps.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,10 @@
"""authentik crypto app config"""
from datetime import datetime
from typing import TYPE_CHECKING, Optional
from typing import Optional

from authentik.blueprints.apps import ManagedAppConfig
from authentik.lib.generators import generate_id

if TYPE_CHECKING:
from authentik.crypto.models import CertificateKeyPair

MANAGED_KEY = "goauthentik.io/crypto/jwt-managed"


Expand All @@ -23,33 +20,37 @@ def reconcile_load_crypto_tasks(self):
"""Load crypto tasks"""
self.import_module("authentik.crypto.tasks")

def _create_update_cert(self, cert: Optional["CertificateKeyPair"] = None):
def _create_update_cert(self):
from authentik.crypto.builder import CertificateBuilder
from authentik.crypto.models import CertificateKeyPair

builder = CertificateBuilder("authentik Internal JWT Certificate")
common_name = "authentik Internal JWT Certificate"
builder = CertificateBuilder(common_name)
builder.build(
subject_alt_names=["goauthentik.io"],
validity_days=360,
)
if not cert:
cert = CertificateKeyPair()
builder.cert = cert
builder.cert.managed = MANAGED_KEY
builder.save()
CertificateKeyPair.objects.update_or_create(
managed=MANAGED_KEY,
defaults={
"name": common_name,
"certificate_data": builder.certificate,
"key_data": builder.private_key,
},
)

def reconcile_managed_jwt_cert(self):
"""Ensure managed JWT certificate"""
from authentik.crypto.models import CertificateKeyPair

certs = CertificateKeyPair.objects.filter(managed=MANAGED_KEY)
if not certs.exists():
self._create_update_cert()
return
cert: CertificateKeyPair = certs.first()
cert: Optional[CertificateKeyPair] = CertificateKeyPair.objects.filter(
managed=MANAGED_KEY
).first()
now = datetime.now()
if now < cert.certificate.not_valid_before or now > cert.certificate.not_valid_after:
self._create_update_cert(cert)
if not cert or (
now < cert.certificate.not_valid_before or now > cert.certificate.not_valid_after
):
self._create_update_cert()

def reconcile_self_signed(self):
"""Create self-signed keypair"""
Expand All @@ -61,4 +62,10 @@ def reconcile_self_signed(self):
return
builder = CertificateBuilder(name)
builder.build(subject_alt_names=[f"{generate_id()}.self-signed.goauthentik.io"])
builder.save()
CertificateKeyPair.objects.get_or_create(
name=name,
defaults={
"certificate_data": builder.certificate,
"key_data": builder.private_key,
},
)

0 comments on commit ad9f500

Please sign in to comment.