Skip to main content

Exclusion Management for Custom Rules across many SecOps tenants

  • Nov 4, 2026 11:04 PM UTC
  • 1 reply
  • 29 views

maxjunker
Forum|alt.badge.img+4

How do you manage rule exclusions across multiple Google SecOps tenants?

 

I´m part of an MSSP running Google SecOps SIEM tenants and a centralized Unified tenant for SOAR. We maintain a shared library of roughly 900 custom YARA-L rules and deploy it across about 50 separate Google SecOps SIEM customer instances. Most customers have different benign activity, so the same rule can need different exclusions in each instance.

We’d like to compare notes with teams managing exclusions at similar scale. Here’s our current approach, what works, and where we run into friction.

 

How we manage exclusions today

 

The rule text (event section) is the same across customer instances. Tenant-specific exceptions live in data tables: the tables have the same names in each instance, but their rows differ by customer.

We keep one table per domain and platform, such as exclusion_network or exclusion_endpoint_windows. A rule builds a key from its identifier and selected event fields, then checks that key against a REGEX column:

$exclusion = strings.to_lower(
strings.concat(
"network_fortinet_admin_login_from_public_source_b##",
$e.principal.ip, "##",
$e.principal.user.userid, "##",
$e.target.hostname
)
)
not($exclusion in regex %exclusion_network.exclusion nocase)

A row starts with the rule identifier, so a shared table can serve multiple rules without one rule’s row matching another rule. For example:

^network_fortinet_admin_login_from_public_source_b##203\.0\.113\.7##[^#]*##fw-hq-01$

We initially used one table per rule, coming from the Reference Sets times. But that would scale poorly against Google SecOps’ documented limit of 1,000 data tables per account. Google also documents a maximum of five in statements using regex operators in a query. Google SecOps data-table documentation. We are also facing long deployment times because of a large number of data tables. That´s why we reduced them to these domain exclusion tables.

At the time of writing, 597 of our 901 rules use an exclusion lookup. About one-third of those use the anchored format above; the rest use older key formats. We migrate those gradually because the rule logic and its rows need to change together.

We treat every exclusion as a reduction in detection coverage. Each row needs supporting evidence and a named human approver. When benign behavior can be described generally, we prefer to improve the rule logic rather than add a one-off exception.

 

Where the approach hurts

 

The pattern works, but its operational cost grows with every customer instance we add.

  • No shared inheritance layer in our workflow. We manage tables per customer instance and have not found a documented MSSP-wide layer where global rows are inherited and customer-specific rows override them. A generally applicable exclusion therefore has to be distributed to each instance.

  • Two sources of truth. Exclusions are usually added in the instance where the noise occurs. As a result, many table files in our repository are empty seeds, and a cross-customer view means collecting the tables instance by instance.

  • Broad or malformed rows are risky. A blank or overly broad regex can behave like a catch-all, so our linter rejects blank patterns and checks table rows before deployment. If a table is temporarily empty, its exclusions won’t match and detections may resume. We therefore update tables by adding or deleting rows rather than replacing them wholesale.

  • Our key format is coupled to rule identifiers. Because the identifier is embedded in the key, a rename or a beta-to-release promotion in our naming scheme can require corresponding row updates in every customer instance.

  • The packed key is a design trade-off. In this format, we concatenate string fields from one event variable. That makes the segment order part of the contract and means a multi-event rule must choose which event to key on. We also have to handle missing fields carefully: if they normalize to empty segments, a row can match more broadly than intended.

  • No real-time run frequency with data tables. Google’s documentation states that real-time run frequency isn’t supported for rules that use data tables. That’s a trade-off for rules where latency matters. Google SecOps data-table documentation

  • No built-in impact preview in our table workflow. We test proposed rows offline against sample events. The native exclusion feature offers a Test Exclusion preview over detections from the last 30 days; we don’t have an equivalent preview for a proposed data-table row in our workflow. Configure alert suppression

 

Why Curated Detections exclusions look attractive

 

Google SecOps has a native rule-exclusion feature: exclusions can filter matches without changing the rule text, and the Exclusions tab supports managing them. The feature also offers a Test Exclusion preview over the last 30 days. The API uses the findingsRefinements resource. Configure alert suppression · Manage rule exclusions through the API

There is an important limitation for us: the current operational documentation says rule exclusions apply to curated rules and curated rule sets, not custom rules. The API guide says that custom-rule names supplied in the rules field are ignored, even though the request can return 200 OK. The REST schema does expose a rules[] field, so the documentation is easy to misread. A Google SecOps staff reply in the Security Forum also says custom rules aren’t supported. Until Google confirms otherwise or we verify a working path, we’re treating curated exclusions as unavailable for our custom library. Alert-suppression documentation · API guide · REST schema · Google Security Forum discussion

For curated rules, the main differences from our current approach look like this:

 

Data tables in our rules

Curated rule exclusions

Rule-text change

Each rule must reference the lookup.

No rule-text change for supported curated rules.

Filter on

The key defined by our rule.

UDM event fields; outcome-variable filters are available through the API.

Impact test

Offline tests against sample events in our workflow.

Test Exclusion previews the effect on detections from the last 30 days.

Management

Table rows, repository tooling and our review process.

Exclusions tab: enable, disable, edit, archive and restore.

Expiry

Data-table rows support TTLs; Google documents a maximum of 365 days.

No exclusion TTL; the API guide describes a timestamp condition as a workaround.

Scope

Managed separately in each customer instance in our setup.

The API resource is scoped to a Google SecOps instance; we found no documented MSSP-wide inheritance layer.

Rule targets

Our row embeds the rule identifier.

Curated rule or rule-set resources; custom-rule targets are documented as unsupported.

Sources: data-table documentation, alert-suppression documentation, rule-exclusion API guide.

 

What we’d like to know

 

We’d especially like to hear from teams managing more than a handful of customer instances:

  1. Where is your source of truth for exclusions: a repository that deploys to instances, or the instances themselves?

  2. How do you separate exclusions that apply broadly from customer-specific ones?

  3. Has anyone confirmed a working API path for native exclusions on custom rules? The REST schema exposes a rules[] target, but the API guide says custom-rule targets are ignored.

  4. Do you keep latency-sensitive rules free of data tables, given the documented real-time-frequency limitation?

  5. How do you review and expire exclusions, and how do you catch a row that is broader than intended?

  6. What other patterns have worked for you, such as SOAR-based suppression or entity context?

  7. For the Google team: is an MSSP-level exclusion, defined once and applied across customer instances, on the roadmap?

We’re happy to share more about our key format, table linting and approval flow in the comments.

1 reply

ar3diu
Forum|alt.badge.img+11
  • Silver 2
  • Nov 5, 2026 9:44 AM UTC

1. We use a single repository with per-customer directories and CI/CD pipelines that run Python scripts for testing, validation, and bidirectional sync between the customers SecOps instances and the Git repo. Exclusions are stored as YAML files.
2. We don't. We just ensure that everyone gets all the exclusions they need.
3. We only create exclusions for curated rules; exclusions for custom rules belong in the rule query itself.
4. We don't use data tables for exclusions. Each exclusion lives in a YAML file inside a customer directory.
5. We enforce specific guardrails on the exclusion YAML files, then each exclusion is tested against the Chronicle API to check for errors, and every change goes through a PR for peer review. We also run a monthly job that checks for stale exclusions with no activity over the last 90 days. These are flagged in a PR assigned to us for review.
6. We convert curated rules to custom ones whenever more advanced YARA-L logic is required for an exclusion, and we also use SOAR playbooks for Alert exclusions when external enrichment/API calls are needed.