August 11, 2026
I automated cloud posture checks. Here’s what it kept flagging.
three months of continuous scanning, a findings list that refused to shrink, and what the recurring items actually revealed about how…

By h@shtalk
3 min read
three months of continuous scanning, a findings list that refused to shrink, and what the recurring items actually revealed about how infrastructure gets built.
I set up continuous cloud posture monitoring across a moderately messy environment and left it running for three months. Not as a compliance exercise — I wanted to know what an automated check actually surfaces over time when nobody's curating the results to look good.
The interesting part wasn't the initial findings dump. Everyone gets a large initial dump; that's just accumulated history. The interesting part was what kept coming back after remediation, because recurring findings tell you about process, and one-time findings only tell you about the past.
The recurring offenders
Over-permissioned IAM roles, constantly, forever. This was the highest-volume recurring category by a wide margin, and the pattern was consistent: new roles created during active development, scoped broadly to unblock work, with a genuine intention to narrow them later. Later did not arrive. The finding would get remediated, and three weeks on, two new instances of the same pattern appeared from a different project.
This is not a knowledge problem. Every engineer creating these roles knew the scope was too broad. It's a friction problem — narrow scoping requires knowing precisely which API calls your service will make, which you often don't know until it's running, so the path of least resistance is to grant broadly, get it working, and intend to tighten afterward. Nothing in the workflow forces the afterward.
Unencrypted resources at creation. Storage volumes, database snapshots, and queues created without encryption enabled, usually through the console rather than infrastructure-as-code, usually by someone doing a quick manual thing. IaC-created resources were near-uniformly compliant, because the module had encryption baked in. Console-created resources were the recurring failures. The distinction between "how we build things properly" and "how we build things quickly" showed up cleanly in the data.
Security groups with 0.0.0.0/0 on non-standard ports. Regularly appearing, regularly remediated, regularly reappearing. Almost always traceable to debugging: someone opened it to test something from their laptop, confirmed it worked, and moved on to the actual problem they were solving. The temporary rule became permanent through pure inattention.
Stale access keys older than the recommended rotation window. Slowly accumulating, essentially never self-resolving, because nothing breaks when a key gets old. The remediation is trivial and the motivation to do it is zero until something forces the issue.
Public snapshots. Rare but genuinely alarming when they appeared — usually a database snapshot shared for a legitimate reason with the sharing scope set wider than intended.
What the pattern actually revealed
Every recurring category shared a shape: the insecure option was the faster option at the moment of creation, and nothing in the workflow made the secure option the default path.
That's the whole finding, really. The scanner wasn't discovering that people don't know how to configure things securely. It was measuring, continuously, the gap between how infrastructure is supposed to be built and how it actually gets built when someone's trying to ship something.
The thing I got wrong at the start
I initially treated the findings list as a to-do list — work through it, drive the count down, feel accomplished. That approach fails, because the list regenerates. You're bailing water rather than finding the leak.
The shift that made it useful was tracking recurrence rather than count. A finding that appears once and gets fixed is history. A finding category that reappears every three weeks is telling you something structural about your provisioning process, and that's the one worth engineering against.
What actually reduced the recurring categories
Preventive guardrails, not detective controls. Service control policies that make the insecure configuration impossible rather than merely detectable. Encryption-by-default enforced at the organization level. This converted "unencrypted resources" from a recurring finding to a non-existent one, immediately, because the failure mode was removed rather than monitored.
IaC modules with secure defaults, plus making IaC the easy path. The console-versus-IaC split in the data was stark enough to be actionable. Reducing console-created resources reduced the finding rate directly.
Expiry on temporary rules. Security group rules created for debugging got an enforced TTL. If it's still needed, someone re-adds it deliberately. Most of the time nobody does, because it was never needed past that afternoon.
Automated key rotation. Removing the human step removed the finding category entirely.
Note what these have in common: none of them are "monitor more effectively." They're all changes to the system that produced the finding. Detection told me where to look; prevention is what actually moved the numbers.
Where the automation genuinely earned its place
Continuous, comprehensive, no-fatigue coverage of an environment that changes daily is exactly the workload machines are for. No human is reviewing every resource creation across a cloud estate. The scanner does it indifferently, at 3am, on a Sunday, without getting bored on the four hundredth security group.
Where it didn't
The tool cannot tell you which findings matter. A wide-open port on an isolated test instance and the same finding on a production system holding customer data are identical rows in the report, distinguished only by context the scanner doesn't have. Severity scores are a generic proxy for risk, not a substitute for knowing your own architecture.
And nothing in the tooling tells you to stop treating the list as a to-do and start reading it as a process diagnostic. That reframe was the entire value of the exercise, and it came from staring at the recurrence pattern long enough to get annoyed by it.