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",
"certificate_download_url",
"private_key_download_url",
"managed",
]
extra_kwargs = {
"key_data": {"write_only": True},
@ -134,7 +135,7 @@ class CertificateKeyPairFilter(FilterSet):
class Meta:
model = CertificateKeyPair
fields = ["name"]
fields = ["name", "managed"]
class CertificateKeyPairViewSet(UsedByMixin, ModelViewSet):

View file

@ -1,4 +1,6 @@
"""authentik crypto app config"""
from importlib import import_module
from django.apps import AppConfig
@ -8,3 +10,6 @@ class AuthentikCryptoConfig(AppConfig):
name = "authentik.crypto"
label = "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.__certificate = None
self.common_name = "authentik Self-signed Certificate"
self.cert = CertificateKeyPair()
def save(self) -> Optional[CertificateKeyPair]:
"""Save generated certificate as model"""
if not self.__certificate:
raise ValueError("Certificated hasn't been built yet")
return CertificateKeyPair.objects.create(
name=self.common_name,
certificate_data=self.certificate,
key_data=self.private_key,
)
self.cert.name = self.common_name
self.cert.certificate_data = self.certificate
self.cert.key_data = self.private_key
self.cert.save()
return self.cert
def build(
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 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`
is set, otherwise it can be used to verify remote data."""

View file

@ -3087,6 +3087,10 @@ paths:
schema:
type: boolean
description: Only return certificate-key pairs with keys
- in: query
name: managed
schema:
type: string
- in: query
name: name
schema:
@ -19174,6 +19178,14 @@ components:
private_key_download_url:
type: string
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:
- cert_expiry
- cert_subject
@ -19199,6 +19211,14 @@ components:
writeOnly: true
description: Optional Private Key. If this is set, you can use this keypair
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:
- certificate_data
- name
@ -25310,6 +25330,14 @@ components:
writeOnly: true
description: Optional Private Key. If this is set, you can use this keypair
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:
type: object
description: ConsentStage Serializer