Skip to content

[ti_abusech] Add YARAify data stream and commercial API for URLhaus - #20380

Merged
moxarth-rathod merged 10 commits into
elastic:mainfrom
moxarth-rathod:abusech-url
Sep 11, 2026
Merged

moxarth-rathod merged 10 commits into
elastic:mainfrom
moxarth-rathod:abusech-url

Conversation

@moxarth-rathod

@moxarth-rathod moxarth-rathod commented Jul 28, 2026 •

Copy link
Copy Markdown
Contributor

Proposed commit message

ti_abusech: add yaraify data stream and commercial url API support

Add a YARAify data stream with community and commercial collection,
a latest indicator transform, and a rules dashboard. Extend the
URLhaus (url) stream to the commercial API, including initial lookback
and page size.

Update the MalwareBazaar commercial token-refresh script test to set
api_type, username, and password as CEL input vars so the test matches
the package-level commercial credential fields.

Checklist

  • I have reviewed tips for building integrations and this pull request is aligned with them.
  • I have verified that all data streams collect metrics or logs.
  • I have added an entry to my package's changelog.yml file.
  • I have verified that Kibana version constraints are current according to guidelines.
  • I have verified that any added dashboard complies with Kibana's Dashboard good practices

How to test this PR locally

  • Clone integrations repo.
  • Install elastic package locally.
  • Start elastic stack using elastic-package.
  • Move to integrations/packages/ti_abusech directory.
  • Run the following command to run tests.

elastic-package test

Related issues

@moxarth-rathod moxarth-rathod self-assigned this Jul 28, 2026
@moxarth-rathod
moxarth-rathod requested review from a team as code owners July 28, 2026 12:21
@moxarth-rathod moxarth-rathod added documentation Improvements or additions to documentation. Applied to PRs that modify *.md files. enhancement New feature or request Integration:ti_abusech abuse.ch Team:Security-Service Integrations Security Service Integrations team [elastic/security-service-integrations] Team:SDE-Crest Crest developers on the Security Integrations team [elastic/sit-crest-contractors] labels Jul 28, 2026
@infra-vault-gh-plugin-prod

Copy link
Copy Markdown

Pinging @elastic/security-service-integrations (Team:Security-Service Integrations)

@github-actions

github-actions Bot commented Jul 28, 2026 •

Copy link
Copy Markdown
Contributor

Elastic Docs Style Checker (Vale)

Summary: 10 suggestions found

💡 Suggestions (10): Optional style improvements. Apply when helpful.
File Line Rule Message
packages/ti_abusech/_dev/build/docs/README.md 9 Elastic.WordChoice Consider using 'misuse' instead of 'abuse', unless the term is in the UI.
packages/ti_abusech/_dev/build/docs/README.md 63 Elastic.WordChoice Consider using 'misuse' instead of 'abuse', unless the term is in the UI.
packages/ti_abusech/_dev/build/docs/README.md 213 Elastic.WordChoice Consider using 'misuse' instead of 'abuse', unless the term is in the UI.
packages/ti_abusech/_dev/build/docs/README.md 216 Elastic.WordChoice Consider using 'misuse' instead of 'abuse', unless the term is in the UI.
packages/ti_abusech/_dev/build/docs/README.md 217 Elastic.WordChoice Consider using 'misuse' instead of 'abuse', unless the term is in the UI.
packages/ti_abusech/_dev/build/docs/README.md 221 Elastic.WordChoice Consider using 'misuse' instead of 'abuse', unless the term is in the UI.
packages/ti_abusech/data_stream/yaraify/fields/fields.yml 3 Elastic.WordChoice Consider using 'misuse' instead of 'Abuse', unless the term is in the UI.
packages/ti_abusech/data_stream/yaraify/manifest.yml 9 Elastic.WordChoice Consider using 'misuse' instead of 'abuse', unless the term is in the UI.
packages/ti_abusech/data_stream/yaraify/manifest.yml 15 Elastic.WordChoice Consider using 'misuse' instead of 'abuse', unless the term is in the UI.
packages/ti_abusech/manifest.yml 32 Elastic.WordChoice Consider using 'misuse' instead of 'abuse', unless the term is in the UI.

The Vale linter checks documentation changes against the Elastic Docs style guide. To use Vale locally or report issues, refer to Elastic style guide for Vale.

"Content-Type": ["application/json"],
?"Auth-Key": has(state.auth_key) ?
optional.of([state.auth_key])
state.?api_type.orValue("community") == "commercial" ?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Severity: 🟠 High confidence: high path: packages/ti_abusech/data_stream/url/agent/stream/cel.yml.hbs:38

The CEL guard that rejected the deprecated /downloads/json URLhaus endpoint was deleted, so policies still holding that URL now silently collect zero events instead of raising a configuration error; restore the guard (or update/remove the script test that still asserts it).

Details

The previous program opened with a state.url.contains("/downloads/json") branch that emitted a configuration_error event telling the user to move to https://urlhaus-api.abuse.ch/v1/urls/recent/. This PR replaces the top of the program with the api_type dispatch and drops that branch entirely. The community path now issues GET against whatever URL is configured; for /downloads/json the response has no urls key, so has(body.urls) is false, the program returns [], and the user gets no data and no error.

This is not hypothetical: packages/ti_abusech/data_stream/url/_dev/test/scripts/deprecated_url.txt still exists unchanged in the branch and asserts stdout 'deprecated full export endpoint' on error.message plus exactly one error document. That test is now inconsistent with the program. The upgrade note in docs/README.md ("Upgrading to v4.0.0") also still tells users the old URL must be changed manually, which is exactly the population this guard protected. Making url show_user: true in this PR widens the set of users who can end up on a wrong URL, and the same silent-failure applies when a user switches API Type to Commercial but leaves the community default URL in place.

Recommendation:

Re-add the deprecated-endpoint guard ahead of the api_type dispatch, and keep deprecated_url.txt valid:

program: |
  state.with(
    state.url.contains("/downloads/json") ?
      {
        "events": {
          "error": {
            "code": "400",
            "id": "configuration_error",
            "message": "the URL is set to the deprecated full export endpoint (/downloads/json) which is no longer supported. Update the URL setting to https://urlhaus-api.abuse.ch/v1/urls/recent/",
          },
        },
        "want_more": false,
      }
    : state.?api_type.orValue("community") == "commercial" ?
      (
        // ... existing commercial branch ...
      )
    :
      // ... existing community branch ...
  )

If dropping the guard is intentional, delete _dev/test/scripts/deprecated_url.txt, remove the stale upgrade instruction from the docs, and add a changelog entry describing the behaviour change.


🤖 AI-Generated Review | Vera Review Bot | 📚 Knowledge base: integration-skills

⚠️ Automated review — verify suggestions before applying.

Comment thread packages/ti_abusech/changelog.yml Outdated
changes:
- description: Add Commercial API support for the URLhaus data stream.
type: enhancement
link: https://github.com/elastic/integrations/pull/20134

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Severity: 🟠 High confidence: high path: packages/ti_abusech/changelog.yml:6

Both new changelog entries link to the placeholder PR #1; point them at this PR (20380) instead.

Details

The two entries added for version 4.2.0 (Add Commercial API support for the URLhaus data stream. at line 6 and Add YARAify data stream with Community and Commercial API support. at line 9) both carry link: https://github.com/elastic/integrations/pull/1. PR 1 is unrelated to this change. The already-merged MalwareBazaar entry directly below correctly references pull/20199, so the placeholder was simply not replaced before pushing. Changelog links are surfaced in the published package changelog, so users following them land on the wrong PR.

Recommendation:

Point both entries at this PR:

- version: "4.2.0"
  changes:
    - description: Add Commercial API support for the URLhaus data stream.
      type: enhancement
      link: https://github.com/elastic/integrations/pull/20380
    - description: Add YARAify data stream with Community and Commercial API support.
      type: enhancement
      link: https://github.com/elastic/integrations/pull/20380

🤖 AI-Generated Review | Vera Review Bot | 📚 Knowledge base: integration-skills

⚠️ Automated review — verify suggestions before applying.

community:
- name: api_type
value: community
- name: auth_key

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Severity: 🟠 High confidence: medium path: packages/ti_abusech/manifest.yml:67

Selecting Commercial API stops Fleet from requiring Auth Key, but threatfox, malware, sslblacklist and ja3_fingerprints always use the Community API and still need it; add auth_key to the commercial required_vars group and fix the contradictory description.

Details

required_vars lists auth_key only under the community group. When a user picks api_type: commercial to collect URLhaus/MalwareBazaar/YARAify, Fleet no longer requires Auth Key, yet the other four data streams in this same policy template (threatfox, malware, sslblacklist, ja3_fingerprints) have no commercial branch in their CEL/httpjson templates and keep calling the community endpoints, which reject unauthenticated requests.

The manifest also contradicts itself about this. The api_type description (line 79) says "Other data streams always use the Community API", while the auth_key description (line 97) says "Not used when API Type is Commercial API" and enumerates only "Threat Fox, Malware Bazaar, URLhaus, YARAify" - omitting SSL Blacklist, JA3 Fingerprints and Malware, all of which need the key regardless of API Type.

Recommendation:

Require auth_key in both groups and correct the description:

        required_vars:
          community:
            - name: api_type
              value: community
            - name: auth_key
          commercial:
            - name: api_type
              value: commercial
            - name: auth_key
            - name: username
            - name: password
          - name: auth_key
            type: password
            title: Auth Key (Community)
            multi: false
            required: false
            show_user: true
            secret: true
            description: >-
              abuse.ch Auth Key for the Community API. Always required: SSL Blacklist, JA3 Fingerprints,
              Malware and Threat Fox only support the Community API, and URLhaus, MalwareBazaar and YARAify
              use it when API Type is Community API. See [documentation](https://abuse.ch/blog/community-first/) for details.

🤖 AI-Generated Review | Vera Review Bot | 📚 Knowledge base: integration-skills

⚠️ Automated review — verify suggestions before applying.


#### YARAify

{{fields "yaraify"}}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Severity: 🟡 Medium confidence: high path: packages/ti_abusech/_dev/build/docs/README.md:199

The Example event section renders {{fields "yaraify"}} instead of {{event "yaraify"}}, so the generated README duplicates the exported-fields table and never shows the YARAify sample event.

Details

Line 169 correctly places {{fields "yaraify"}} under the exported-fields section, but line 199 - added under ### Example event, directly after {{event "url"}} - repeats {{fields "yaraify"}}. The rendered docs/README.md confirms the effect: the identical YARAify field table appears twice (once around line 400 and again around line 947), and no YARAify example event is shown even though data_stream/yaraify/sample_event.json was added in this PR.

Recommendation:

Render the sample event in the Example event section:

#### YARAify

{{event "yaraify"}}

Then regenerate docs/README.md with elastic-package build.


🤖 AI-Generated Review | Vera Review Bot | 📚 Knowledge base: integration-skills

⚠️ Automated review — verify suggestions before applying.


- Configure **Auth Key**.
- Configure **Auth Key** for Community API datasets.
- For ThreatFox Commercial API collection, set **API Type** to **Commercial API**, set the **URL** to the commercial API base URL (for example `https://api.spamhaus.com`), and configure **Username** and **Password**.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Severity: 🟡 Medium confidence: high path: packages/ti_abusech/_dev/build/docs/README.md:90

The doc template credits Commercial API support to ThreatFox, which this PR does not add, and it no longer matches the committed docs/README.md - so the next build will regress the rendered README.

Details

The template says "For ThreatFox Commercial API collection, set API Type to Commercial API ...". ThreatFox has no commercial branch: data_stream/threatfox/agent/stream/cel.yml.hbs is untouched by this PR and the root manifest's own api_type description says Commercial applies to "URLhaus, MalwareBazaar, and YARAify".

The generated packages/ti_abusech/docs/README.md (line 89 in the rendered file) already reads "For URLhaus, MalwareBazaar, or YARAify Commercial API collection ...". Because the two files disagree, the committed README was not produced from this template - the next elastic-package build will overwrite it with the incorrect ThreatFox wording.

Recommendation:

Fix the template so it matches the rendered docs, then rebuild:

        - Configure **Auth Key** for Community API datasets.
        - For URLhaus, MalwareBazaar, or YARAify Commercial API collection, set **API Type** to **Commercial API**, set the **URL** to the commercial API base URL (for example `https://api.spamhaus.com`), and configure **Username** and **Password**.

🤖 AI-Generated Review | Vera Review Bot | 📚 Knowledge base: integration-skills

⚠️ Automated review — verify suggestions before applying.

Comment thread packages/ti_abusech/manifest.yml Outdated
conditions:
kibana:
version: "^8.19.0 || ^9.1.0"
version: "^9.1.0"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Severity: 🟡 Medium confidence: medium path: packages/ti_abusech/manifest.yml:12

conditions.kibana.version is narrowed from "^8.19.0 || ^9.1.0" to "^9.1.0", dropping 8.19 support in a minor release with no feature that requires it and no changelog note; keep the 8.19 range or document the drop.

Details

Nothing added by this PR requires Kibana 9.1+. The only new manifest capability is required_vars on a policy-template input, which package-spec gates on format_version >= 3.3.2 (spec/integration/manifest.spec.yml removes .../inputs/items/properties/required_vars only before: 3.3.2); the package was already at 3.3.2 before this change, and the spec ties it to no Kibana version. The rest of the change is CEL, ingest-pipeline, fields and dashboard work.

The effect is user-visible: every 8.19.x deployment on ti_abusech 4.1.x stops receiving upgrades at 4.2.0. Both changelog entries are typed enhancement, so nothing signals the compatibility reduction.

Recommendation:

Restore the existing range unless a concrete 9.1-only feature is being used:

conditions:
  kibana:
    version: "^8.19.0 || ^9.1.0"

If 8.19 really must be dropped, add a changelog entry stating it, for example:

    - description: Drop support for Kibana 8.19; the package now requires 9.1.0 or later.
      type: breaking-change
      link: https://github.com/elastic/integrations/pull/20380

🤖 AI-Generated Review | Vera Review Bot | 📚 Knowledge base: integration-skills

⚠️ Automated review — verify suggestions before applying.

@@ -1,5 +1,5 @@
{
"@timestamp": "2026-05-11T18:17:40.972Z",
"@timestamp": "2026-07-27T09:15:15.628Z",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Severity: 🟡 Medium confidence: medium path: packages/ti_abusech/data_stream/url/sample_event.json:2

The url sample event was regenerated on an 8.19.0 stack and lost event.module, threat.feed.name, threat.feed.dashboard_id and labels.is_ioc_transform_source; regenerate it on a stack matching the package's new ^9.1.0 requirement.

Details

The regenerated sample event drops four fields that the package still defines and that the previous sample contained: event.module (constant_keyword ti_abusech from data_stream/url/fields/base-fields.yml), threat.feed.name (AbuseCH URL) and threat.feed.dashboard_id (both from the same unchanged file), and labels.is_ioc_transform_source (from fields/is-ioc-transform-source-true.yml, also unchanged). threat.feed.dashboard_id and threat.feed.name are what the Kibana CTI UI uses to link indicators back to the feed dashboard, and labels.is_ioc_transform_source is what distinguishes source-data-stream documents from latest_url destination documents.

The stack version also went backwards: agent.version/elastic_agent.version changed from 9.3.1 to 8.19.0, below the ^9.1.0 floor this same PR sets in the root manifest. The yaraify sample event added in this PR was generated on 9.1.0 and does contain all four fields, so the two sample events in one PR disagree. This propagates into docs/README.md, whose url example event now omits them too.

Recommendation:

Re-run the url system test on a stack that satisfies the package's declared conditions.kibana.version and commit the regenerated sample so it matches the yaraify sample:

{
    "event": {
        "module": "ti_abusech"
    },
    "labels": {
        "is_ioc_transform_source": "true"
    },
    "threat": {
        "feed": {
            "dashboard_id": "ti_abusech-c0d8d1f0-3b20-11ec-ae50-2fdf1e96c6a6",
            "name": "AbuseCH URL"
        }
    }
}

Then regenerate docs/README.md.


🤖 AI-Generated Review | Vera Review Bot | 📚 Knowledge base: integration-skills

⚠️ Automated review — verify suggestions before applying.

description: >
The ID of the indicator.

- name: first_seen

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Severity: 🔵 Low confidence: high path: packages/ti_abusech/data_stream/url/fields/fields.yml:10

abusech.url.first_seen is declared as a field and documented, but the pipeline removes it unconditionally so it can never appear in a document; drop the declaration or stop removing the field.

Details

abusech.url.first_seen is added here and in elasticsearch/transform/latest_url/fields/fields.yml, and it is now listed in the generated README exported-fields table. However elasticsearch/ingest_pipeline/default.yml adds abusech.url.first_seen to the remove_97e5a966 processor, which has no if condition, so the field is stripped from every document after being mapped to threat.indicator.first_seen. The PR's own fixture confirms this: _dev/test/pipeline/test-commercial-fields.log-expected.json contains threat.indicator.first_seen but no abusech.url.first_seen in either expected document. The other always-removed keys (date_added, dateadded, url, host) are correspondingly absent from fields.yml.

Recommendation:

Drop the unused declaration from both data_stream/url/fields/fields.yml and elasticsearch/transform/latest_url/fields/fields.yml:

    - name: id
      type: keyword
      description: >
        The ID of the indicator.

    - name: last_online
      type: date

Alternatively, if the raw value should be retained, remove abusech.url.first_seen from the remove_97e5a966 processor's field list and update the expected fixtures.


🤖 AI-Generated Review | Vera Review Bot | 📚 Knowledge base: integration-skills

⚠️ Automated review — verify suggestions before applying.

Comment thread packages/ti_abusech/changelog.yml Outdated
changes:
- description: Add Commercial API support for the URLhaus data stream.
type: enhancement
link: https://github.com/elastic/integrations/pull/20134

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Severity: 🟡 Medium confidence: high path: packages/ti_abusech/changelog.yml:6

Changelog links a different PR number

Details

This changelog entry's link: points at pull/1, but it was added in PR #​20380. It is likely a leftover template placeholder or a copy from another PR.

Recommendation:

Point the changelog link at this PR:

link: https://github.com/elastic/integrations/pull/20380

🤖 AI-Generated Review | Vera Review Bot | 📚 Knowledge base: integration-skills

⚠️ Automated review — verify suggestions before applying.

link: https://github.com/elastic/integrations/pull/20134
- description: Add YARAify data stream with Community and Commercial API support.
type: enhancement
link: https://github.com/elastic/integrations/pull/20134

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Severity: 🟡 Medium confidence: high path: packages/ti_abusech/changelog.yml:9

Changelog links a different PR number

Details

This changelog entry's link: points at pull/1, but it was added in PR #​20380. It is likely a leftover template placeholder or a copy from another PR.

Recommendation:

Point the changelog link at this PR:

link: https://github.com/elastic/integrations/pull/20380

🤖 AI-Generated Review | Vera Review Bot | 📚 Knowledge base: integration-skills

⚠️ Automated review — verify suggestions before applying.

:
string(resp.Status) + ' (' + string(resp.StatusCode) + ')'
),
duration(state.interval_value) > duration("72h") ?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Severity: 🟠 High confidence: high path: packages/ti_abusech/data_stream/url/agent/stream/cel.yml.hbs:162

The rewrite dropped the /downloads/json deprecated-endpoint guard from the community branch; restore it ahead of the interval check so the documented configuration error is still emitted.

Details

Before this change the program's first branch was state.url.contains("/downloads/json"), which emitted a configuration_error telling the user to move off the deprecated URLhaus full-export endpoint. The rewritten program only keeps the 72h interval guard in the community branch, so that check is gone.

Two things break as a result:

  1. packages/ti_abusech/data_stream/url/_dev/test/scripts/deprecated_url.txt (unchanged by this PR, still in the tree) configures url: http://abusech-mock:8080/downloads/json, waits for exactly one document and asserts stdout 'deprecated full export endpoint'. With the guard removed no error event is produced at all — the mock returns {}, has(body.urls) is false, and the program yields zero events — so get_docs -want 1 times out and the test fails.
  2. packages/ti_abusech/docs/README.md line 120 still tells upgrading users "the integration will log an error: the URL is set to the deprecated full export endpoint (/downloads/json) which is no longer supported". That statement is now false, and a user who upgraded from 3.x and never edited the URL setting silently collects nothing instead of getting a diagnosable error.

Recommendation:

Reinstate the guard as the first test inside the community branch, before the interval check:

    :
      state.url.contains("/downloads/json") ?
        {
          "events": {
            "error": {
              "code": "400",
              "id": "configuration_error",
              "message": "the URL is set to the deprecated full export endpoint (/downloads/json) which is no longer supported. Update the URL setting to https://urlhaus-api.abuse.ch/v1/urls/recent/",
            },
          },
          "want_more": false,
        }
      : duration(state.interval_value) > duration("72h") ?
        {
          "events": {
            "error": {
              "code": "400",
              "id": "configuration_error",
              "message": "the polling interval (" + state.interval_value + ") exceeds the 3-day window of the URLhaus recent API. Reduce the interval to 72h or less to avoid missing data.",
            },
          },
          "want_more": false,
        }
      :
        request("GET", state.url).with({

Remember to regenerate the three affected _dev/test/policy/*.expected files after the change.


🤖 AI-Generated Review | Vera Review Bot | 📚 Knowledge base: integration-skills

⚠️ Automated review — verify suggestions before applying.


- Configure **Auth Key**.
- Configure **Auth Key** for Community API datasets.
- For ThreatFox Commercial API collection, set **API Type** to **Commercial API**, set the **URL** to the commercial API base URL (for example `https://api.spamhaus.com`), and configure **Username** and **Password**.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Severity: 🟠 High confidence: high path: packages/ti_abusech/_dev/build/docs/README.md:90

The README source template and the generated docs/README.md have diverged in two places; update the template so a rebuild reproduces the committed README.

Details

docs/README.md is generated from this template, so the two must agree. They currently do not:

  • Template line 90 says "For ThreatFox Commercial API collection..." while generated docs/README.md line 90 says "For URLhaus, MalwareBazaar, or YARAify Commercial API collection...". ThreatFox commercial support is PR 20134, a different branch; it is not part of this package version's commercial support set.
  • Template line 21 still has the old MalwareBazaar bullet (Collects malware payloads from MalwareBazaar via [MalwareBazaar API]...) while generated docs/README.md line 21 has the Community/Commercial wording.

Because the template is the source of truth, elastic-package build regenerates docs/README.md from it and the docs-up-to-date check fails. If it is regenerated as-is, the shipped README loses the MalwareBazaar commercial note and tells users the API Type toggle applies to ThreatFox, which this version does not support.

Recommendation:

Bring the template in line with the intended (and already-generated) content, then re-run elastic-package build so the two files match:

- `malwarebazaar`: Collects malware payloads from MalwareBazaar via the Community [MalwareBazaar API](https://bazaar.abuse.ch/api/#latest_additions) or the Commercial API (`GET /malwarebazaar/v1/samples`). Community API uses Auth Key; Commercial API requires username and password from the [Spamhaus Customer Portal](https://portal.spamhaus.com).
        - For URLhaus, MalwareBazaar, or YARAify Commercial API collection, set **API Type** to **Commercial API**, set the **URL** to the commercial API base URL (for example `https://api.spamhaus.com`), and configure **Username** and **Password**.

🤖 AI-Generated Review | Vera Review Bot | 📚 Knowledge base: integration-skills

⚠️ Automated review — verify suggestions before applying.


#### YARAify

{{fields "yaraify"}}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Severity: 🟡 Medium confidence: high path: packages/ti_abusech/_dev/build/docs/README.md:199

The Example event section for YARAify calls {{fields "yaraify"}} instead of {{event "yaraify"}}, so the field table is rendered twice and the sample event never appears.

Details

Line 169 already emits {{fields "yaraify"}} under the "Exported fields" section. Line 199 sits under ### Example event, after {{event "url"}}, but repeats {{fields "yaraify"}}. The generated docs/README.md confirms the effect: the identical YARAify field table is rendered twice (once at line ~404 and again at line ~950) and no YARAify example event is shown, even though packages/ti_abusech/data_stream/yaraify/sample_event.json exists and is ready to be rendered.

Recommendation:

Use the event helper in the Example event section:

#### YARAify

{{event "yaraify"}}

Then re-run elastic-package build to regenerate docs/README.md.


🤖 AI-Generated Review | Vera Review Bot | 📚 Knowledge base: integration-skills

⚠️ Automated review — verify suggestions before applying.

Comment thread packages/ti_abusech/changelog.yml Outdated
changes:
- description: Add Commercial API support for the URLhaus data stream.
type: enhancement
link: https://github.com/elastic/integrations/pull/20134

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Severity: 🟡 Medium confidence: high path: packages/ti_abusech/changelog.yml:6

Both new changelog entries link to PR 20134 (the ThreatFox commercial-API PR) rather than this PR; point them at 20380.

Details

Lines 6 and 9 both set link: https://github.com/elastic/integrations/pull/20134. PR 20134 is titled "[AbuseCH] Add Commercial API support for the ThreatFox data stream" and is a separate open PR — it does not contain the URLhaus commercial support or the YARAify data stream added here. The changelog link is what users follow from the package changelog to find the change, so both entries currently point at unrelated work. The neighbouring MalwareBazaar entry correctly references its own PR (20199), which shows the intended convention.

Recommendation:

Point both new entries at this PR:

- version: "4.2.0"
  changes:
    - description: Add Commercial API support for the URLhaus data stream.
      type: enhancement
      link: https://github.com/elastic/integrations/pull/20380
    - description: Add YARAify data stream with Community and Commercial API support.
      type: enhancement
      link: https://github.com/elastic/integrations/pull/20380

🤖 AI-Generated Review | Vera Review Bot | 📚 Knowledge base: integration-skills

⚠️ Automated review — verify suggestions before applying.

Comment thread packages/ti_abusech/manifest.yml Outdated
conditions:
kibana:
version: "^8.19.0 || ^9.1.0"
version: "^9.1.0"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Severity: 🟡 Medium confidence: medium path: packages/ti_abusech/manifest.yml:12

The Kibana constraint is narrowed from ^8.19.0 || ^9.1.0 to ^9.1.0, dropping 8.19 support with no changelog entry explaining it.

Details

This is an existing package (4.1.x releases already shipped) and the change makes 4.2.0 uninstallable and un-upgradable on 8.19 stacks that run 4.1.2 today. Nothing in the diff obviously forces the bump: required_vars is accepted from package-spec 3.3.2, which this package already declared before the format_version bump to 3.4.2, and it was already paired with ^8.19.0 || ^9.1.0 on main. The PR's own packages/ti_abusech/data_stream/url/sample_event.json was regenerated on an 8.19.0 agent, which suggests 8.19 is still an active test target.

The changelog for 4.2.0 contains only two enhancement entries and says nothing about raising the minimum stack version, so 8.19 users get no warning about why the upgrade disappears.

Recommendation:

Either keep 8.19 in the constraint:

conditions:
  kibana:
    version: "^8.19.0 || ^9.1.0"

or, if a 9.1-only feature really is required, record the drop explicitly in changelog.yml and name the feature:

- version: "4.2.0"
  changes:
    - description: Raise the minimum Kibana version to 9.1.0.
      type: breaking-change
      link: https://github.com/elastic/integrations/pull/20380

🤖 AI-Generated Review | Vera Review Bot | 📚 Knowledge base: integration-skills

⚠️ Automated review — verify suggestions before applying.

"name": "elastic-agent-40794",
"type": "filebeat",
"version": "9.3.1"
"version": "8.19.0"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Severity: 🟡 Medium confidence: medium path: packages/ti_abusech/data_stream/url/sample_event.json:22

The URL sample event was regenerated on an 8.19 stack and lost event.module, labels.is_ioc_transform_source and threat.feed.*; regenerate it on the same 9.x stack used for the YARAify sample.

Details

The agent version in this file moved from 9.3.1 to 8.19.0, and in the same regeneration the document lost event.module, labels.is_ioc_transform_source and the whole threat.feed object (name, dashboard_id). Those are the constant_keyword values declared in data_stream/url/fields/base-fields.yml and fields/is-ioc-transform-source-true.yml; they only materialise into _source on stacks where the logs data stream uses synthetic source, which is why the older 9.3.1 capture had them and the 8.19.0 capture does not.

The result is a README that documents threat.feed.name, threat.feed.dashboard_id, event.module and labels.is_ioc_transform_source as exported fields for url while the rendered example event no longer shows any of them. It is also internally inconsistent with the new data_stream/yaraify/sample_event.json added in this same PR, which was captured on a 9.1.0 agent and does still contain all four.

Recommendation:

Re-run the URL system test on the same 9.x stack used for YARAify and commit the resulting sample so the block again carries the constant_keyword fields:

    "labels": {
        "is_ioc_transform_source": "true"
    },
    "threat": {
        "feed": {
            "dashboard_id": "ti_abusech-c0d8d1f0-3b20-11ec-ae50-2fdf1e96c6a6",
            "name": "AbuseCH URL"
        },
        "indicator": {

If the URL sample did not actually need to change in this PR, reverting it is also fine.


🤖 AI-Generated Review | Vera Review Bot | 📚 Knowledge base: integration-skills

⚠️ Automated review — verify suggestions before applying.

if: ctx.threat?.indicator?.marking?.tlp == null

- set:
field: threat.indicator.type

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Severity: 🟡 Medium confidence: medium path: packages/ti_abusech/data_stream/yaraify/elasticsearch/ingest_pipeline/default.yml:263

threat.indicator.type is only set when a yarahub_reference_md5 is present, so rules without one are indexed with no indicator type; add an unknown fallback.

Details

The only processor that sets threat.indicator.type is guarded by if: ctx.threat?.indicator?.file?.hash?.md5 != null. YARAify rules frequently omit yarahub_reference_md5 — two of the three documents in _dev/test/pipeline/test-yaraify-sample.log-expected.json and one of the two in test-yaraify-community-sample.log-expected.json come out with a populated threat.indicator.* object but no threat.indicator.type.

Those documents still flow through elasticsearch/transform/latest_yaraify into logs-ti_abusech_latest.yaraify, where the Security CTI views and indicator-match rules key off threat.indicator.type to decide how to interpret an indicator. Untyped indicators are silently skipped there. threat.indicator.type is also declared in elasticsearch/transform/latest_yaraify/fields/ecs.yml, so the mapping expects it to be present.

Recommendation:

Keep the file mapping and add a default immediately after it, mirroring how threat.indicator.marking.tlp already defaults to CLEAR in this pipeline:

  - set:
      field: threat.indicator.type
      tag: set_threat_indicator_type_file
      value: file
      if: ctx.threat?.indicator?.file?.hash?.md5 != null
  - set:
      field: threat.indicator.type
      tag: set_threat_indicator_type_default
      value: unknown
      if: ctx.threat?.indicator?.type == null && ctx.threat?.indicator?.name != null

Update the two pipeline expected-output files accordingly.


🤖 AI-Generated Review | Vera Review Bot | 📚 Knowledge base: integration-skills

⚠️ Automated review — verify suggestions before applying.

).do_request().as(resp, (resp.StatusCode == 200) ?
resp.Body.decode_json().as(body,
{
"events": has(body.data) ?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Severity: 🔵 Low confidence: medium path: packages/ti_abusech/data_stream/yaraify/agent/stream/cel.yml.hbs:194

The YARAify community branch ignores query_status, so an API-level error returned with HTTP 200 produces zero events and no error.message; check it as the MalwareBazaar program does.

Details

The community request handler only does has(body.data) ? body.data.map(...) : []. The YARAify Community API answers with HTTP 200 and a query_status field, and for anything other than ok (for example an unknown or rejected query, or an auth problem surfaced in the body) it returns no data key. The program therefore treats it as an empty poll: no events, no error.message, nothing in the request tracer output for an operator to find. The data stream just looks idle.

The sibling data_stream/malwarebazaar/agent/stream/cel.yml.hbs already handles this correctly (lines 170-186), branching on body.?query_status == optional.of("ok") / "no_results" and emitting an error event otherwise. This is new code, so it should follow the better of the two existing patterns in the package.

Recommendation:

Branch on query_status before mapping the payload:

      ).do_request().as(resp, (resp.StatusCode == 200) ?
        resp.Body.decode_json().as(body, body.?query_status == optional.of("ok") ?
          {
            "events": body.data.map(item, { "message": item.encode_json() }),
            "want_more": false,
          }
        : body.?query_status == optional.of("no_result") ?
          {
            "events": [],
            "want_more": false,
          }
        :
          {
            "events": {
              "error": {
                ?"id": body.?query_status,
                "message": "POST " + state.url.trim_right("/") + ": " + string(resp.Body),
              },
            },
            "want_more": false,
          }
        )

Regenerate the three _dev/test/policy/*.expected files after the change.


🤖 AI-Generated Review | Vera Review Bot | 📚 Knowledge base: integration-skills

⚠️ Automated review — verify suggestions before applying.

Comment thread packages/ti_abusech/changelog.yml Outdated
changes:
- description: Add Commercial API support for the URLhaus data stream.
type: enhancement
link: https://github.com/elastic/integrations/pull/20134

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Severity: 🟡 Medium confidence: high path: packages/ti_abusech/changelog.yml:6

Changelog links a different PR number

Details

This changelog entry's link: points at pull/20134, but it was added in PR #​20380. It is likely a leftover template placeholder or a copy from another PR.

Recommendation:

Point the changelog link at this PR:

link: https://github.com/elastic/integrations/pull/20380

🤖 AI-Generated Review | Vera Review Bot | 📚 Knowledge base: integration-skills

⚠️ Automated review — verify suggestions before applying.

link: https://github.com/elastic/integrations/pull/20134
- description: Add YARAify data stream with Community and Commercial API support.
type: enhancement
link: https://github.com/elastic/integrations/pull/20134

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Severity: 🟡 Medium confidence: high path: packages/ti_abusech/changelog.yml:9

Changelog links a different PR number

Details

This changelog entry's link: points at pull/20134, but it was added in PR #​20380. It is likely a leftover template placeholder or a copy from another PR.

Recommendation:

Point the changelog link at this PR:

link: https://github.com/elastic/integrations/pull/20380

🤖 AI-Generated Review | Vera Review Bot | 📚 Knowledge base: integration-skills

⚠️ Automated review — verify suggestions before applying.

@andrewkroh andrewkroh added the dashboard Relates to a Kibana dashboard bug, enhancement, or modification. label Jul 28, 2026
Comment on lines +239 to +255
params:
"TLP:WHITE": CLEAR
"WHITE": CLEAR
"TLP:GREEN": GREEN
"GREEN": GREEN
"TLP:AMBER": AMBER
"AMBER": AMBER
"TLP:RED": RED
"RED": RED
source: |-
String tlp = ctx.abusech.yaraify.yarahub_rule_matching_tlp;
if (params.containsKey(tlp)) {
ctx.threat = ctx.threat ?: [:];
ctx.threat.indicator = ctx.threat.indicator ?: [:];
ctx.threat.indicator.marking = ctx.threat.indicator.marking ?: [:];
ctx.threat.indicator.marking.tlp = params[tlp];
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This can be done more cheaply by prefix-trimming "TLP:" from the string and conditionally changing "WHITE" to "CLEAR", assuming that the params map is the full set of values that can be in the input field.

String tlp = ctx.abusech.yaraify.yarahub_rule_matching_tlp;
if (tlp.startsWith("TLP:")) {
    tlp = tlp.substring("TLP:".length());
}
if (tlp == "WHITE") {
    tlp = "CLEAR";
}
…

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You will need to elastic-package build.

"field": "event.module",
"indexRefName": "kibanaSavedObjectMeta.searchSourceJSON.filter[0].meta.index",
"key": "event.module",
"key": "threat.indicator.type",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This appears to be ANDed with other values for threat.indicator.type resulting in a tautology. Can you check this?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, let me check

"alias": null,
"disabled": false,
"field": "event.module",
"field": "threat.indicator.type",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same issue here.

"field": "threat.indicator.type",
"indexRefName": "kibanaSavedObjectMeta.searchSourceJSON.filter[4].meta.index",
"key": "threat.indicator.file.hash.ssdeep",
"key": "threat.indicator.type",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And here.

# newer versions go on top
- version: "4.4.0"
changes:
- description: Add Commercial API support for the URLhaus data stream.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Severity: 🟠 High confidence: high path: packages/ti_abusech/changelog.yml:4

These changes are appended to version 4.2.0, which is already released on main - add a new - version: "4.3.0" block instead and bump version in manifest.yml to match.

Details

Version 4.2.0 is the version currently on main: I fetched packages/ti_abusech/manifest.yml from the default branch and it reads version: "4.2.0" (blob sha c0eaa5b92d1, identical to this PR's base blob), and the 4.2.0 changelog block already carries the MalwareBazaar entry from PR 20199, which is MERGED. This PR appends two new entries to that released block and leaves manifest.yml at 4.2.0, so the package content changes without a version change. Republishing an already-published version is rejected by the publishing pipeline. Separately, this PR narrows conditions.kibana.version from "^8.19.0 || ^9.1.0" to "^9.1.0" (manifest.yml line 12), dropping Kibana/stack 8.19 support, and that user-visible support drop is not recorded anywhere in the changelog.

Recommendation:

Open a new version block and bump manifest.yml to match. A new data stream plus a dropped stack version warrants at least a minor bump:

# newer versions go on top
- version: "4.3.0"
  changes:
    - description: Add Commercial API support for the URLhaus data stream.
      type: enhancement
      link: https://github.com/elastic/integrations/pull/20380
    - description: Add YARAify data stream with Community and Commercial API support.
      type: enhancement
      link: https://github.com/elastic/integrations/pull/20380
    - description: Require Kibana 9.1.0 or newer. Support for Kibana 8.19 is dropped.
      type: breaking-change
      link: https://github.com/elastic/integrations/pull/20380
- version: "4.2.0"
  changes:
    - description: Add Commercial API support for the MalwareBazaar data stream.
      type: enhancement
      link: https://github.com/elastic/integrations/pull/20199

and in packages/ti_abusech/manifest.yml:

version: "4.3.0"

🤖 AI-Generated Review | Vera Review Bot | 📚 Knowledge base: integration-skills

⚠️ Automated review — verify suggestions before applying.

changes:
- description: Add Commercial API support for the URLhaus data stream.
type: enhancement
link: https://github.com/elastic/integrations/pull/20380

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Severity: 🟠 High confidence: high path: packages/ti_abusech/changelog.yml:6

Both new changelog entries link to PR 20134 instead of this PR (20380) - the check_changelog_entries CI step fails on this, so update both link: values.

Details

Lines 6 and 9 both point at https://github.com/elastic/integrations/pull/20134. I checked that PR: it is a different, still-OPEN pull request titled "[AbuseCH] Add Commercial API support for the ThreatFox data stream". .buildkite/scripts/check_changelog_entries.sh greps every added link: line and hard-fails (exit 1) with "unexpected link" whenever it is not exactly the URL of the PR under test, so this build cannot go green as written. The neighbouring 4.2.0 entry correctly carries its own originating PR (20199), confirming the one-link-per-PR convention.

Recommendation:

Point both entries at this PR:

    - description: Add Commercial API support for the URLhaus data stream.
      type: enhancement
      link: https://github.com/elastic/integrations/pull/20380
    - description: Add YARAify data stream with Community and Commercial API support.
      type: enhancement
      link: https://github.com/elastic/integrations/pull/20380

🤖 AI-Generated Review | Vera Review Bot | 📚 Knowledge base: integration-skills

⚠️ Automated review — verify suggestions before applying.

)
)
:
state.url.contains("/downloads/json") ?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Severity: 🟠 High confidence: high path: packages/ti_abusech/data_stream/url/agent/stream/cel.yml.hbs:162

The rewrite drops the /downloads/json deprecation guard from the community branch, which breaks the existing deprecated_url.txt system test - re-add the guard ahead of the 72h interval check.

Details

The previous program began the community path with state.url.contains("/downloads/json") ? {..."id": "configuration_error", "message": "the URL is set to the deprecated full export endpoint..."}. The new community branch starts directly at the 72h interval check and the guard is not re-added anywhere in the file. packages/ti_abusech/data_stream/url/_dev/test/scripts/deprecated_url.txt is not touched by this PR and still asserts stdout 'deprecated full export endpoint' against error.message after configuring url: http://abusech-mock:8080/downloads/json; that assertion now has nothing to match. The migration note this guard backs is still live in docs/README.md lines 113-117 and in the 4.0.0 changelog entry, so users who never migrated now get a JSON decode failure on a ZIP body instead of the actionable configuration error.

Recommendation:

Restore the guard as the first branch of the community path:

    :
      state.url.contains("/downloads/json") ?
        {
          "events": {
            "error": {
              "code": "400",
              "id": "configuration_error",
              "message": "the URL is set to the deprecated full export endpoint (/downloads/json) which is no longer supported. Update the URL setting to https://urlhaus-api.abuse.ch/v1/urls/recent/",
            },
          },
          "want_more": false,
        }
      : duration(state.interval_value) > duration("72h") ?

🤖 AI-Generated Review | Vera Review Bot | 📚 Knowledge base: integration-skills

⚠️ Automated review — verify suggestions before applying.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Similar comment here.

@@ -0,0 +1,31 @@
- name: abusech.yaraify

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Severity: 🟠 High confidence: medium path: packages/ti_abusech/data_stream/yaraify/fields/fields.yml:1

The new yaraify data stream has no fields/ecs.yml, so the date-typed ECS field threat.indicator.first_seen it populates is undeclared - add an ecs.yml mirroring the sibling data streams.

Details

data_stream/yaraify/fields/ contains only base-fields.yml, beats.yml, fields.yml and is-ioc-transform-source-true.yml. Every other data stream in this package (url, malwarebazaar, malware, ja3_fingerprints, ...) ships a fields/ecs.yml, and each declares threat.indicator.first_seen as external: ecs precisely because date-typed ECS fields are not covered by the string dynamic templates. The yaraify pipeline sets threat.indicator.first_seen (default.yml line 92) yet nothing in the data stream declares it, so it is mapped from a string value rather than as a date. The mismatch is visible inside this PR: the companion elasticsearch/transform/latest_yaraify/fields/ecs.yml was created and does declare threat.indicator.first_seen plus 21 other ECS fields, so the destination index and the source data stream disagree on the mapping.

Recommendation:

Add packages/ti_abusech/data_stream/yaraify/fields/ecs.yml matching the sibling data streams (data_stream/url/fields/ecs.yml):

- external: ecs
  name: threat.indicator.first_seen

If you want the source data stream to declare the same surface as the new transform, mirror the ECS entries from elasticsearch/transform/latest_yaraify/fields/ecs.yml as well.


🤖 AI-Generated Review | Vera Review Bot | 📚 Knowledge base: integration-skills

⚠️ Automated review — verify suggestions before applying.


#### YARAify

{{event "yaraify"}}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Severity: 🟡 Medium confidence: high path: packages/ti_abusech/_dev/build/docs/README.md:199

The YARAify entry under "Example event" uses {{fields "yaraify"}} instead of {{event "yaraify"}}, so the generated README repeats the exported-fields table and never shows the sample event.

Details

Line 199 sits in the ### Example event section, directly after {{event "url"}} on line 195, but uses the fields helper. Every other entry in that section uses event. The mistake has already propagated into the committed output: packages/ti_abusech/docs/README.md renders the full YARAify exported-fields table a second time under ### Example event, and no YARAify sample event appears anywhere in the README even though data_stream/yaraify/sample_event.json exists.

Recommendation:

Use the event helper, then regenerate docs/README.md with elastic-package build:

#### YARAify

{{event "yaraify"}}

🤖 AI-Generated Review | Vera Review Bot | 📚 Knowledge base: integration-skills

⚠️ Automated review — verify suggestions before applying.


- Configure **Auth Key**.
- Configure **Auth Key** for Community API datasets.
- For Commercial API collection, set **API Type** to **Commercial API**, set the **URL** to the commercial API base URL (for example `https://api.spamhaus.com`), and configure **Username** and **Password**.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Severity: 🟡 Medium confidence: high path: packages/ti_abusech/_dev/build/docs/README.md:90

The new setup step tells users to enable the Commercial API "For ThreatFox", but ThreatFox has no commercial support here - name URLhaus, MalwareBazaar and YARAify instead.

Details

data_stream/threatfox/ contains no reference to api_type, username or password; its CEL template is community-only. The package's own variable descriptions contradict this line: the root manifest.yml api_type description says "Select the abuse.ch API to use for URLhaus, MalwareBazaar, and YARAify... Other data streams always use the Community API", and the username/password descriptions scope commercial to the same three. The ThreatFox wording appears to have been carried over from PR 20134, which is the separate open PR that adds ThreatFox commercial support. The identical line also exists at packages/ti_abusech/docs/README.md line 90 and needs regenerating.

Recommendation:

Name the data streams that actually support the Commercial API in this version:

        - For URLhaus, MalwareBazaar, or YARAify Commercial API collection, set **API Type** to **Commercial API**, set the **URL** to the commercial API base URL (for example `https://api.spamhaus.com`), and configure **Username** and **Password**.

🤖 AI-Generated Review | Vera Review Bot | 📚 Knowledge base: integration-skills

⚠️ Automated review — verify suggestions before applying.

value: file
if: ctx.threat?.indicator?.file?.hash?.md5 != null

- append:

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Severity: 🟡 Medium confidence: high path: packages/ti_abusech/data_stream/yaraify/elasticsearch/ingest_pipeline/default.yml:263

threat.indicator.type is only set when a reference MD5 is present, so YARA rules without one are indexed with no indicator type - add a default so every document is typed.

Details

set_threat_indicator_type_file is gated on ctx.threat?.indicator?.file?.hash?.md5 != null, and yarahub_reference_md5 is optional in the feed. This PR's own fixtures prove the gap: in _dev/test/pipeline/test-yaraify-community-sample.log-expected.json the second document (win_othermw) has threat.indicator.name, description, first_seen and marking.tlp but no threat.indicator.type at all, and the same holds for the second and third documents in test-yaraify-sample.log-expected.json and for sample_event.json. Indicators without threat.indicator.type are not usable by the Threat Intelligence UI or by indicator-match rules, and the latest_yaraify transform declares the field, so the destination index carries a column that is empty for most rows. Every other data stream in this package sets an unconditional type (the url pipeline sets threat.indicator.type: url outright).

Recommendation:

Keep the file specialisation, then fall back to an allowed ECS value for untyped rules:

  - set:
      field: threat.indicator.type
      tag: set_threat_indicator_type_file
      value: file
      if: ctx.threat?.indicator?.file?.hash?.md5 != null
  - set:
      field: threat.indicator.type
      tag: set_threat_indicator_type_unknown
      value: unknown
      if: ctx.threat?.indicator?.type == null

🤖 AI-Generated Review | Vera Review Bot | 📚 Knowledge base: integration-skills

⚠️ Automated review — verify suggestions before applying.

changes:
- description: Add Commercial API support for the URLhaus data stream.
type: enhancement
link: https://github.com/elastic/integrations/pull/20380

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Severity: 🟡 Medium confidence: high path: packages/ti_abusech/changelog.yml:6

Changelog links a different PR number

Details

This changelog entry's link: points at pull/20134, but it was added in PR #​20380. It is likely a leftover template placeholder or a copy from another PR.

Recommendation:

Point the changelog link at this PR:

link: https://github.com/elastic/integrations/pull/20380

🤖 AI-Generated Review | Vera Review Bot | 📚 Knowledge base: integration-skills

⚠️ Automated review — verify suggestions before applying.

link: https://github.com/elastic/integrations/pull/20380
- description: Add YARAify data stream with Community and Commercial API support.
type: enhancement
link: https://github.com/elastic/integrations/pull/20380

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Severity: 🟡 Medium confidence: high path: packages/ti_abusech/changelog.yml:9

Changelog links a different PR number

Details

This changelog entry's link: points at pull/20134, but it was added in PR #​20380. It is likely a leftover template placeholder or a copy from another PR.

Recommendation:

Point the changelog link at this PR:

link: https://github.com/elastic/integrations/pull/20380

🤖 AI-Generated Review | Vera Review Bot | 📚 Knowledge base: integration-skills

⚠️ Automated review — verify suggestions before applying.

@@ -0,0 +1,31 @@
- name: abusech.yaraify

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Severity: 🟠 High confidence: high path: packages/ti_abusech/data_stream/yaraify/fields/fields.yml:1

The new yaraify data stream ships no fields/ecs.yml, so every ECS field its pipeline writes is undeclared; add an ecs.yml listing them with external: ecs.

Details

packages/ti_abusech/data_stream/yaraify/fields/ contains only base-fields.yml, beats.yml, fields.yml and is-ioc-transform-source-true.yml. Every other data stream in this package (url, malware, malwarebazaar, threatfox, sslblacklist, ja3_fingerprints) also has an ecs.yml, and the companion transform elasticsearch/transform/latest_yaraify/fields/ecs.yml declares exactly the ECS fields that are missing here.

The yaraify pipeline populates ecs.version, event.kind, event.category, event.type, event.id, event.original, error.message, tags, related.user, related.hash, rule.name, user.name, threat.indicator.name, threat.indicator.description, threat.indicator.type, threat.indicator.first_seen, threat.indicator.reference, threat.indicator.marking.tlp and threat.indicator.file.hash.md5 -- none of which are declared for the data stream.

The effect is already visible in the generated documentation committed in this PR: the 'YARAify -> Exported fields' table in packages/ti_abusech/docs/README.md (lines 406-427) lists only @​timestamp, the abusech.yaraify.* custom fields, data_stream., event.dataset, event.module, input.type, labels.is_ioc_transform_source and threat.feed.. Compare it with the 'URL' table immediately above, which documents threat.indicator.first_seen, threat.indicator.last_seen and the rest. Users of the new data stream get no field reference for the ECS fields the pipeline actually produces, and the source index mapping falls back to dynamic mapping instead of the ECS definitions the transform destination index uses.

Recommendation:

Add packages/ti_abusech/data_stream/yaraify/fields/ecs.yml mirroring the declarations already written for the transform in elasticsearch/transform/latest_yaraify/fields/ecs.yml:

- external: ecs
  name: ecs.version
- external: ecs
  name: error.message
- external: ecs
  name: tags
- external: ecs
  name: related.hash
- external: ecs
  name: related.user
- external: ecs
  name: event.kind
- external: ecs
  name: event.category
- external: ecs
  name: event.type
- external: ecs
  name: event.id
- external: ecs
  name: event.original
- external: ecs
  name: rule.name
- external: ecs
  name: user.name
- external: ecs
  name: threat.indicator.name
- external: ecs
  name: threat.indicator.description
- external: ecs
  name: threat.indicator.type
- external: ecs
  name: threat.indicator.first_seen
- external: ecs
  name: threat.indicator.reference
- external: ecs
  name: threat.indicator.marking.tlp
- external: ecs
  name: threat.indicator.file.hash.md5

Then regenerate docs/README.md with elastic-package build.


🤖 AI-Generated Review | Vera Review Bot | 📚 Knowledge base: integration-skills

⚠️ Automated review — verify suggestions before applying.

field: threat.indicator.type
tag: set_threat_indicator_type_file
value: file
if: ctx.threat?.indicator?.file?.hash?.md5 != null

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Severity: 🟡 Medium confidence: high path: packages/ti_abusech/data_stream/yaraify/elasticsearch/ingest_pipeline/default.yml:261

threat.indicator.type is only set when yarahub_reference_md5 is present, so YARA rules without a reference hash are indexed with no indicator type; add an 'unknown' fallback like the url pipeline has.

Details

set_threat_indicator_type_file is the only processor that assigns threat.indicator.type, and it is guarded by if: ctx.threat?.indicator?.file?.hash?.md5 != null. Rules that carry no yarahub_reference_md5 therefore end up with no threat.indicator.type at all.

This is not hypothetical -- it is visible in the fixtures committed by this PR. In _dev/test/pipeline/test-yaraify-sample.log-expected.json documents 2 and 3 (win_othermw, win_samplemw) and in test-yaraify-community-sample.log-expected.json document 2, the threat.indicator object contains description, first_seen, marking.tlp and name but no type. The same gap is present in the committed sample_event.json.

threat.indicator.type is the field the Security threat-intel UI and indicator-match rules use to classify an indicator, and it is declared in the latest_yaraify transform's ecs.yml, so the destination index expects it. The url data stream pipeline in this same package already handles this with a trailing set_threat_indicator_type_ac7917ab processor that defaults the value to unknown.

Recommendation:

Add a fallback after the existing set_threat_indicator_type_file processor, matching the pattern already used in data_stream/url/elasticsearch/ingest_pipeline/default.yml:

  - set:
      field: threat.indicator.type
      tag: set_threat_indicator_type_default
      value: unknown
      if: ctx.threat?.indicator?.type == null

Regenerate the affected *-expected.json fixtures and sample_event.json afterwards.


🤖 AI-Generated Review | Vera Review Bot | 📚 Knowledge base: integration-skills

⚠️ Automated review — verify suggestions before applying.

- name: username
- name: password
vars:
- name: api_type

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Severity: 🟡 Medium confidence: medium path: packages/ti_abusech/manifest.yml:74

Moving api_type/username/password from the malwarebazaar data stream to input-level vars silently resets existing 4.2.x Commercial MalwareBazaar policies to Community; record it as a breaking change and document the migration.

Details

This PR adds api_type, username and password as policy-template input vars in the root manifest, and the same three vars are deleted from data_stream/malwarebazaar/manifest.yml (removed lines 14-42 of that file). Those data-stream vars were introduced in 4.2.0, which already shipped Commercial API support for MalwareBazaar.

On upgrade, a policy that stored api_type: commercial plus username/password at the MalwareBazaar data-stream level loses those values -- Fleet drops vars that no longer exist on the stream, and the newly added input-level api_type resolves to its community default with empty username/password. The MalwareBazaar stream therefore reverts from the Commercial API to the Community API without the user changing anything.

The changelog for 4.4.0 records only two enhancement entries (URLhaus Commercial API, new YARAify data stream). Neither the variable relocation nor its upgrade impact is mentioned anywhere in changelog.yml or in _dev/build/docs/README.md.

Recommendation:

Record the relocation explicitly in packages/ti_abusech/changelog.yml and add a migration note to _dev/build/docs/README.md:

- version: "4.4.0"
  changes:
    - description: Move `API Type`, `Username` and `Password` from the MalwareBazaar data stream to integration-level settings. Existing policies using the MalwareBazaar Commercial API must reconfigure these settings after upgrading.
      type: breaking-change
      link: https://github.com/elastic/integrations/pull/20380
    - description: Add Commercial API support for the URLhaus data stream.
      type: enhancement
      link: https://github.com/elastic/integrations/pull/20380
    - description: Add YARAify data stream with Community and Commercial API support.
      type: enhancement
      link: https://github.com/elastic/integrations/pull/20380

🤖 AI-Generated Review | Vera Review Bot | 📚 Knowledge base: integration-skills

⚠️ Automated review — verify suggestions before applying.

Comment thread packages/ti_abusech/manifest.yml Outdated
conditions:
kibana:
version: "^8.19.0 || ^9.1.0"
version: "^9.1.0"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Severity: 🔵 Low confidence: medium path: packages/ti_abusech/manifest.yml:12

conditions.kibana.version is narrowed from '^8.19.0 || ^9.1.0' to '^9.1.0', dropping 8.19 support with no changelog entry; restore the 8.19 range or record the drop as a breaking change.

Details

The constraint changes from ^8.19.0 || ^9.1.0 to ^9.1.0 in the same commit that bumps format_version from 3.3.2 to 3.4.2. That makes 4.4.0 uninstallable on 8.19 stacks, which will remain on 4.2.0 and therefore never receive the URLhaus Commercial API support or the YARAify data stream.

Nothing added in this PR appears to require Kibana 9.1: the new input-level required_vars block, the select-typed api_type var, secret: true password vars and the latest transform are all supported by the previously declared 8.19 floor. The changelog entries for 4.4.0 are both typed enhancement and make no mention of the narrowed compatibility range.

Recommendation:

If no feature in this PR requires 9.1, restore the previous range:

conditions:
  kibana:
    version: "^8.19.0 || ^9.1.0"

If the narrowing is intentional, name the feature that requires it and record it in changelog.yml:

    - description: Drop support for Kibana 8.19; the integration now requires 9.1.0 or later.
      type: breaking-change
      link: https://github.com/elastic/integrations/pull/20380

🤖 AI-Generated Review | Vera Review Bot | 📚 Knowledge base: integration-skills

⚠️ Automated review — verify suggestions before applying.

# Bump this version to delete, reinstall, and restart the transform during package.
# Version bump is needed if there is any code change in transform.
fleet_transform_version: 0.2.0
settings:

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Severity: 🔵 Low confidence: medium path: packages/ti_abusech/elasticsearch/transform/latest_yaraify/transform.yml:43

The new latest_yaraify transform omits settings.unattended and does not exclude cold/frozen tiers in its source query; add both.

Details

settings contains only num_failure_retries: -1. Without unattended: true the transform does not auto-recover from transient failures such as a temporarily unavailable destination index, and it has to be restarted manually.

The source.query also filters only on must_not: exists: error.message. It does not exclude the data_frozen and data_cold tiers, so once the source data stream ages into those tiers the transform scans expensive storage on every 30s run.

Recommendation:

source:
  index:
    - "logs-ti_abusech.yaraify-*"
  query:
    bool:
      must_not:
        - exists:
            field: error.message
        - terms:
            _tier:
              - data_frozen
              - data_cold

and:

settings:
  unattended: true
  num_failure_retries: -1

🤖 AI-Generated Review | Vera Review Bot | 📚 Knowledge base: integration-skills

⚠️ Automated review — verify suggestions before applying.

tag: set_event_kind
value: enrichment
- set:
field: event.category

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Severity: 🔵 Low confidence: high path: packages/ti_abusech/data_stream/yaraify/elasticsearch/ingest_pipeline/default.yml:59

event.category and event.type are ECS array fields but are written with set in the new yaraify pipeline; use append with allow_duplicates: false.

Details

set_event_category and set_event_type (lines 58-65) assign event.category and event.type with a set processor and a list literal. Both are ECS array fields, and the pipeline standard is to build them with append so that a value added by an earlier stage or by a custom pipeline is not overwritten. Output is identical today because nothing else writes these fields in this brand-new data stream, so this is a convention fix rather than a behavioural bug.

Recommendation:

  - append:
      field: event.category
      tag: append_event_category
      value: threat
      allow_duplicates: false
  - append:
      field: event.type
      tag: append_event_type
      value: indicator
      allow_duplicates: false

🤖 AI-Generated Review | Vera Review Bot | 📚 Knowledge base: integration-skills

⚠️ Automated review — verify suggestions before applying.

description: >-
abuse.ch Auth Key for the Community API. Required when API Type is Community API. See [documentation](https://abuse.ch/blog/community-first/) for details.
abuse.ch Auth Key for the Community API. Required when API Type is Community API for data streams that use the Community API (Threat Fox, Malware Bazaar, URLhaus, YARAify). Not used when API Type is Commercial API. See [documentation](https://abuse.ch/blog/community-first/) for details.
- name: username

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Severity: 🟠 High confidence: medium path: packages/ti_abusech/manifest.yml:98

Moving api_type/username/password from the malwarebazaar stream vars up to the cel input vars discards the values already stored in 4.2.0 policies; keep them reachable or ship an explicit migration note so existing Commercial API users are not silently reverted to Community.

Details

Version 4.2.0 (currently on main) defined api_type, username and password inside packages/ti_abusech/data_stream/malwarebazaar/manifest.yml under streams[0].vars. This PR deletes all three from that file (the malwarebazaar manifest hunk is pure deletion) and re-declares them here at policy_templates[].inputs[].vars. Fleet preserves package-policy var values by name within the same scope; a var that disappears from the data stream scope is dropped on upgrade, and the newly introduced input-level username/password have no default. So an existing policy that was configured for the MalwareBazaar Commercial API loses its stored username and its secret-referenced password on upgrade to 4.4.0, and api_type falls back to its default 'community'. Combined with the new required_vars block on lines 63-72, the upgraded policy also fails the 'commercial' requirement group, so the user has to reconfigure before collection resumes. Neither changelog entry for 4.4.0 records this.

Recommendation:

Either keep the three vars addressable at the data stream level while the input-level copies are introduced, or make the relocation explicit in the changelog so Fleet users know they must re-enter credentials:

# packages/ti_abusech/changelog.yml
- version: "4.4.0"
  changes:
    - description: |
        The `API Type`, `Username (Commercial)` and `Password (Commercial)` settings moved from the
        MalwareBazaar data stream to the shared `Collect abuse.ch logs via API` input so URLhaus and
        YARAify can use them. Existing policies that used the MalwareBazaar Commercial API must set
        **API Type**, **Username** and **Password** again at the integration level after upgrading.
      type: breaking-change
      link: https://github.com/elastic/integrations/pull/20380

🤖 AI-Generated Review | Vera Review Bot | 📚 Knowledge base: integration-skills

⚠️ Automated review — verify suggestions before applying.

@@ -0,0 +1,31 @@
- name: abusech.yaraify

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Severity: 🟠 High confidence: medium path: packages/ti_abusech/data_stream/yaraify/fields/fields.yml:1

The new yaraify data stream ships no fields/ecs.yml, so threat.indicator.first_seen and the other ECS fields the pipeline writes are left to dynamic mapping while latest_yaraify maps them explicitly; add data_stream/yaraify/fields/ecs.yml (and agent.yml) to match the sibling data streams.

Details

packages/ti_abusech/data_stream/yaraify/fields/ contains only base-fields.yml, beats.yml, fields.yml and is-ioc-transform-source-true.yml. Every other data stream in this package ships fields/ecs.yml and fields/agent.yml, and this PR's own elasticsearch/transform/latest_yaraify/fields/ecs.yml declares threat.indicator.first_seen, threat.indicator.type, threat.indicator.marking.tlp, user.name, rule.name, related.hash, related.user, event.id and event.original as external: ecs. The result is that the source data stream index and the transform destination index mapped from the same documents get their mappings from different sources for the same field names. data_stream/url/fields/ecs.yml deliberately declares exactly the threat.indicator date fields (first_seen/last_seen/modified_at) — that file exists because of the 2.3.1 bugfix 'Fix ECS date mapping on threat fields', which is the same date field the yaraify pipeline now populates at lines 122-134 and 176-190 without any declaration. fields/agent.yml (cloud.image.id, host.containerized, host.os.build, host.os.codename) is also absent, and those fields appear in documents produced by the Docker-based system tests.

Recommendation:

Add the missing field files to the data stream, mirroring the transform's declarations:

# packages/ti_abusech/data_stream/yaraify/fields/ecs.yml
- external: ecs
  name: threat.indicator.first_seen
- external: ecs
  name: threat.indicator.type
- external: ecs
  name: threat.indicator.marking.tlp
- external: ecs
  name: threat.indicator.name
- external: ecs
  name: threat.indicator.description
- external: ecs
  name: threat.indicator.reference
- external: ecs
  name: threat.indicator.file.hash.md5
- external: ecs
  name: rule.name
- external: ecs
  name: user.name
- external: ecs
  name: related.user
- external: ecs
  name: related.hash
- external: ecs
  name: event.id

and copy packages/ti_abusech/data_stream/url/fields/agent.yml to packages/ti_abusech/data_stream/yaraify/fields/agent.yml.


🤖 AI-Generated Review | Vera Review Bot | 📚 Knowledge base: integration-skills

⚠️ Automated review — verify suggestions before applying.

field: threat.indicator.type
tag: set_threat_indicator_type_file
value: file
if: ctx.threat?.indicator?.file?.hash?.md5 != null

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Severity: 🟡 Medium confidence: high path: packages/ti_abusech/data_stream/yaraify/elasticsearch/ingest_pipeline/default.yml:261

threat.indicator.type is only set when a rule carries yarahub_reference_md5, so YARAify rules without a reference hash are indexed with no indicator type at all; add an 'unknown' fallback like the url pipeline has.

Details

This set processor is the only thing in the pipeline that assigns threat.indicator.type, and it is guarded by ctx.threat?.indicator?.file?.hash?.md5 != null. Both pipeline test fixtures confirm the gap: in _dev/test/pipeline/test-yaraify-community-sample.log-expected.json and test-yaraify-sample.log-expected.json the second and third documents (win_othermw, win_samplemw — no yarahub_reference_md5) have no threat.indicator.type, and the committed sample_event.json has none either. Every other data stream in the package always ends up with a value; data_stream/url/elasticsearch/ingest_pipeline/default.yml line 228 has an explicit set threat.indicator.type: unknown if ctx.threat?.indicator?.type == null fallback for exactly this reason. Indicators with no threat.indicator.type are excluded from the Threat Intelligence view and from the 'Indicator Type' controls used on the abuse.ch dashboards.

Recommendation:

Add the same fallback the url pipeline uses, after the file-hash branch:

  - set:
      field: threat.indicator.type
      tag: set_threat_indicator_type_file
      value: file
      if: ctx.threat?.indicator?.file?.hash?.md5 != null
  - set:
      field: threat.indicator.type
      tag: set_threat_indicator_type_unknown
      value: unknown
      if: ctx.threat?.indicator?.type == null

🤖 AI-Generated Review | Vera Review Bot | 📚 Knowledge base: integration-skills

⚠️ Automated review — verify suggestions before applying.

Comment thread packages/ti_abusech/changelog.yml Outdated
@@ -1,4 +1,12 @@
# newer versions go on top
- version: "4.4.0"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Severity: 🟡 Medium confidence: high path: packages/ti_abusech/changelog.yml:2

4.4.0 is recorded as two enhancements, but it also narrows conditions.kibana.version from '^8.19.0 || ^9.1.0' to '^9.1.0'; add a breaking-change entry so 8.19 users know the package no longer installs for them.

Details

packages/ti_abusech/manifest.yml changes conditions.kibana.version from '^8.19.0 || ^9.1.0' to '^9.1.0' (needed for the new required_vars block, which requires package-spec 3.4.0 and Kibana 9.1). Dropping a supported stack range is user-visible: an 8.19 deployment running 4.2.0 can no longer upgrade and the package disappears from its integrations list. The package has consistently used type: breaking-change for changes of this class (3.0.0 auth-key requirement, 4.0.0 URL endpoint switch), but both 4.4.0 entries are type: enhancement. Separately, main is currently at 4.2.0, so this bump skips 4.3.0 — worth confirming that is intentional rather than a stale rebase.

Recommendation:

Record the dropped 8.x support explicitly:

- version: "4.4.0"
  changes:
    - description: |
        Kibana constraint narrowed to `^9.1.0`. The package now uses `required_vars`, which requires
        Kibana 9.1.0 or newer; Kibana 8.19 deployments must stay on 4.2.0.
      type: breaking-change
      link: https://github.com/elastic/integrations/pull/20380
    - description: Add Commercial API support for the URLhaus data stream.
      type: enhancement
      link: https://github.com/elastic/integrations/pull/20380
    - description: Add YARAify data stream with Community and Commercial API support.
      type: enhancement
      link: https://github.com/elastic/integrations/pull/20380

🤖 AI-Generated Review | Vera Review Bot | 📚 Knowledge base: integration-skills

⚠️ Automated review — verify suggestions before applying.

type: integer
title: Page Size
multi: false
required: false

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Severity: 🔵 Low confidence: medium path: packages/ti_abusech/data_stream/url/manifest.yml:53

page_size is declared required: false but cel.yml.hbs interpolates it into state unconditionally, so clearing the field renders page_size: (null) and breaks string(state.page_size) in the Commercial branch; mark it required like initial_interval.

Details

data_stream/url/agent/stream/cel.yml.hbs emits page_size: {{page_size}} outside any {{#if}} guard, and the Commercial branch evaluates "page_size": [string(state.page_size)]. If a user clears this optional field in Fleet the template renders page_size: with no value, state.page_size is null, and string() has no matching overload, so the whole CEL program fails to evaluate rather than falling back to the default. initial_interval, which is read the same way, is correctly declared required: true. The new yaraify data stream manifest has the same required: false on page_size.

Recommendation:

Make the value non-clearable, matching initial_interval:

      - name: page_size
        type: integer
        title: Page Size
        multi: false
        required: true
        show_user: false
        default: 100
        description: Number of malware URLs to request per page when using the Commercial API.

Alternatively guard the template so an empty value is simply omitted from state:

{{#if page_size}}
  page_size: {{page_size}}
{{/if}}

🤖 AI-Generated Review | Vera Review Bot | 📚 Knowledge base: integration-skills

⚠️ Automated review — verify suggestions before applying.

@moxarth-rathod
moxarth-rathod requested a review from efd6 August 3, 2026 06:26
@@ -0,0 +1,31 @@
- name: abusech.yaraify

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Severity: 🟠 High confidence: high path: packages/ti_abusech/data_stream/yaraify/fields/fields.yml:1

The new yaraify data stream has no fields/ecs.yml, so every ECS field its pipeline writes is undeclared; add an ecs.yml listing them with external: ecs.

Details

packages/ti_abusech/data_stream/yaraify/fields/ contains only base-fields.yml, beats.yml, fields.yml and is-ioc-transform-source-true.yml. The new ingest pipeline populates a large set of ECS fields that are declared nowhere: threat.indicator.name, threat.indicator.description, threat.indicator.first_seen (date), threat.indicator.type, threat.indicator.reference, threat.indicator.marking.tlp, threat.indicator.file.hash.md5, user.name, rule.name, related.user, related.hash, event.id, event.kind, event.category, event.type, event.original, ecs.version, error.message and tags. Two pieces of evidence that this is an oversight rather than a choice: (a) every sibling data stream in this package (e.g. data_stream/url/fields/) ships a fields/ecs.yml, and (b) the transform added in this same PR, elasticsearch/transform/latest_yaraify/fields/ecs.yml, declares exactly this field list. The consequence is visible in the generated docs: the '#### YARAify' exported-fields table in packages/ti_abusech/docs/README.md lists only abusech.yaraify., data_stream., event.dataset/module, input.type, labels.* and threat.feed.* - no threat.indicator.* rows at all, while the URL and ThreatFox tables include threat.indicator.first_seen/last_seen. Date-typed fields such as threat.indicator.first_seen therefore have no package-provided mapping.

Recommendation:

Add packages/ti_abusech/data_stream/yaraify/fields/ecs.yml mirroring the transform's list:

- external: ecs
  name: ecs.version
- external: ecs
  name: error.message
- external: ecs
  name: tags
- external: ecs
  name: related.hash
- external: ecs
  name: related.user
- external: ecs
  name: event.kind
- external: ecs
  name: event.category
- external: ecs
  name: event.type
- external: ecs
  name: event.id
- external: ecs
  name: event.original
- external: ecs
  name: rule.name
- external: ecs
  name: user.name
- external: ecs
  name: threat.indicator.name
- external: ecs
  name: threat.indicator.description
- external: ecs
  name: threat.indicator.type
- external: ecs
  name: threat.indicator.first_seen
- external: ecs
  name: threat.indicator.reference
- external: ecs
  name: threat.indicator.marking.tlp
- external: ecs
  name: threat.indicator.file.hash.md5

Then regenerate the docs so the YARAify exported-fields table matches the other data streams.


🤖 AI-Generated Review | Vera Review Bot | 📚 Knowledge base: integration-skills

⚠️ Automated review — verify suggestions before applying.

- name: api_type
value: community
- name: auth_key
commercial:

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Severity: 🟠 High confidence: high path: packages/ti_abusech/manifest.yml:68

The commercial required_vars group omits auth_key, but the threatfox and malware data streams are Community-only and enabled by default, so a Commercial install collects nothing from them; add auth_key to the commercial group.

Details

api_type is a single package-level var shared by all data streams, but only url, malwarebazaar and yaraify branch on it. data_stream/threatfox/agent/stream/cel.yml.hbs and data_stream/malware/agent/stream/cel.yml.hbs contain no api_type handling at all - they always call the Community endpoint and send Auth-Key: state.auth_key. Both of those data streams have enabled: true in their manifests. With the required_vars groups as written, a user who selects 'Commercial API' is only prompted for username and password; auth_key is never required and the auth_key description on line 97 tells them it is 'Not used when API Type is Commercial API'. The default policy for a Commercial install therefore ships threatfox and malware with no Auth-Key and their requests are rejected by abuse.ch.

Recommendation:

Require auth_key in both groups, since the Community-only data streams need it regardless of the selected API type:

        required_vars:
          community:
            - name: api_type
              value: community
            - name: auth_key
          commercial:
            - name: api_type
              value: commercial
            - name: auth_key
            - name: username
            - name: password

and correct the auth_key description so it no longer says the key is unused for Commercial:

            description: >-
              abuse.ch Auth Key for the Community API. Always required for the ThreatFox and Malware data streams, which only support the Community API,
              and for URLhaus, MalwareBazaar and YARAify when API Type is Community API. See [documentation](https://abuse.ch/blog/community-first/) for details.

🤖 AI-Generated Review | Vera Review Bot | 📚 Knowledge base: integration-skills

⚠️ Automated review — verify suggestions before applying.

Comment thread packages/ti_abusech/changelog.yml Outdated
@@ -1,4 +1,12 @@
# newer versions go on top
- version: "4.4.0"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Severity: 🟠 High confidence: medium path: packages/ti_abusech/changelog.yml:2

Moving malwarebazaar's api_type/username/password from data-stream vars to package-level input vars drops the values existing 4.2.x commercial users configured; record it as a breaking change and document the re-entry step.

Details

data_stream/malwarebazaar/manifest.yml deletes the api_type, username and password stream vars that 4.2.0 introduced, and packages/ti_abusech/manifest.yml re-adds them as input-level vars on the policy template. Fleet upgrades package policies by matching vars within their own scope, so a stream var that no longer exists in the new manifest is dropped and the new input-level var is initialised from its default (api_type: community). Anyone who configured MalwareBazaar Commercial collection under 4.2.x silently reverts to the Community path with no credentials after upgrading to 4.4.0. The 4.4.0 changelog records only two enhancement entries and says nothing about this relocation. The same release also narrows conditions.kibana.version from ^8.19.0 || ^9.1.0 to ^9.1.0, which blocks the upgrade for 8.x stacks and is likewise unrecorded.

Recommendation:

Add explicit entries so the relocation and the support drop are visible in the release notes, and mention the re-entry step in the README upgrade guidance:

- version: "4.4.0"
  changes:
    - description: |
        Move `API Type`, `Username` and `Password` from the MalwareBazaar data stream to package-level settings.
        Policies that configured MalwareBazaar Commercial collection in 4.2.x must re-enter these values after upgrading.
      type: breaking-change
      link: https://github.com/elastic/integrations/pull/20380
    - description: Drop support for Kibana 8.x; the integration now requires Kibana 9.1.0 or later.
      type: breaking-change
      link: https://github.com/elastic/integrations/pull/20380
    - description: Add Commercial API support for the URLhaus data stream.
      type: enhancement
      link: https://github.com/elastic/integrations/pull/20380
    - description: Add YARAify data stream with Community and Commercial API support.
      type: enhancement
      link: https://github.com/elastic/integrations/pull/20380

🤖 AI-Generated Review | Vera Review Bot | 📚 Knowledge base: integration-skills

⚠️ Automated review — verify suggestions before applying.

Comment thread packages/ti_abusech/manifest.yml Outdated
type: select
title: API Type
description: >-
Select the abuse.ch API to use for ThreatFox, URLhaus, MalwareBazaar, and YARAify. Community API uses an Auth Key.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Severity: 🟡 Medium confidence: high path: packages/ti_abusech/manifest.yml:78

The API Type description lists ThreatFox as a data stream the setting applies to, but ThreatFox has no Commercial support in this PR; drop it from the list.

Details

The description reads 'Select the abuse.ch API to use for ThreatFox, URLhaus, MalwareBazaar, and YARAify.' data_stream/threatfox/agent/stream/cel.yml.hbs has no api_type in its state block and no commercial branch in its CEL program - it always POSTs to the Community ThreatFox endpoint with the Auth-Key header. Selecting 'Commercial API' has no effect on ThreatFox other than removing the auth_key prompt (see finding 2). The auth_key description on line 97 repeats the same list and additionally omits the malware data stream, which also sends Auth-Key.

Recommendation:

List only the data streams that actually branch on api_type:

          - name: api_type
            type: select
            title: API Type
            description: >-
              Select the abuse.ch API to use for URLhaus, MalwareBazaar, and YARAify. Community API uses an Auth Key.
              Commercial API uses Spamhaus credentials and JWT authentication. The ThreatFox, Malware, SSL Blacklist and
              JA3 Fingerprints data streams always use the Community API and always require the Auth Key.

🤖 AI-Generated Review | Vera Review Bot | 📚 Knowledge base: integration-skills

⚠️ Automated review — verify suggestions before applying.


- rename:
field: abusech.yaraify.author
target_field: user.name

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Severity: 🟡 Medium confidence: medium path: packages/ti_abusech/data_stream/yaraify/elasticsearch/ingest_pipeline/default.yml:187

The YARAify pipeline maps the rule author only to user.name, while every other data stream in this package maps the submitter to threat.indicator.provider; also copy author to threat.indicator.provider.

Details

url, malwarebazaar and threatfox all rename their submitter field to threat.indicator.provider (for example rename_abusech_url_reporter_to_threat_indicator_provider_7c166e1f in data_stream/url/elasticsearch/ingest_pipeline/default.yml:153). The YARAify pipeline instead renames abusech.yaraify.author to user.name and never sets threat.indicator.provider, so YARAify indicators are the only ones in this package with no provider attribution in the Kibana threat intel UI or in the latest_yaraify destination index. user.name is also a poor fit for the value: the samples carry display names such as 'Example Author' rather than logins.

Recommendation:

Keep the user.name rename if it is wanted, and add a provider copy next to it:

  - rename:
      field: abusech.yaraify.author
      target_field: user.name
      tag: rename_author_to_user_name
      ignore_missing: true
  - set:
      field: threat.indicator.provider
      tag: set_threat_indicator_provider_from_author
      copy_from: user.name
      if: ctx.user?.name != null

Remember to add threat.indicator.provider to the new data stream fields/ecs.yml (finding 1) and to elasticsearch/transform/latest_yaraify/fields/ecs.yml.


🤖 AI-Generated Review | Vera Review Bot | 📚 Knowledge base: integration-skills

⚠️ Automated review — verify suggestions before applying.

).as(since,
request(
"GET",
state.url.trim_right("/") + "/urlhaus/v1/urls?" + {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Severity: 🔵 Low confidence: medium path: packages/ti_abusech/data_stream/url/agent/stream/cel.yml.hbs:97

Selecting Commercial API while leaving the data stream URL at its Community default builds a nonsense endpoint; add a guard like the existing deprecated-URL check.

Details

api_type is a package-level setting while url stays per data stream, and the url data stream keeps its Community default https://urlhaus-api.abuse.ch/v1/urls/recent/. Switching the package to Commercial without also editing each data stream's URL makes the program request https://urlhaus-api.abuse.ch/v1/urls/recent/v1/login and .../urls/recent/urlhaus/v1/urls. The user only sees a generic non-200 error message. The community branch of this same program already guards a comparable misconfiguration (the deprecated /downloads/json endpoint) with an explicit configuration_error, and the commercial branch already guards missing username/password, so a matching check would be consistent. The yaraify template has the same shape.

Recommendation:

Add a configuration guard at the top of the commercial branch, alongside the existing username/password check:

    state.?api_type.orValue("community") == "commercial" ?
      (
        state.url.contains("urlhaus-api.abuse.ch") ?
          {
            "events": {
              "error": {
                "code": "400",
                "id": "configuration_error",
                "message": "api_type is 'commercial' but the URL is still set to the Community endpoint. Set the URL to the commercial API base URL, for example https://api.spamhaus.com.",
              },
            },
            "want_more": false,
          }
        : !has(state.username) || !has(state.password) ?
          ...

🤖 AI-Generated Review | Vera Review Bot | 📚 Knowledge base: integration-skills

⚠️ Automated review — verify suggestions before applying.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe.

@elastic-vault-github-plugin-prod

Copy link
Copy Markdown
Contributor

🚀 Benchmarks report

To see the full report comment with /test benchmark fullreport

@efd6 efd6 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please go over and address or respond to the Vera comments.

)
)
:
state.url.contains("/downloads/json") ?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Similar comment here.

).as(since,
request(
"GET",
state.url.trim_right("/") + "/urlhaus/v1/urls?" + {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you address the comments for the url data stream, also do it here.

@moxarth-rathod
moxarth-rathod marked this pull request as draft August 7, 2026 05:47
@efd6

efd6 commented Aug 31, 2026

Copy link
Copy Markdown
Contributor

/test

@moxarth-rathod
moxarth-rathod marked this pull request as ready for review August 31, 2026 08:00
@moxarth-rathod
moxarth-rathod requested a review from efd6 August 31, 2026 08:01

@kcreddy kcreddy left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Correct the PR description and commit message

@moxarth-rathod moxarth-rathod changed the title [ti_abusech] Add Commercial API support for url data streams [ti_abusech] Add YARAify data stream and commercial API for URLhaus Sep 2, 2026
moxarth-rathod and others added 2 commits September 3, 2026 12:39
…nsform.yml

Co-authored-by: Krishna Chaitanya Reddy Burri <krish.reddy91@gmail.com>
@vera-review-bot

Copy link
Copy Markdown
Contributor

🟢 No issues across the latest commits fc1ae98.

Review summary

Issues found across earlier commits d9cb765 — 3 high, 2 medium, 1 low
  • 🟠 The new yaraify data stream has no fields/ecs.yml, so every ECS field its pipeline writes is undeclared (link) (Unresolved)
  • 🟠 The commercial required_vars group omits auth_key, but the threatfox and malware data streams are Community-only and enabled by default, so a Commercial install collects nothing from them (link) (Unresolved)
  • 🟠 Moving malwarebazaar's api_type/username/password from data-stream vars to package-level input vars drops the values existing 4.2.x commercial users configured (link) (Unresolved)
  • 🟡 The API Type description lists ThreatFox as a data stream the setting applies to, but ThreatFox has no Commercial support in this PR (link) (Unresolved)
  • 🟡 The YARAify pipeline maps the rule author only to user.name, while every other data stream in this package maps the submitter to threat.indicator.provider (link) (Unresolved)
  • 🔵 Selecting Commercial API while leaving the data stream URL at its Community default builds a nonsense endpoint (link) (Unresolved)
Issues found across earlier commits 0181437 — 2 high, 2 medium, 1 low
  • 🟠 Moving api_type/username/password from the malwarebazaar stream vars up to the cel input vars discards the values already stored in 4.2.0 policies (link) (Unresolved)
  • 🟠 The new yaraify data stream ships no fields/ecs.yml, so threat.indicator.first_seen and the other ECS fields the pipeline writes are left to dynamic mapping while latest_yaraify maps them explicitly (link) (Unresolved)
  • 🟡 threat.indicator.type is only set when a rule carries yarahub_reference_md5, so YARAify rules without a reference hash are indexed with no indicator type at all (link) (Unresolved)
  • 🟡 4.4.0 is recorded as two enhancements, but it also narrows conditions.kibana.version from '^8.19.0 || ^9.1.0' to '^9.1.0' (link) (Unresolved)
  • 🔵 page_size is declared required: false but cel.yml.hbs interpolates it into state unconditionally, so clearing the field renders page_size: (null) and breaks string(state.page_size) in the Commercial branch (link) (Unresolved)
Issues found across earlier commits 5f00644 — 1 high, 2 medium, 3 low
  • 🟠 The new yaraify data stream ships no fields/ecs.yml, so every ECS field its pipeline writes is undeclared (link) (Unresolved)
  • 🟡 threat.indicator.type is only set when yarahub_reference_md5 is present, so YARA rules without a reference hash are indexed with no indicator type (link) (Unresolved)
  • 🟡 Moving api_type/username/password from the malwarebazaar data stream to input-level vars silently resets existing 4.2.x Commercial MalwareBazaar policies to Community (link) (Unresolved)
  • 🔵 conditions.kibana.version is narrowed from '^8.19.0 || ^9.1.0' to '^9.1.0', dropping 8.19 support with no changelog entry (link) (Unresolved)
  • 🔵 The new latest_yaraify transform omits settings.unattended and does not exclude cold/frozen tiers in its source query (link) (Unresolved)
  • 🔵 event.category and event.type are ECS array fields but are written with set in the new yaraify pipeline (link) (Unresolved)
Issues found across earlier commits 98f3fb2 — 4 high, 6 medium
  • 🟠 These changes are appended to version 4.2.0, which is already released on main - add a new - version: "4.3.0" block instead and bump version in manifest.yml to match. (link) (Unresolved)
  • 🟠 Both new changelog entries link to PR 20134 instead of this PR (20380) - the check_changelog_entries CI step fails on this, so update both link: values. (link) (Unresolved)
  • 🟠 The rewrite drops the /downloads/json deprecation guard from the community branch, which breaks the existing deprecated_url.txt system test - re-add the guard ahead of the 72h interval check. (link) (Unresolved)
  • 🟠 The new yaraify data stream has no fields/ecs.yml, so the date-typed ECS field threat.indicator.first_seen it populates is undeclared - add an ecs.yml mirroring the sibling data streams. (link) (Unresolved)
  • 🟡 The YARAify entry under "Example event" uses {{fields "yaraify"}} instead of {{event "yaraify"}}, so the generated README repeats the exported-fields table and never shows the sample event. (link) (Unresolved)
  • 🟡 The new setup step tells users to enable the Commercial API "For ThreatFox", but ThreatFox has no commercial support here - name URLhaus, MalwareBazaar and YARAify instead. (link) (Unresolved)
  • 🟡 threat.indicator.type is only set when a reference MD5 is present, so YARA rules without one are indexed with no indicator type - add a default so every document is typed. (link) (Unresolved)
  • 🟡 The new configuration-error events emit only message, omitting the code and id keys the error shape defines - add them so the failures surface consistently. (link) (Unresolved)
  • 🟡 Changelog links a different PR number (link) (Unresolved)
  • 🟡 Changelog links a different PR number (link) (Unresolved)
Issues found across earlier commits 2f1b703 — 2 high, 7 medium, 1 low
  • 🟠 The rewrite dropped the /downloads/json deprecated-endpoint guard from the community branch (link) (Unresolved)
  • 🟠 The README source template and the generated docs/README.md have diverged in two places (link) (Unresolved)
  • 🟡 The Example event section for YARAify calls {{fields "yaraify"}} instead of {{event "yaraify"}}, so the field table is rendered twice and the sample event never appears. (link) (Unresolved)
  • 🟡 Both new changelog entries link to PR 20134 (the ThreatFox commercial-API PR) rather than this PR (link) (Unresolved)
  • 🟡 The Kibana constraint is narrowed from ^8.19.0 || ^9.1.0 to ^9.1.0, dropping 8.19 support with no changelog entry explaining it. (link) (Unresolved)
  • 🟡 The URL sample event was regenerated on an 8.19 stack and lost event.module, labels.is_ioc_transform_source and threat.feed.* (link) (Unresolved)
  • 🟡 threat.indicator.type is only set when a yarahub_reference_md5 is present, so rules without one are indexed with no indicator type (link) (Unresolved)
  • 🔵 The YARAify community branch ignores query_status, so an API-level error returned with HTTP 200 produces zero events and no error.message (link) (Unresolved)
  • 🟡 Changelog links a different PR number (link) (Unresolved)
  • 🟡 Changelog links a different PR number (link) (Unresolved)
Issues found across earlier commits 21f540c — 3 high, 9 medium, 1 low
  • 🟠 The CEL guard that rejected the deprecated /downloads/json URLhaus endpoint was deleted, so policies still holding that URL now silently collect zero events instead of raising a configuration error (link) (Unresolved)
  • 🟠 Both new changelog entries link to the placeholder PR Initial structure #1 (link) (Unresolved)
  • 🟠 Selecting Commercial API stops Fleet from requiring Auth Key, but threatfox, malware, sslblacklist and ja3_fingerprints always use the Community API and still need it (link) (Unresolved)
  • 🟡 The Example event section renders {{fields "yaraify"}} instead of {{event "yaraify"}}, so the generated README duplicates the exported-fields table and never shows the YARAify sample event. (link) (Unresolved)
  • 🟡 The doc template credits Commercial API support to ThreatFox, which this PR does not add, and it no longer matches the committed docs/README.md - so the next build will regress the rendered README. (link) (Unresolved)
  • 🟡 The YARAify community branch ignores query_status, so an auth or query failure returned with HTTP 200 yields zero events and no error (link) (Unresolved)
  • 🟡 threat.indicator.type is only set when a reference MD5 is present, so YARAify rules without one are indexed with no indicator type (link) (Unresolved)
  • 🟡 The yaraify data stream ships no fields/ecs.yml, so ECS date fields such as threat.indicator.first_seen are left to dynamic mapping in the source index (link) (Unresolved)
  • 🟡 conditions.kibana.version is narrowed from "^8.19.0 || ^9.1.0" to "^9.1.0", dropping 8.19 support in a minor release with no feature that requires it and no changelog note (link) (Unresolved)
  • 🟡 The url sample event was regenerated on an 8.19.0 stack and lost event.module, threat.feed.name, threat.feed.dashboard_id and labels.is_ioc_transform_source (link) (Unresolved)
  • 🔵 abusech.url.first_seen is declared as a field and documented, but the pipeline removes it unconditionally so it can never appear in a document (link) (Unresolved)
  • 🟡 Changelog links a different PR number (link) (Unresolved)
  • 🟡 Changelog links a different PR number (link) (Unresolved)

A new commit triggers another review — at most once every 15 minutes. I skip the PR while it's approved or has merge conflicts.

🤖 AI-Generated Review | Vera Review Bot - v0.3.0 | 📚 Knowledge base: integration-skills

⚠️ Automated review — verify suggestions before applying.

@elastic-vault-github-plugin-prod

Copy link
Copy Markdown
Contributor

✅ All changelog entries have the correct PR link.

@infra-vault-gh-plugin-prod

Copy link
Copy Markdown

💚 Build Succeeded

History

cc @moxarth-rathod

@kcreddy kcreddy left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, please wait for @efd6

@mergify

mergify Bot commented Sep 4, 2026

Copy link
Copy Markdown
Contributor

Tick the box to add this pull request to the merge queue (same as @mergifyio queue).

  • Queue this pull request

@moxarth-rathod
moxarth-rathod merged commit c85e14a into elastic:main Sep 11, 2026
12 checks passed
@elastic-vault-github-plugin-prod

Copy link
Copy Markdown
Contributor

Package ti_abusech - 5.1.0 containing this change is available at https://epr.elastic.co/package/ti_abusech/5.1.0/

kcreddy added a commit to kcreddy/integrations that referenced this pull request Sep 11, 2026
The YARAify change re-exported the ti_abusech dashboards with
useCurrentFilters: false on every link, so this PR's changes to the
package had become pure key reordering plus a no-op version bump.
Restore the package to main.
kcreddy added a commit that referenced this pull request Sep 11, 2026
…ing on dashboard links panels (#21175)

Links panels default to useCurrentFilters: true, which forwards
app-state filters from the source dashboard to the destination.
Kibana then merges those with the destination's saved filters. When
each dashboard carries a dashboard-level dataset filter (for example
data_stream.dataset), navigation via links combines conflicting
filters and panels show no data.

Set useCurrentFilters: false on every dashboardLink in the affected
dashboards. Pinned filters are still forwarded, so analysts can opt in
by pinning a filter before navigating.

For axonius, jupiter_one, and m365_defender, useCurrentDateRange is
set to true, matching Kibana's default so time-range behaviour is
unchanged. For jamf_pro, the Overview link is set to
useCurrentDateRange: false to match the four sibling links in the same
panel, which already had that value.

ti_abusech was originally included but is no longer needed: #20380
re-exported its dashboards with useCurrentFilters: false already set,
so its changes here reduced to key reordering with no effect.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

dashboard Relates to a Kibana dashboard bug, enhancement, or modification. documentation Improvements or additions to documentation. Applied to PRs that modify *.md files. enhancement New feature or request Integration:ti_abusech abuse.ch Team:SDE-Crest Crest developers on the Security Integrations team [elastic/sit-crest-contractors] Team:Security-Service Integrations Security Service Integrations team [elastic/security-service-integrations]

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants