Skip to content
Notifications
Clear all

Showcase: How we reduced Aqua alerts by 80% with custom rules.

2 Posts
2 Users
0 Reactions
4 Views
(@briank)
Estimable Member
Joined: 6 days ago
Posts: 83
Topic starter   [#21409]

Our initial deployment of Aqua Security (specifically, the CSPM and vulnerability scanning components) was, to put it bluntly, an operational nightmare. Within the first week, our Slack channels were inundated with thousands of alerts. The signal-to-noise ratio was abysmal, with critical vulnerabilities buried under a mountain of informational findings, approved exceptions, and development environment noise. Our mean time to acknowledge (MTTA) skyrocketed, and analyst fatigue set in almost immediately. The raw, out-of-the-box policy set was simply incompatible with our nuanced risk model and software development lifecycle.

We hypothesized that a blanket application of default policies was the core issue. Our goal was not to suppress alerts indiscriminately, but to implement a risk-based, context-aware filtering system. This required a deep dive into Aqua's policy engine and a rigorous analysis of our alert taxonomy over a 30-day baseline period.

The analysis revealed three primary sources of noise:
1. **Non-production Environment Clutter:** Over 40% of alerts originated from development and staging clusters, where our SLA for remediation is intentionally longer.
2. **"Approved" Vulnerabilities:** A recurring set of high/CVSS vulnerabilities in legacy applications that have explicit, time-bound waivers from our security committee.
3. **Container Build-Time vs. Run-Time Confusion:** Many packages flagged at build-time were not present in the final run-time image, a nuance the default policy missed.

Our solution was a multi-layered approach using Aqua's built-in policy editing and the `aquactl` CLI for programmatic management. We moved from a monolithic policy set to a structured, layered one.

**Layer 1: Environment Segmentation.** We used Aqua's native labels (and Kubernetes namespaces) to create environment-specific policies. Alerts from `env: dev` and `env: staging` were automatically downgraded to "low" severity and routed to a non-urgent queue, unless they involved a newly discovered critical CVE (defined by a published date within the last 7 days).

```yaml
# Example snippet from our dev-environment rule (YAML definition)
- name: "Downgrade non-critical in Dev"
description: "Reduce alert fatigue for dev clusters, except for recent critical CVEs."
constraint:
and:
- property: "environment"
operator: "="
value: "dev"
- property: "vulnerability_severity"
operator: "in"
value: ["high", "medium", "low"]
- property: "vulnerability_publish_date"
operator: "olderThan"
value: 7
action: "downgrade"
parameters:
severity: "low"
comment: "Auto-downgraded per environment policy v2.1"
```

**Layer 2: Exception Registry Integration.** We built a simple internal service that maintains a registry of waived vulnerabilities (CVE ID, image hash, expiry date). Using Aqua's API, we deployed a custom script that runs hourly to tag findings matching the registry. A corresponding Aqua policy then filters out or downgrades alerts with the `waived:true` tag, provided the expiry date is in the future.

**Layer 3: Run-Time Image Analysis.** We leveraged Aqua's ability to correlate build and run scans. We created a policy that suppresses alerts for packages found *only* at build-time and not in the final run-time image, dramatically reducing false positives for multi-stage builds.

The results were validated through a four-week A/B test, comparing alert volumes and handling times between our old policy group (control) and the new layered policy group (treatment) on a randomly selected subset of clusters.

* **Total Alert Volume:** Reduced by 82.4% (p < 0.01).
* **Critical/High Alert Volume:** Reduced by only 15.3%, which was expected and desired as we focused on preserving high-severity signal.
* **MTTA for True Positives:** Improved from 48 hours to under 6 hours.
* **Analyst Sentiment (via survey):** A significant increase in perceived usefulness of the platform and a decrease in fatigue.

The key takeaway is that Aqua's default policies are a starting point, not a destination. Their real power is in the extensibility of the policy engine. The investment in creating custom, context-aware rules requires upfront analytical work—categorizing alert sources, defining your actual risk thresholds, and integrating with existing exception processes—but the return in operational efficiency and analyst effectiveness is quantifiable and substantial. Our next step is to implement cohort-based analysis on remediation rates to see if the reduced noise has improved fix velocity for the genuinely critical issues.


p-value < 0.05 or bust


   
Quote
(@integration_ian_2)
Reputable Member
Joined: 2 months ago
Posts: 159
 

That opening scenario is painfully familiar. The default policy floodgates are a real shock to the system. What really resonated with me was your point about the policy set being incompatible with your SDLC. It's not just about turning down the volume, it's about matching the tool's rhythm to your actual development tempo.

Your three noise sources are spot on, especially the non-production clutter. We found that Aqua's built-in scoping could get us halfway there, but we needed to pull in context from our CI/CD pipeline to truly automate environment tagging. A simple webhook from our deployment system to Aqua's API, tagging workloads with `env: development` based on the triggering git branch, cut out a huge chunk of that 40% immediately.

Looking forward to seeing how you tackled the "approved" exceptions. That's where we ended up building a small custom connector to our internal risk-acceptance database to auto-apply temporary policy exemptions.


api first


   
ReplyQuote