Kaminari Ad

Combo rules

Combine several tags into one aggregate tag, and choose whether the conditions must be met anywhere on the scan or within a single link.

A combo rule fires on a combination of other tags and assigns one aggregate tag of its own. It turns several weak signals into a single decision — "five antivirus vendors agree", "a prohibited keyword and a redirect through a flagged domain".

Combo is one of the detection rule types. A combo's output tag can feed another combo, so aggregates can be chained.

Match scope

One scan usually covers several links — the creative, every hop of the redirect chain, the landing. Match scope decides whether conditions are counted across all of them or link by link. In the rule form it is its own field, immediately above Conditions:

  • Across the whole scan (any links) ("match_scope": "scan") — "Tags from different links of the scan can add up to satisfy the conditions." This is the default, and what rules authored before the setting existed do.
  • Within a single link (all conditions on one URL) ("match_scope": "url") — "Every condition must be satisfied by tags on the same link, and the tag is assigned to that link. A rule built only from link-less tags (AI, behaviour) has no link to attach to and will never match — keep those on the whole scan."
{ "match_scope": "url", "tag_category": "antivirus", "count_gte": 5 }

Existing rules are unchanged: a rule saved without match_scope is evaluated exactly as before — an absent key means the whole scan. A value that is neither "scan" nor "url" is rejected with 422 and the error code checking.combo_match_scope_invalid (see Authentication for the error body).

Some tags describe the scan as a whole rather than one link — AI verdicts, crawler behaviour signals. Under "url" they are treated as context available on every link, so they never block a rule that also requires a per-link detection. But they carry no link of their own, so a rule built only from link-less tags has no group to fire in and will never match under "url". Keep those rules on the whole scan.

One current limitation is worth knowing before you combine the two: AI verdicts and per-link detections (domain reputation, content and URL matches) are produced by different stages of a scan and are not evaluated together today, under either scope. A combo that mixes them will not fire until that changes. Combos over per-link detections — several antivirus vendors, a domain verdict plus a content match — are evaluated together as normal.

Conditions

A rule holds one or more conditions and fires only when all of them hold. Over the API (POST /api/v1/custom-rules) they are keys of the rule's config object:

Conditionconfig keysHolds when
All ofall_ofevery listed tag is present
Any ofany_of, any_of_minat least any_of_min of the listed tags are present (default 1)
Category counttag_category, count_gtecount_gte or more distinct tags of that category are present
None ofnone_ofnone of the listed tags is present
None of categorynone_of_categoryno tag of that category is present

Thresholds are always "N or more".

Under "url" the exclusions are evaluated per link too: a none_of or none_of_category tag sitting on another link does not suppress the rule. That can make a rule fire more often on a single link than the same rule set to the whole scan, where one excluded tag anywhere suppresses it everywhere.

Exclusions only narrow, so a per-link rule needs at least one positive condition — all_of, any_of, or a category count — to mean anything. A rule listing nothing but none_of / none_of_category has no detection to locate and simply matches every link that lacks the excluded tags.

A rule with an exclusion waits until every scan stage able to produce an excluded tag has finished, so its tag can appear later than the tags of rules without exclusions. It never fires on an absence a later stage could still disprove.

An input whose tag has been archived is out of service and is never assigned to a scan, so a rule that requires it cannot fire while that input stays archived. The editor warns you when a rule references one. See Tags → Archiving a tag.

Choosing a scope

Pick "url" when the conditions only mean something together on one address — vendor consensus, or "this link is both newly registered and serving a download". Pick "scan" when the signals describe the ad as a whole and may legitimately land on different links — an AI verdict plus a blacklisted domain somewhere in the chain — and for any rule built only from link-less tags.

Example: antivirus consensus

{ "tag_category": "antivirus", "count_gte": 5 } means "five antivirus vendors flagged something".

  • Under "scan", three vendors flagging a redirect hop plus two flagging an unrelated tracker on another domain add up to five. The tag fires even though no single link was called malicious by more than three vendors.
  • Under "url", the five detections have to land on the same link. The 3 + 2 split no longer fires; five vendors on one hop do, and the tag is attached to that hop.

Which reading you want is a per-rule decision, so the scope is yours to set on the rules you author. Kaminari Ad's own built-in aggregates are not affected by the setting — they keep counting across the whole scan until an administrator changes their scope.

What "url" does and does not guarantee

Links are matched as exact URLs. …?a=1 and …?a=2 are different links, and two vendors that flagged different files on the same host land in different groups. A host five vendors dislike can therefore miss the threshold in every group if some of those verdicts are per-file rather than per-host. Verdicts issued about a domain are spread across all of that host's links, so they do add up on the hop itself — which is why the redirect-chain hop is usually the group that fires. Grouping by domain rather than by URL is the natural next step for cases like this; it does not exist yet.

The guarantee is not transitive. match_scope is a property of one rule. If a "url" rule consumes the output of a "scan" rule, the parent's conditions are satisfied on one link, but the child's were not: the intermediate aggregate was allowed to add tags up across links, and it is assigned to every link that contributed. "All conditions on one link" holds fully only for rules built on raw detections, or on intermediates that are themselves "url"-scoped. Check the scope of the whole chain, not just the rule you are editing.

The tag is assigned to the group's link, not preferentially to the redirect hop. In practice that is usually the hop, because the hop's group is the richest one. But when the matching link is a sub-request, the tag is shown inside that sub-request's subtree, and if the link is not part of the rendered request tree at all (the tree is capped in depth and breadth, and filters some resource types) the tag will not appear in the tree — the host still shows up in the per-tag host list.

Testing and rechecking

Test rule evaluates a draft combo against the tags of a scan you pick, which is the quickest way to confirm a scope change still catches the cases you care about. It reports whether the rule fires, not which link it fired on.

A scope change applies to scans checked from that point on. To apply it to earlier results, recheck them — with one caveat: a recheck re-runs the checks without re-crawling, so it works from less material than the first pass did. The scan's full request list is not reproduced, and the reputation sources lose ground unevenly: those that read only that list contribute nothing, those that combine the redirect chain with it still cover the chain but no longer reach hosts that appeared only in sub-requests, and only the sources working purely from the redirect chain are unaffected. Behaviour tags are cleared by the recheck and are not regenerated either, so a rule that leans on them cannot match on a rechecked scan. Fewer tags on the second pass is expected — judge a threshold or scope change on a fresh scan.

← All documentation