Coverage for src / lexigram / contracts / security / rotation.py: 0%
14 statements
« prev ^ index » next coverage.py v7.13.5, created at 2026-08-15 18:57 +0800
« prev ^ index » next coverage.py v7.13.5, created at 2026-08-15 18:57 +0800
1"""Secret rotation policy contract types."""
3from __future__ import annotations
5from dataclasses import dataclass, field
8@dataclass(frozen=True)
9class SecretRotationPolicy:
10 """Policy governing when a named secret should be rotated.
12 Attributes:
13 max_age_days: Maximum permitted age of the secret in days.
14 rotation_warning_days: Number of days *before* ``max_age_days``
15 at which an advance warning is emitted.
16 auto_rotate: When ``True``, rotation is attempted automatically;
17 otherwise only a warning is emitted.
18 """
20 max_age_days: int = 90
21 rotation_warning_days: int = 14
22 auto_rotate: bool = False
23 _secret_name: str = field(default="", init=False, repr=False, compare=False)
25 def is_warning_due(self, current_age_days: float) -> bool:
26 """Return True if a rotation warning should be emitted.
28 Args:
29 current_age_days: Current age of the secret in fractional days.
31 Returns:
32 ``True`` when the warning threshold has been reached.
33 """
34 threshold = self.max_age_days - self.rotation_warning_days
35 return current_age_days >= threshold
37 def is_expired(self, current_age_days: float) -> bool:
38 """Return True if the secret has exceeded its maximum permitted age.
40 Args:
41 current_age_days: Current age of the secret in fractional days.
43 Returns:
44 ``True`` when ``current_age_days >= max_age_days``.
45 """
46 return current_age_days >= self.max_age_days
49__all__ = ["SecretRotationPolicy"]