using OTSSignsOrchestrator.Server.Data.Entities; namespace OTSSignsOrchestrator.Server.Health.Checks; /// /// Checks the age of the OAuth2 application credentials from . /// Alerts Warning at 180 days, Critical at 365 days. AutoRemediate=false — suggests /// a "rotate-oauth2" job instead. /// public sealed class OauthAppAgeHealthCheck : IHealthCheck { /// Days at which severity escalates to Warning. internal const int WarningThresholdDays = 180; /// Days at which severity escalates to Critical. internal const int CriticalThresholdDays = 365; public string CheckName => "OauthAppAge"; public bool AutoRemediate => false; public Task RunAsync(Instance instance, CancellationToken ct) { var oauthApp = instance.OauthAppRegistries .OrderByDescending(o => o.CreatedAt) .FirstOrDefault(); if (oauthApp is null) return Task.FromResult(new HealthCheckResult(HealthStatus.Degraded, "No OAuth app registered")); var ageDays = (DateTime.UtcNow - oauthApp.CreatedAt).TotalDays; if (ageDays >= CriticalThresholdDays) { return Task.FromResult(new HealthCheckResult(HealthStatus.Critical, $"OAuth2 credentials are {(int)ageDays} days old (critical threshold: {CriticalThresholdDays}d)", "Create a 'rotate-credentials' job to rotate the OAuth2 application")); } if (ageDays >= WarningThresholdDays) { return Task.FromResult(new HealthCheckResult(HealthStatus.Degraded, $"OAuth2 credentials are {(int)ageDays} days old (warning threshold: {WarningThresholdDays}d)", "Schedule credential rotation before they reach 365 days")); } return Task.FromResult(new HealthCheckResult(HealthStatus.Healthy, $"OAuth2 credentials are {(int)ageDays} days old")); } }