🚧 Update certificate management

This commit is contained in:
Jonas Bengtsson
2026-09-19 17:12:58 +02:00
parent 111d6cc390
commit a16a01b1e7
21 changed files with 1128 additions and 37 deletions
+50 -1
View File
@@ -169,6 +169,18 @@ class MqttClientOut(BaseModel):
last_known_connection: datetime | None
class ClientIdUpdate(BaseModel):
"""PUT /clients/{username}/clientid — bind or clear the expected
client ID (spec section 11: "bind an expected client ID").
An empty string clears the binding: any client id may then connect
with these credentials. A bound ID restricts connections to exactly
that client id (anti-credential-sharing).
"""
clientid: str = Field(default="", max_length=200)
class MqttPasswordReset(BaseModel):
"""Response for create/reset — plaintext shown exactly once (spec 11)."""
@@ -203,6 +215,8 @@ class ListenerIn(BaseModel):
tls_min_version: Literal["tlsv1.2", "tlsv1.3"] | None = None
require_certificate: bool = False
use_identity_as_username: bool = False
# Bound server certificate (PKI): emitted as certfile/keyfile/cafile.
cert_id: uuid.UUID | None = None
class ListenerOut(ListenerIn):
@@ -269,6 +283,10 @@ class CertificateOut(BaseModel):
common_name: str
is_ca: bool
parent_id: uuid.UUID | None
cert_type: str
# MQTT client this certificate authenticates (client certs only;
# the CN equals the username — spec section 24).
username: str | None = None
key_algorithm: str
serial_number: str
dns_sans: list[str]
@@ -278,4 +296,35 @@ class CertificateOut(BaseModel):
expiry_date: datetime
created_at: datetime
model_config = {"from_attributes": True}
model_config = {"from_attributes": True}
class ClientCertCreate(BaseModel):
"""Issue a client certificate bound to an MQTT client (spec section 20).
The certificate CN is the MQTT username — with
use_identity_as_username the broker maps CN -> dynsec identity
(spec section 24), so the dynsec client must already exist.
"""
username: str = Field(min_length=1, max_length=100)
ca_id: uuid.UUID
validity_days: int = Field(gt=0, le=36500)
class CertificateBundle(BaseModel):
"""One-time download payload (spec sections 20, 44).
Contains EVERYTHING including the plaintext private key — shown
exactly once, never retrievable afterwards from the inventory.
"""
certificate_id: uuid.UUID
username: str
certificate_pem: str
private_key_pem: str
ca_chain_pem: str
download_hint: str = (
"Store these files securely now — the private key cannot be "
"retrieved again."
)