crypto: fix race conditions when creating self-signed certificates on startup (#7344)
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
This commit is contained in:
parent
15d7175750
commit
ad9f500ad1
|
@ -1,13 +1,10 @@
|
||||||
"""authentik crypto app config"""
|
"""authentik crypto app config"""
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from typing import TYPE_CHECKING, Optional
|
from typing import Optional
|
||||||
|
|
||||||
from authentik.blueprints.apps import ManagedAppConfig
|
from authentik.blueprints.apps import ManagedAppConfig
|
||||||
from authentik.lib.generators import generate_id
|
from authentik.lib.generators import generate_id
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
|
||||||
from authentik.crypto.models import CertificateKeyPair
|
|
||||||
|
|
||||||
MANAGED_KEY = "goauthentik.io/crypto/jwt-managed"
|
MANAGED_KEY = "goauthentik.io/crypto/jwt-managed"
|
||||||
|
|
||||||
|
|
||||||
|
@ -23,33 +20,37 @@ class AuthentikCryptoConfig(ManagedAppConfig):
|
||||||
"""Load crypto tasks"""
|
"""Load crypto tasks"""
|
||||||
self.import_module("authentik.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.builder import CertificateBuilder
|
||||||
from authentik.crypto.models import CertificateKeyPair
|
from authentik.crypto.models import CertificateKeyPair
|
||||||
|
|
||||||
builder = CertificateBuilder("authentik Internal JWT Certificate")
|
common_name = "authentik Internal JWT Certificate"
|
||||||
|
builder = CertificateBuilder(common_name)
|
||||||
builder.build(
|
builder.build(
|
||||||
subject_alt_names=["goauthentik.io"],
|
subject_alt_names=["goauthentik.io"],
|
||||||
validity_days=360,
|
validity_days=360,
|
||||||
)
|
)
|
||||||
if not cert:
|
CertificateKeyPair.objects.update_or_create(
|
||||||
cert = CertificateKeyPair()
|
managed=MANAGED_KEY,
|
||||||
builder.cert = cert
|
defaults={
|
||||||
builder.cert.managed = MANAGED_KEY
|
"name": common_name,
|
||||||
builder.save()
|
"certificate_data": builder.certificate,
|
||||||
|
"key_data": builder.private_key,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
def reconcile_managed_jwt_cert(self):
|
def reconcile_managed_jwt_cert(self):
|
||||||
"""Ensure managed JWT certificate"""
|
"""Ensure managed JWT certificate"""
|
||||||
from authentik.crypto.models import CertificateKeyPair
|
from authentik.crypto.models import CertificateKeyPair
|
||||||
|
|
||||||
certs = CertificateKeyPair.objects.filter(managed=MANAGED_KEY)
|
cert: Optional[CertificateKeyPair] = CertificateKeyPair.objects.filter(
|
||||||
if not certs.exists():
|
managed=MANAGED_KEY
|
||||||
self._create_update_cert()
|
).first()
|
||||||
return
|
|
||||||
cert: CertificateKeyPair = certs.first()
|
|
||||||
now = datetime.now()
|
now = datetime.now()
|
||||||
if now < cert.certificate.not_valid_before or now > cert.certificate.not_valid_after:
|
if not cert or (
|
||||||
self._create_update_cert(cert)
|
now < cert.certificate.not_valid_before or now > cert.certificate.not_valid_after
|
||||||
|
):
|
||||||
|
self._create_update_cert()
|
||||||
|
|
||||||
def reconcile_self_signed(self):
|
def reconcile_self_signed(self):
|
||||||
"""Create self-signed keypair"""
|
"""Create self-signed keypair"""
|
||||||
|
@ -61,4 +62,10 @@ class AuthentikCryptoConfig(ManagedAppConfig):
|
||||||
return
|
return
|
||||||
builder = CertificateBuilder(name)
|
builder = CertificateBuilder(name)
|
||||||
builder.build(subject_alt_names=[f"{generate_id()}.self-signed.goauthentik.io"])
|
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,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
Reference in a new issue