Functional Weave
Code in TypeScript

monitor.cert-expiry@1.0.0

README.md

1,908 bytes · view raw

# monitor.cert-expiry

How long a TLS certificate has left, and whether to worry: `ok`, `warning`,
`critical` or `expired`. The caller reads `notAfter` from the certificate
(as Unix seconds); this decides what it means today.

## Decisions

- **notAfter is inclusive.** RFC 5280 section 4.1.2.5: "The validity period
  for a certificate is the period of time from notBefore through notAfter,
  inclusive." So the certificate is still valid during the notAfter second
  and is `expired` only when `now > notAfter`. At `now == notAfter`,
  `secondsLeft` is 0 but the state is not yet expired.
- **Thresholds are "fewer than N days"**: critical when
  `secondsLeft < criticalDays * 86400`, else warning when
  `secondsLeft < warnDays * 86400`, else ok. Exactly 30 days left with a
  30-day warning is still ok. This is computed as
  `floor(secondsLeft / 86400) < N`, which is the same test with nothing to
  overflow.
- `daysLeft` is whole days, rounded down: 6 days 23 hours is 6.
- `secondsLeft` and `daysLeft` are 0 once expired, never negative.
- `warnDays` equal to `criticalDays` means no warning stage. With
  `criticalDays` 0 there is no critical stage, and the last valid second is
  `ok`; pick at least 1 if you want to hear about it.
- The usual settings are 30 and 7 days (Let's Encrypt certificates last 90
  days and are renewed at 30 left), or 14 and 3.
- `99991231235959Z` (253402300799), which RFC 5280 says marks a certificate
  with no well-defined expiry, is simply a very distant date and reads `ok`.

## Errors

- `criticalDays must be a whole number 0 or more, received X`
- `warnDays must be a whole number at least criticalDays (C), received X`
- `notAfter and now must be whole seconds, received A and B`

## Sources

- RFC 5280, Internet X.509 Public Key Infrastructure Certificate and CRL
  Profile, section 4.1.2.5 Validity:
  https://www.rfc-editor.org/rfc/rfc5280#section-4.1.2.5