alec.vogelsang
← All work

Turning compliance controls into alerts that page someone

A government-cloud environment had its vulnerability posture sitting in a scanner's dashboards that someone was supposed to look at. I rebuilt those views in Splunk, then kept going — because a dashboard nobody opens on a Tuesday is not a control.

Where
Deltek, on a consulting engagement via SP6
When
2021
Role
Detection and dashboard build
Stack
Splunk, Qualys, ServiceNow

The situation

The environment was in scope for a federal compliance regime, which meant a written set of continuous-monitoring controls: scan everything on this cadence, remediate criticals within this window, keep unauthenticated scans below this share of the total, and so on.

All the underlying data existed. The vulnerability scanner had good dashboards and they were accurate. The problem was that satisfying a control depended on a person remembering to go and look, and then remembering what normal looked like when they got there. That works right up until the week it doesn’t, and an audit is precisely the exercise of finding that week.

The ask, initially, was to replicate the scanner’s dashboards in Splunk so the data lived alongside everything else.

Replication first, and it wasn’t enough

I did the replication. Rebuilt the vulnerability views, the asset coverage views, the port and protocol inventories. Along the way I put in base searches so the panels shared work instead of each running its own scan of the data, and re-accelerated the data models so the dashboards would hold up over the longer time ranges the compliance windows actually needed.

But sitting in the review meetings, the same question kept coming up in different forms, and it was never about the visualisation. It was who gets told, and what are they supposed to do about it?

That’s the real finding from this project. Every control in the document decomposed into the same four parts, and only three of them were technical:

The owner is the part everyone forgets, and it’s the part that decides whether any of the rest matters.

What I built

Port baselining with change detection

Rather than a panel showing currently-open ports, I inventoried ports, services, and protocols, classified them by range — system, user, dynamic — and snapshotted that as a baseline. From then on the alert fires on change, not on state.

If the count of open user ports moves, a ticket opens automatically, and a human confirms the change went through the approved change-control process. If it didn’t, security has a real lead. This inverts the work: instead of someone auditing a list periodically and hoping to spot a difference, the system notices the difference and asks a person one specific question.

Weak-protocol and cipher detection

The scanner already flagged deprecated TLS versions and weak ciphers in red on a dashboard. I turned each of those conditions into a detection that opened a ticket, so “red on a dashboard” became “assigned to a queue with a clock on it.”

Scan-freshness thresholds

Several controls were fundamentally about coverage rather than findings — a host that hasn’t been scanned in too long is a gap regardless of what its last scan said. Those became straightforward age-based alerts.

The subtler one was tracking unauthenticated scans as a proportion of the total. The scanner marks a scan unauthenticated when it can’t determine the OS or log in, and the control capped what share of scans could be in that state. The naive version of that alert is useless, because a stable set of hosts can never authenticate by design and they’d pin the metric permanently over threshold. Getting it right meant accounting for that known population so the alert only fired on genuine drift.

Routing into the ticketing system, not into email

Alerts opened incidents in ServiceNow rather than sending mail. Email has no owner, no state, and no SLA — three things a compliance control needs and an inbox cannot provide. Letting the ticketing system handle notification also meant Splunk only had to do the part it was good at.

The thing I'd carry forward

A compliance control is an alert nobody has written yet. Read the control document as a detection backlog and most of it translates directly — the hard part isn’t the search, it’s establishing the baseline and finding out who owns the response.

Where it landed

What I’d do differently

I’d settle ownership before building a single detection. I built several alerts that were technically correct and then sat unrouted while we worked out which team should receive them, and an alert with no owner is just a more-expensive dashboard. The right sequence is to agree the owner first and let that shape the threshold — because how noisy an alert is allowed to be depends entirely on who has to read it.

This describes the approach, not the environment. The specific control identifiers, the findings themselves, host and asset counts, scanner configuration, and the teams involved are all left out — a former employer’s security posture isn’t mine to publish, and the transferable part is the method anyway.