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

1"""Secret rotation policy contract types.""" 

2 

3from __future__ import annotations 

4 

5from dataclasses import dataclass, field 

6 

7 

8@dataclass(frozen=True) 

9class SecretRotationPolicy: 

10 """Policy governing when a named secret should be rotated. 

11 

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 """ 

19 

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) 

24 

25 def is_warning_due(self, current_age_days: float) -> bool: 

26 """Return True if a rotation warning should be emitted. 

27 

28 Args: 

29 current_age_days: Current age of the secret in fractional days. 

30 

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 

36 

37 def is_expired(self, current_age_days: float) -> bool: 

38 """Return True if the secret has exceeded its maximum permitted age. 

39 

40 Args: 

41 current_age_days: Current age of the secret in fractional days. 

42 

43 Returns: 

44 ``True`` when ``current_age_days >= max_age_days``. 

45 """ 

46 return current_age_days >= self.max_age_days 

47 

48 

49__all__ = ["SecretRotationPolicy"]