crypto: add managed field, prepare managed JWT cert

Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
This commit is contained in:
Jens Langhammer 2021-10-09 19:14:39 +02:00
parent 0a4343d61b
commit dff0613b3d
7 changed files with 107 additions and 7 deletions

View File

@ -99,6 +99,7 @@ class CertificateKeyPairSerializer(ModelSerializer):
"private_key_available", "private_key_available",
"certificate_download_url", "certificate_download_url",
"private_key_download_url", "private_key_download_url",
"managed",
] ]
extra_kwargs = { extra_kwargs = {
"key_data": {"write_only": True}, "key_data": {"write_only": True},
@ -134,7 +135,7 @@ class CertificateKeyPairFilter(FilterSet):
class Meta: class Meta:
model = CertificateKeyPair model = CertificateKeyPair
fields = ["name"] fields = ["name", "managed"]
class CertificateKeyPairViewSet(UsedByMixin, ModelViewSet): class CertificateKeyPairViewSet(UsedByMixin, ModelViewSet):

View File

@ -1,4 +1,6 @@
"""authentik crypto app config""" """authentik crypto app config"""
from importlib import import_module
from django.apps import AppConfig from django.apps import AppConfig
@ -8,3 +10,6 @@ class AuthentikCryptoConfig(AppConfig):
name = "authentik.crypto" name = "authentik.crypto"
label = "authentik_crypto" label = "authentik_crypto"
verbose_name = "authentik Crypto" verbose_name = "authentik Crypto"
def ready(self):
import_module("authentik.crypto.managed")

View File

@ -24,16 +24,17 @@ class CertificateBuilder:
self.__builder = None self.__builder = None
self.__certificate = None self.__certificate = None
self.common_name = "authentik Self-signed Certificate" self.common_name = "authentik Self-signed Certificate"
self.cert = CertificateKeyPair()
def save(self) -> Optional[CertificateKeyPair]: def save(self) -> Optional[CertificateKeyPair]:
"""Save generated certificate as model""" """Save generated certificate as model"""
if not self.__certificate: if not self.__certificate:
raise ValueError("Certificated hasn't been built yet") raise ValueError("Certificated hasn't been built yet")
return CertificateKeyPair.objects.create( self.cert.name = self.common_name
name=self.common_name, self.cert.certificate_data = self.certificate
certificate_data=self.certificate, self.cert.key_data = self.private_key
key_data=self.private_key, self.cert.save()
) return self.cert
def build( def build(
self, self,

View File

@ -0,0 +1,40 @@
"""Crypto managed objects"""
from datetime import datetime
from typing import Optional
from authentik.crypto.builder import CertificateBuilder
from authentik.crypto.models import CertificateKeyPair
from authentik.managed.manager import ObjectManager
MANAGED_KEY = "goauthentik.io/crypto/jwt-managed"
class CryptoManager(ObjectManager):
"""Crypto managed objects"""
def _create(self, cert: Optional[CertificateKeyPair] = None):
builder = CertificateBuilder()
builder.common_name = "goauthentik.io"
builder.build(
subject_alt_names=["goauthentik.io"],
validity_days=360,
)
if not cert:
cert = CertificateKeyPair()
cert.certificate_data = builder.certificate
cert.key_data = builder.private_key
cert.name = "authentik Internal JWT Certificate"
cert.managed = MANAGED_KEY
cert.save()
def reconcile(self):
certs = CertificateKeyPair.objects.filter(managed=MANAGED_KEY)
if not certs.exists():
self._create()
return []
cert: CertificateKeyPair = certs.first()
now = datetime.now()
if now < cert.certificate.not_valid_before or now > cert.certificate.not_valid_after:
self._create(cert)
return []
return []

View File

@ -0,0 +1,24 @@
# Generated by Django 3.2.8 on 2021-10-09 17:05
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
("authentik_crypto", "0002_create_self_signed_kp"),
]
operations = [
migrations.AddField(
model_name="certificatekeypair",
name="managed",
field=models.TextField(
default=None,
help_text="Objects which are managed by authentik. These objects are created and updated automatically. This is flag only indicates that an object can be overwritten by migrations. You can still modify the objects via the API, but expect changes to be overwritten in a later update.",
null=True,
unique=True,
verbose_name="Managed by authentik",
),
),
]

View File

@ -13,9 +13,10 @@ from django.db import models
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
from authentik.lib.models import CreatedUpdatedModel from authentik.lib.models import CreatedUpdatedModel
from authentik.managed.models import ManagedModel
class CertificateKeyPair(CreatedUpdatedModel): class CertificateKeyPair(ManagedModel, CreatedUpdatedModel):
"""CertificateKeyPair that can be used for signing or encrypting if `key_data` """CertificateKeyPair that can be used for signing or encrypting if `key_data`
is set, otherwise it can be used to verify remote data.""" is set, otherwise it can be used to verify remote data."""

View File

@ -3087,6 +3087,10 @@ paths:
schema: schema:
type: boolean type: boolean
description: Only return certificate-key pairs with keys description: Only return certificate-key pairs with keys
- in: query
name: managed
schema:
type: string
- in: query - in: query
name: name name: name
schema: schema:
@ -19174,6 +19178,14 @@ components:
private_key_download_url: private_key_download_url:
type: string type: string
readOnly: true readOnly: true
managed:
type: string
nullable: true
title: Managed by authentik
description: Objects which are managed by authentik. These objects are created
and updated automatically. This is flag only indicates that an object
can be overwritten by migrations. You can still modify the objects via
the API, but expect changes to be overwritten in a later update.
required: required:
- cert_expiry - cert_expiry
- cert_subject - cert_subject
@ -19199,6 +19211,14 @@ components:
writeOnly: true writeOnly: true
description: Optional Private Key. If this is set, you can use this keypair description: Optional Private Key. If this is set, you can use this keypair
for encryption. for encryption.
managed:
type: string
nullable: true
title: Managed by authentik
description: Objects which are managed by authentik. These objects are created
and updated automatically. This is flag only indicates that an object
can be overwritten by migrations. You can still modify the objects via
the API, but expect changes to be overwritten in a later update.
required: required:
- certificate_data - certificate_data
- name - name
@ -25310,6 +25330,14 @@ components:
writeOnly: true writeOnly: true
description: Optional Private Key. If this is set, you can use this keypair description: Optional Private Key. If this is set, you can use this keypair
for encryption. for encryption.
managed:
type: string
nullable: true
title: Managed by authentik
description: Objects which are managed by authentik. These objects are created
and updated automatically. This is flag only indicates that an object
can be overwritten by migrations. You can still modify the objects via
the API, but expect changes to be overwritten in a later update.
PatchedConsentStageRequest: PatchedConsentStageRequest:
type: object type: object
description: ConsentStage Serializer description: ConsentStage Serializer