| """ |
| Security/deployment models — signing_keys, key_rotation_log, config_versions, deployment_events. |
| |
| Maps to AGENT.md DBML: Lines 675-734. |
| """ |
| from django.conf import settings |
| from django.db import models |
|
|
| from core.models import BaseModel |
|
|
|
|
| class ConfigVersion(models.Model): |
| """Tracks configuration version deployments.""" |
|
|
| version = models.CharField(max_length=50, primary_key=True) |
| checksum = models.CharField(max_length=64, blank=True, default="") |
| applied_at = models.DateTimeField(auto_now_add=True) |
|
|
| class Meta: |
| db_table = "config_versions" |
|
|
| def __str__(self) -> str: |
| return self.version |
|
|
|
|
| class DeploymentEvent(BaseModel): |
| """Records deployment lifecycle events.""" |
|
|
| class Status(models.TextChoices): |
| STARTED = "started", "Started" |
| COMPLETED = "completed", "Completed" |
| FAILED = "failed", "Failed" |
| ROLLED_BACK = "rolled_back", "Rolled Back" |
|
|
| version = models.CharField(max_length=50) |
| status = models.CharField(max_length=20, choices=Status.choices, default=Status.STARTED) |
| started_at = models.DateTimeField(null=True, blank=True) |
| finished_at = models.DateTimeField(null=True, blank=True) |
|
|
| class Meta: |
| db_table = "deployment_events" |
| ordering = ["-created_at"] |
|
|
| def __str__(self) -> str: |
| return f"Deploy {self.version} ({self.get_status_display()})" |
|
|
|
|
| class SigningKey(BaseModel): |
| """Cryptographic signing keys for tokens/webhooks.""" |
|
|
| public_key = models.TextField() |
| private_ref = models.CharField(max_length=255) |
| algorithm = models.CharField(max_length=20, default="RS256") |
| active = models.BooleanField(default=True) |
| rotated_at = models.DateTimeField(auto_now_add=True) |
|
|
| class Meta: |
| db_table = "signing_keys" |
|
|
| def __str__(self) -> str: |
| return f"Key {self.pk} ({self.algorithm})" |
|
|
|
|
| class KeyRotationLog(BaseModel): |
| """Tracks signing key rotation events.""" |
|
|
| key = models.ForeignKey( |
| SigningKey, |
| on_delete=models.CASCADE, |
| related_name="rotation_logs", |
| ) |
| rotated_by = models.ForeignKey( |
| settings.AUTH_USER_MODEL, |
| on_delete=models.SET_NULL, |
| null=True, |
| blank=True, |
| related_name="key_rotations", |
| ) |
| rotated_at = models.DateTimeField(auto_now_add=True) |
|
|
| class Meta: |
| db_table = "key_rotation_log" |
| ordering = ["-rotated_at"] |
|
|
| def __str__(self) -> str: |
| return f"Rotation of {self.key_id}" |
|
|