Is your feature request related to a problem? Please describe.
Currently, assigning a template with type="cert" to a device has no backend effect. I need to implement the automated, synchronous lifecycle that generates, renews, and securely revokes standalone X.509 certificates based on template assignment. Without this core engine, the certificate templates cannot interact with physical devices.
Describe the solution you'd like
I will implement the logic governing the certificate lifecycle, mirroring the proven VpnClient pattern:
-
Relational Database Modeling: create a DeviceCertificate intermediate Many-To-Many (M2M) model.
- Fields:
config (ForeignKey), template (ForeignKey), cert (OneToOneField), and auto_cert (BooleanField).
- Enforce a unique_together constraint on
(config, template).
-
Synchronous Generation (post_add): bind a manage_device_certs handler to the m2m_changed signal of the Config.templates.through model. When a cert template is assigned:
- Check if a
blueprint_cert exists.
- If a blueprint exists, copy the non-unique properties listed in the proposal: organization, key length, digest, subject fields, and base extensions.
- If no blueprint is specified, fall back to the CA defaults.
- Set the device hostname as the Common Name (CN).
- Inject the device MAC address and UUID as custom private OIDs.
- Call
cert.full_clean() and cert.save() to synchronously auto-generate the certificate.
-
Secure Revocation (post_remove): when unassigned, the post_delete signal handler on DeviceCertificate must explicitly revoke the underlying certificate, adding it to the CRL via cert.revoke(), before object cleanup. This invalidates any local copies retained by the device.
-
Automated Renewal: when a standalone cert is renewed via the existing PKI API, it will automatically trigger the device configuration update path.
Config status updates from the proposal
- Extend the existing
certificate_updated handler so it can resolve the affected config through DeviceCertificate in addition to VpnClient.
- Use
transaction.on_commit where this follows the existing certificate update path.
- Use
config.update_status_if_checksum_changed() for certificate generation and renewal so configs are marked modified only when the rendered configuration actually changes.
Blueprint safety validation
The proposal also states that DeviceCertificate.clean() should prevent a certificate referenced as a blueprint_cert by any template from being assigned directly to a device.
Tests from the GSoC proposal
- Certificate generation from a template with and without a blueprint certificate.
- Blueprint property cloning for key length, digest, subject fields, and extensions.
- Fallback to CA defaults when no blueprint is specified.
- Device property injection: hostname as CN, MAC address and UUID as private OIDs.
DeviceCertificate creation on template assignment.
- Certificate revocation and deletion on template unassignment.
- Certificate renewal triggering config status update.
Measurable outcomes: 4, 6
Implementation points: 2, 3
Related issue: #1377 tracks the DeviceCertificate model details.
Is your feature request related to a problem? Please describe.
Currently, assigning a template with
type="cert"to a device has no backend effect. I need to implement the automated, synchronous lifecycle that generates, renews, and securely revokes standalone X.509 certificates based on template assignment. Without this core engine, the certificate templates cannot interact with physical devices.Describe the solution you'd like
I will implement the logic governing the certificate lifecycle, mirroring the proven
VpnClientpattern:Relational Database Modeling: create a
DeviceCertificateintermediate Many-To-Many (M2M) model.config(ForeignKey),template(ForeignKey),cert(OneToOneField), andauto_cert(BooleanField).(config, template).Synchronous Generation (
post_add): bind amanage_device_certshandler to them2m_changedsignal of theConfig.templates.throughmodel. When a cert template is assigned:blueprint_certexists.cert.full_clean()andcert.save()to synchronously auto-generate the certificate.Secure Revocation (
post_remove): when unassigned, thepost_deletesignal handler onDeviceCertificatemust explicitly revoke the underlying certificate, adding it to the CRL viacert.revoke(), before object cleanup. This invalidates any local copies retained by the device.Automated Renewal: when a standalone cert is renewed via the existing PKI API, it will automatically trigger the device configuration update path.
Config status updates from the proposal
certificate_updatedhandler so it can resolve the affected config throughDeviceCertificatein addition toVpnClient.transaction.on_commitwhere this follows the existing certificate update path.config.update_status_if_checksum_changed()for certificate generation and renewal so configs are marked modified only when the rendered configuration actually changes.Blueprint safety validation
The proposal also states that
DeviceCertificate.clean()should prevent a certificate referenced as ablueprint_certby any template from being assigned directly to a device.Tests from the GSoC proposal
DeviceCertificatecreation on template assignment.Measurable outcomes: 4, 6
Implementation points: 2, 3
Related issue: #1377 tracks the
DeviceCertificatemodel details.