From 8b7df158837c57b24906b13188f6eab648b182f4 Mon Sep 17 00:00:00 2001 From: Pierre-Olivier Mercier Date: Fri, 15 May 2026 21:59:32 +0800 Subject: [PATCH 1/2] Include certificate count in issuer check state messages Add a per-issuer certificate counter to issuerAgg and append the count to each CheckState message and Meta map, so operators can see how many certificates were observed per issuer at a glance. --- checker/rule.go | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/checker/rule.go b/checker/rule.go index 6850730..7e91fb5 100644 --- a/checker/rule.go +++ b/checker/rule.go @@ -31,6 +31,7 @@ type issuerAgg struct { code string msg string endpoints map[string]bool + count int // number of certificates observed from this issuer } type allowList struct { @@ -152,6 +153,7 @@ func (r *caaRule) Evaluate(ctx context.Context, obs sdk.ObservationGetter, opts cur = &issuerAgg{sample: p, endpoints: map[string]bool{}} agg[k] = cur } + cur.count++ if severityRank(severity) >= severityRank(cur.severity) { cur.severity = severity cur.code = code @@ -233,22 +235,23 @@ func (r *caaRule) Evaluate(ctx context.Context, obs sdk.ObservationGetter, opts endpoints = append(endpoints, ep) } sort.Strings(endpoints) - meta := map[string]any{"endpoints": endpoints} + meta := map[string]any{"endpoints": endpoints, "cert_count": a.count} + certSuffix := fmt.Sprintf(" (%d certificate(s) checked)", a.count) switch a.severity { case SeverityCrit: out = append(out, sdk.CheckState{ - Status: sdk.StatusCrit, Message: a.msg, Code: a.code, + Status: sdk.StatusCrit, Message: a.msg + certSuffix, Code: a.code, Subject: subject, Meta: meta, }) case SeverityWarn: out = append(out, sdk.CheckState{ - Status: sdk.StatusWarn, Message: a.msg, Code: a.code, + Status: sdk.StatusWarn, Message: a.msg + certSuffix, Code: a.code, Subject: subject, Meta: meta, }) case SeverityInfo: out = append(out, sdk.CheckState{ - Status: sdk.StatusInfo, Message: a.msg, Code: a.code, + Status: sdk.StatusInfo, Message: a.msg + certSuffix, Code: a.code, Subject: subject, Meta: meta, }) default: @@ -257,7 +260,7 @@ func (r *caaRule) Evaluate(ctx context.Context, obs sdk.ObservationGetter, opts msg = "Certificate observed; no CAA records published" } out = append(out, sdk.CheckState{ - Status: sdk.StatusOK, Message: msg, Code: CodeOK, + Status: sdk.StatusOK, Message: msg + certSuffix, Code: CodeOK, Subject: subject, Meta: meta, }) } From 59af24f695dc63ae26968fe420f5104afdfda49f Mon Sep 17 00:00:00 2001 From: Pierre-Olivier Mercier Date: Sat, 16 May 2026 13:04:51 +0800 Subject: [PATCH 2/2] Remove redundant RunAt field from CAAData The observation timestamp is already stored by the core; there is no need to duplicate it inside the payload. --- checker/collect.go | 2 -- checker/types.go | 1 - 2 files changed, 3 deletions(-) diff --git a/checker/collect.go b/checker/collect.go index b378de2..ad0d927 100644 --- a/checker/collect.go +++ b/checker/collect.go @@ -4,7 +4,6 @@ import ( "context" "encoding/json" "fmt" - "time" sdk "git.happydns.org/checker-sdk-go/checker" ) @@ -64,7 +63,6 @@ func (p *caaProvider) Collect(ctx context.Context, opts sdk.CheckerOptions) (any return &CAAData{ Domain: domain, Records: records, - RunAt: time.Now().UTC().Format(time.RFC3339), }, nil } diff --git a/checker/types.go b/checker/types.go index b42c67b..a266ff3 100644 --- a/checker/types.go +++ b/checker/types.go @@ -40,7 +40,6 @@ const ( type CAAData struct { Domain string `json:"domain,omitempty"` Records []CAARecord `json:"records,omitempty"` - RunAt string `json:"run_at,omitempty"` } type CAARecord struct {