Skip to content

[ti_eset] Add emailattachments data stream - #19138

Open
polakovicp wants to merge 2 commits into
elastic:ti_set_polakovicp_enhancementsfrom
polakovicp:ti_eset_emailattachments
Open

[ti_eset] Add emailattachments data stream#19138
polakovicp wants to merge 2 commits into
elastic:ti_set_polakovicp_enhancementsfrom
polakovicp:ti_eset_emailattachments

Conversation

@polakovicp

@polakovicp polakovicp commented May 21, 2026

Copy link
Copy Markdown
Contributor

[ti_eset] Add emailattachments data stream

PR adds new Email attachments data stream to ti_eset integration. Documentation for this data stream is submitted as a separate PR

Related issues

Relates to PR #18709

Test result

> elastic-package test                                          

--- Test results for package: ti_eset - START ---
╭─────────┬──────────────────┬───────────┬──────────────────────────────────────────────────────────────────┬────────┬──────────────╮
│ PACKAGE │ DATA STREAM      │ TEST TYPE │ TEST NAME                                                        │ RESULT │ TIME ELAPSED │
├─────────┼──────────────────┼───────────┼──────────────────────────────────────────────────────────────────┼────────┼──────────────┤
│ ti_eset │                  │ asset     │ dashboard ti_eset-402bf6b0-8194-11ee-a704-a3364df0a052 is loaded │ PASS   │           0s │
│ ti_eset │                  │ asset     │ dashboard ti_eset-4fc91930-819a-11ee-a704-a3364df0a052 is loaded │ PASS   │           0s │
│ ti_eset │                  │ asset     │ dashboard ti_eset-c27d91e0-819a-11ee-a704-a3364df0a052 is loaded │ PASS   │           0s │
│ ti_eset │                  │ asset     │ dashboard ti_eset-f608e350-8192-11ee-a704-a3364df0a052 is loaded │ PASS   │           0s │
│ ti_eset │ apt              │ asset     │ index_template logs-ti_eset.apt is loaded                        │ PASS   │           0s │
│ ti_eset │ apt              │ asset     │ ingest_pipeline logs-ti_eset.apt-1.10.0 is loaded                │ PASS   │           0s │
│ ti_eset │ botnet           │ asset     │ index_template logs-ti_eset.botnet is loaded                     │ PASS   │           0s │
│ ti_eset │ botnet           │ asset     │ ingest_pipeline logs-ti_eset.botnet-1.10.0 is loaded             │ PASS   │           0s │
│ ti_eset │ cc               │ asset     │ index_template logs-ti_eset.cc is loaded                         │ PASS   │           0s │
│ ti_eset │ cc               │ asset     │ ingest_pipeline logs-ti_eset.cc-1.10.0 is loaded                 │ PASS   │           0s │
│ ti_eset │ domains          │ asset     │ index_template logs-ti_eset.domains is loaded                    │ PASS   │           0s │
│ ti_eset │ domains          │ asset     │ ingest_pipeline logs-ti_eset.domains-1.10.0 is loaded            │ PASS   │           0s │
│ ti_eset │ emailattachments │ asset     │ index_template logs-ti_eset.emailattachments is loaded           │ PASS   │           0s │
│ ti_eset │ emailattachments │ asset     │ ingest_pipeline logs-ti_eset.emailattachments-1.10.0 is loaded   │ PASS   │           0s │
│ ti_eset │ files            │ asset     │ index_template logs-ti_eset.files is loaded                      │ PASS   │           0s │
│ ti_eset │ files            │ asset     │ ingest_pipeline logs-ti_eset.files-1.10.0 is loaded              │ PASS   │           0s │
│ ti_eset │ ip               │ asset     │ index_template logs-ti_eset.ip is loaded                         │ PASS   │           0s │
│ ti_eset │ ip               │ asset     │ ingest_pipeline logs-ti_eset.ip-1.10.0 is loaded                 │ PASS   │           0s │
│ ti_eset │ url              │ asset     │ index_template logs-ti_eset.url is loaded                        │ PASS   │           0s │
│ ti_eset │ url              │ asset     │ ingest_pipeline logs-ti_eset.url-1.10.0 is loaded                │ PASS   │           0s │
╰─────────┴──────────────────┴───────────┴──────────────────────────────────────────────────────────────────┴────────┴──────────────╯
--- Test results for package: ti_eset - END   ---
2026/08/03 11:12:10  INFO elastic-stack: 9.4.2
--- Test results for package: ti_eset - START ---
╭─────────┬──────────────────┬───────────┬─────────────────────────────────────────────────┬────────┬──────────────╮
│ PACKAGE │ DATA STREAM      │ TEST TYPE │ TEST NAME                                       │ RESULT │ TIME ELAPSED │
├─────────┼──────────────────┼───────────┼─────────────────────────────────────────────────┼────────┼──────────────┤
│ ti_eset │ apt              │ pipeline  │ (ingest pipeline warnings test-eset-ndjson.log) │ PASS   │   897.1365ms │
│ ti_eset │ apt              │ pipeline  │ test-eset-ndjson.log                            │ PASS   │   870.9632ms │
│ ti_eset │ botnet           │ pipeline  │ (ingest pipeline warnings test-eset-ndjson.log) │ PASS   │   974.4428ms │
│ ti_eset │ botnet           │ pipeline  │ test-eset-ndjson.log                            │ PASS   │   418.2077ms │
│ ti_eset │ cc               │ pipeline  │ (ingest pipeline warnings test-eset-ndjson.log) │ PASS   │   882.4227ms │
│ ti_eset │ cc               │ pipeline  │ test-eset-ndjson.log                            │ PASS   │   278.7846ms │
│ ti_eset │ domains          │ pipeline  │ (ingest pipeline warnings test-eset-ndjson.log) │ PASS   │   877.2285ms │
│ ti_eset │ domains          │ pipeline  │ test-eset-ndjson.log                            │ PASS   │   155.1631ms │
│ ti_eset │ emailattachments │ pipeline  │ (ingest pipeline warnings test-eset-ndjson.log) │ PASS   │   943.3145ms │
│ ti_eset │ emailattachments │ pipeline  │ test-eset-ndjson.log                            │ PASS   │   159.4435ms │
│ ti_eset │ files            │ pipeline  │ (ingest pipeline warnings test-eset-ndjson.log) │ PASS   │   904.3174ms │
│ ti_eset │ files            │ pipeline  │ test-eset-ndjson.log                            │ PASS   │   297.2261ms │
│ ti_eset │ ip               │ pipeline  │ (ingest pipeline warnings test-eset-ndjson.log) │ PASS   │   901.2808ms │
│ ti_eset │ ip               │ pipeline  │ test-eset-ndjson.log                            │ PASS   │   254.9658ms │
│ ti_eset │ url              │ pipeline  │ (ingest pipeline warnings test-eset-ndjson.log) │ PASS   │   927.8207ms │
│ ti_eset │ url              │ pipeline  │ test-eset-ndjson.log                            │ PASS   │   278.9183ms │
╰─────────┴──────────────────┴───────────┴─────────────────────────────────────────────────┴────────┴──────────────╯
--- Test results for package: ti_eset - END   ---
2026/08/03 11:12:23  INFO elastic-stack: 9.4.2
--- Test results for package: ti_eset - START ---
╭─────────┬──────────────────┬───────────┬──────────────────────────┬────────┬──────────────╮
│ PACKAGE │ DATA STREAM      │ TEST TYPE │ TEST NAME                │ RESULT │ TIME ELAPSED │
├─────────┼──────────────────┼───────────┼──────────────────────────┼────────┼──────────────┤
│ ti_eset │ apt              │ static    │ Verify sample_event.json │ PASS   │   116.1864ms │
│ ti_eset │ botnet           │ static    │ Verify sample_event.json │ PASS   │   111.6623ms │
│ ti_eset │ cc               │ static    │ Verify sample_event.json │ PASS   │   115.5284ms │
│ ti_eset │ domains          │ static    │ Verify sample_event.json │ PASS   │    73.6737ms │
│ ti_eset │ emailattachments │ static    │ Verify sample_event.json │ PASS   │   201.5779ms │
│ ti_eset │ files            │ static    │ Verify sample_event.json │ PASS   │   139.3191ms │
│ ti_eset │ ip               │ static    │ Verify sample_event.json │ PASS   │   152.8872ms │
│ ti_eset │ url              │ static    │ Verify sample_event.json │ PASS   │   216.5342ms │
╰─────────┴──────────────────┴───────────┴──────────────────────────┴────────┴──────────────╯
--- Test results for package: ti_eset - END   ---
Done
--- Test results for package: ti_eset - START ---
╭─────────┬──────────────────┬───────────┬───────────┬────────┬──────────────╮
│ PACKAGE │ DATA STREAM      │ TEST TYPE │ TEST NAME │ RESULT │ TIME ELAPSED │
├─────────┼──────────────────┼───────────┼───────────┼────────┼──────────────┤
│ ti_eset │ apt              │ system    │ httpjson  │ PASS   │  49.1826999s │
│ ti_eset │ botnet           │ system    │ httpjson  │ PASS   │  44.6532706s │
│ ti_eset │ cc               │ system    │ httpjson  │ PASS   │  49.9867111s │
│ ti_eset │ domains          │ system    │ httpjson  │ PASS   │  46.2537095s │
│ ti_eset │ emailattachments │ system    │ cel       │ PASS   │  45.6209966s │
│ ti_eset │ files            │ system    │ httpjson  │ PASS   │  43.3094802s │
│ ti_eset │ ip               │ system    │ httpjson  │ PASS   │  48.5194816s │
│ ti_eset │ url              │ system    │ httpjson  │ PASS   │  46.8162578s │
╰─────────┴──────────────────┴───────────┴───────────┴────────┴──────────────╯
--- Test results for package: ti_eset - END   ---
Done
@polakovicp
polakovicp requested a review from a team as a code owner May 21, 2026 15:16
@elastic-vault-github-plugin-prod

Copy link
Copy Markdown
Contributor

Reviewers

Buildkite won't run for external contributors automatically; you need to add a comment:

  • /test : will kick off a build in Buildkite.

NOTE: https://github.com/elastic/integrations/blob/main/.buildkite/pull-requests.json contains all those details.

@andrewkroh andrewkroh added Integration:ti_eset ESET Threat Intelligence (Partner supported) Team:Security-Service Integrations Security Service Integrations team [elastic/security-service-integrations] labels May 21, 2026
@infra-vault-gh-plugin-prod

Copy link
Copy Markdown

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

@polakovicp
polakovicp force-pushed the ti_eset_emailattachments branch from 6e98f63 to d0e056a Compare May 26, 2026 20:27
@botelastic

botelastic Bot commented Jun 25, 2026

Copy link
Copy Markdown

Hi! We just realized that we haven't looked into this PR in a while. We're sorry! We're labeling this issue as Stale to make it hit our filters and make sure we get back to it as soon as possible. In the meantime, it'd be extremely helpful if you could take a look at it as well and confirm its relevance. A simple comment with a nice emoji will be enough :+1. Thank you for your contribution!

@botelastic botelastic Bot added the Stalled label Jun 25, 2026
@mergify

mergify Bot commented Jun 25, 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
@vera-review-bot

Copy link
Copy Markdown

👀 I have started reviewing the PR

@brijesh-elastic

brijesh-elastic commented Jul 13, 2026

Copy link
Copy Markdown
Contributor

This stream declares input: cel, but packages/ti_eset/manifest.yml policy_templates only define an httpjson input. So, we need to add cel input on package-level manifest.

packages/ti_eset/changelog.yml also needs an entry for this new data stream.

@botelastic botelastic Bot removed the Stalled label Jul 13, 2026
Comment thread packages/ti_eset/data_stream/emailattachments/agent/stream/cel.yml.hbs Outdated
Comment thread packages/ti_eset/data_stream/emailattachments/manifest.yml
Comment thread packages/ti_eset/data_stream/emailattachments/manifest.yml
Comment thread packages/ti_eset/data_stream/emailattachments/manifest.yml Outdated
Comment thread packages/ti_eset/data_stream/emailattachments/manifest.yml Outdated
@polakovicp

Copy link
Copy Markdown
Contributor Author

⚠️ @polakovicp I couldn't complete the review for commits d98003212d3f09 (5 commits) after several attempts. A maintainer can re-run it with @vera-review-bot review.

@brijesh-elastic do we know why this PR (and other PRs I opened) are not passing automated review?

@brijesh-elastic

Copy link
Copy Markdown
Contributor

@vera-review-bot review

Comment thread packages/ti_eset/changelog.yml
Comment thread packages/ti_eset/manifest.yml Outdated
size: 96x96
type: image/svg+xml
vars:
- name: username

Copy link
Copy Markdown

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_eset/manifest.yml:34

username/password move from the httpjson input to package-level vars, which existing 1.9.0 policies cannot carry over; treat this as a breaking change (major version + breaking-change changelog entry) or keep the input-level vars.

Details

This PR deletes the vars block from the httpjson input under policy_templates[0].inputs and re-declares username and password at package level. Fleet stores existing agent policy values against the scope they were declared in: 1.9.0 policies hold these values under inputs[].vars, and there is no package-level vars object to migrate them into. After upgrading to 1.10.0 the two package-level vars are required: true with no default, so upgraded policies come back with unset required credentials. The version bump is a minor one (1.9.0 -> 1.10.0) and the changelog entry does not mention it.

Recommendation:

If the move is intentional, ship it as a breaking change so users are warned and Fleet surfaces the reconfiguration:

- version: "2.0.0"
  changes:
    - description: Move the ETI username and password to package-level variables so they are shared by the httpjson and cel inputs. Existing agent policies must be reconfigured with the ETI credentials after upgrading.
      type: breaking-change
      link: https://github.com/elastic/integrations/pull/19138

Otherwise keep the credentials on the httpjson input and declare the same two vars on the new cel input:

      - type: cel
        title: ETI New-Generation Feeds (TAXII 2.1)
        description: Collection of ETI new-generation feeds
        vars:
          - name: username
            type: text
            title: ETI Username
            required: true
            show_user: true
          - name: password
            type: password
            title: ETI Password
            multi: false
            required: true
            secret: true
            show_user: true

🤖 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.

@polakovicp, can you please declare the same two vars on the new cel input instead of keeping it globally?

Comment thread packages/ti_eset/data_stream/emailattachments/manifest.yml
target_field: eset.valid_until
formats:
- ISO8601
if: ctx.eti?.valid_until != null

Copy link
Copy Markdown

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_eset/data_stream/emailattachments/elasticsearch/ingest_pipeline/default.yml:79

threat.indicator.first_seen is declared in fields/ecs.yml but nothing populates it, while the STIX valid_from value is discarded; add a date processor mapping eti.valid_from to threat.indicator.first_seen.

Details

packages/ti_eset/data_stream/emailattachments/fields/ecs.yml declares threat.indicator.first_seen, but no processor in this pipeline writes it. The source objects do carry the value: the committed fixture _dev/test/pipeline/test-eset-ndjson.log contains "valid_from": "2024-03-18T14:15:42Z", and eti.valid_from is discarded by the remove_a0758d9e processor that drops the whole eti object. Consumers of the IOC index therefore never get a first-seen timestamp for these indicators.

Recommendation:

Parse valid_from next to the existing valid_until handling:

- date:
    tag: date_eti_valid_from_to_threat_indicator_first_seen
    field: eti.valid_from
    target_field: threat.indicator.first_seen
    formats:
    - ISO8601
    if: ctx.eti?.valid_from != null

🤖 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.

correct. @polakovicp, can you populate the field instead of discarding? if its not the correct ECS match, then you can store it in custom field(maybe eset.valid_from).

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.

@brijesh-elastic since IoC does not contain information about first_seen, I populated eset.valid_from. threat.indicator.first_seen was removed from ecs

allow_duplicates: false
if: ctx.error?.message != null
on_failure:
- append:

Copy link
Copy Markdown

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_eset/data_stream/emailattachments/elasticsearch/ingest_pipeline/default.yml:178

Two of the three on_failure processors have no tag and the first one is indented with 6 spaces instead of 4; add tags and normalise the indentation.

Details

Every processor in the main processors list of this pipeline carries a tag, but in the on_failure block only the set has one; the append to error.message and the append to tags do not, which makes failures inside the failure handler harder to attribute. The first append also uses a 6-space body indent while the other two use 4, so elastic-package format will rewrite the block.

Recommendation:

Tag all three and use a consistent indent:

on_failure:
- append:
    field: error.message
    tag: append_error_message
    value: |-
      Processor '{{{ _ingest.on_failure_processor_type }}}'
      {{{#_ingest.on_failure_processor_tag}}}with tag '{{{ _ingest.on_failure_processor_tag }}}'
      {{{/_ingest.on_failure_processor_tag}}}failed with message '{{{ _ingest.on_failure_message }}}'
- set:
    field: event.kind
    tag: set_pipeline_error_to_event_kind
    value: pipeline_error
- append:
    field: tags
    tag: append_preserve_original_event_tag
    value: preserve_original_event
    allow_duplicates: false

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

⚠️ Automated review — verify suggestions before applying.

@brijesh-elastic brijesh-elastic 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.

Nit only. LGTM.

@brijesh-elastic

Copy link
Copy Markdown
Contributor

Hi @polakovicp, nice work on the PR!

Could you run elastic-package test -v and share the test results? You can add them to the PR description, similar to this #10110

Comment thread packages/ti_eset/data_stream/emailattachments/manifest.yml
Comment thread packages/ti_eset/changelog.yml
Comment thread packages/ti_eset/manifest.yml Outdated
size: 96x96
type: image/svg+xml
vars:
- name: username

Copy link
Copy Markdown

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_eset/manifest.yml:34

username/password move from the httpjson input's vars up to package-level vars, which changes where existing 1.9.x policies store them; either declare them per input instead, or record this as a breaking change in the changelog.

Details

This diff deletes the vars: block from the httpjson input of the eset policy template and re-declares username and password as package-level vars at the root of manifest.yml.

For policies already created on 1.9.x, these values are persisted against the httpjson input, not against the package policy. After upgrading to 1.10.0 the package schema no longer defines them at the input level and instead requires them at package level, where both are required: true with no default. The stored input-scoped values do not carry over to the new scope, so upgraded policies hit a required-but-unset variable rather than reusing the credentials the user already entered.

The changelog entry for 1.10.0 is typed enhancement and does not mention this relocation.

Recommendation:

Keep the vars scoped to each input so existing httpjson policies retain their values, and declare the same pair on the new cel input:

policy_templates:
  - name: eset
    title: ETI feeds (TAXII version 2.1)
    description: Collect data from ETI feeds (TAXII version 2.1)
    inputs:
      - type: httpjson
        title: ETI Legacy Feeds (TAXII 2.1)
        description: Collection of ETI legacy feeds
        vars: &eti_credentials
          - name: username
            type: text
            title: ETI Username
            required: true
            show_user: true
          - name: password
            type: password
            title: ETI Password
            multi: false
            required: true
            secret: true
            show_user: true
      - type: cel
        title: ETI New-Generation Feeds (TAXII 2.1)
        description: Collection of ETI new-generation feeds
        vars: *eti_credentials

If the package-level move is intentional, keep it but record it explicitly:

- version: "1.10.0"
  changes:
    - description: Move `username` and `password` from the httpjson input to package-level variables. Existing policies must re-enter ETI credentials after upgrade.
      type: breaking-change
      link: https://github.com/elastic/integrations/pull/19138

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

⚠️ Automated review — verify suggestions before applying.

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.

@brijesh-elastic should this breaking change be addressed? Can I simply do it like this?

- version: "1.10.0"
  changes:
    - description: |-
        PLACEHOLDER - specified once all related PRs will be merged to branch ti_set_polakovicp_enhancements
        Move `username` and `password` from the httpjson input to package-level variables. Existing policies must re-enter ETI credentials after upgrade.
      type: breaking-change, enhancement
      link: TODO

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.

We should avoid introducing breaking-change as much as possible. You can avoid this by declaring the same variables in the cel input instead of keeping them globally in the manifest.

@polakovicp

Copy link
Copy Markdown
Contributor Author

Hi @polakovicp, nice work on the PR!

Could you run elastic-package test -v and share the test results? You can add them to the PR description, similar to this #10110

I updated description as requested

Comment thread packages/ti_eset/manifest.yml Outdated
title: Sample logo
size: 96x96
type: image/svg+xml
vars:

Copy link
Copy Markdown

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_eset/manifest.yml:33

username/password are moved from the httpjson input's vars up to package-level vars, which changes where Fleet stores existing policy values; either keep them at the input level or ship this as a documented breaking change rather than a minor enhancement bump.

Details

This diff deletes the vars block from the httpjson input under policy_templates[0].inputs and re-declares username and password as package-level vars. Package-level vars are stored in a different place in the package policy than input-level vars, so the credential values configured by existing 1.9.x installations do not carry over to the new location. Both new vars are required: true with no default, so an upgraded policy has no value for them, and all seven existing httpjson data streams (apt, botnet, cc, domains, files, ip, url) render {{username}}/{{password}} from those vars. The package is nonetheless bumped 1.9.0 -> 1.10.0 with a changelog entry of type: enhancement, which does not signal to users that policy reconfiguration is needed. The new cel stream can read the credentials from either scope, so package-level placement is not required to add the emailattachments data stream.

Recommendation:

Either keep the credentials on the inputs that use them (and duplicate onto the new cel input):

policy_templates:
  - name: eset
    inputs:
      - type: httpjson
        title: ETI Legacy Feeds (TAXII 2.1)
        vars: &eti_credentials
          - name: username
            type: text
            title: ETI Username
            required: true
            show_user: true
          - name: password
            type: password
            title: ETI Password
            multi: false
            required: true
            secret: true
            show_user: true
      - type: cel
        title: ETI New-Generation Feeds (TAXII 2.1)
        vars: *eti_credentials

or, if the move to package scope is intentional, record it as a breaking change in changelog.yml:

- version: "2.0.0"
  changes:
    - description: Move ETI username and password to package-level variables. Existing agent policies must re-enter the credentials after upgrade.
      type: breaking-change
      link: https://github.com/elastic/integrations/pull/19138

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

⚠️ Automated review — verify suggestions before applying.

Comment thread packages/ti_eset/changelog.yml
@polakovicp
polakovicp force-pushed the ti_eset_emailattachments branch from 0568535 to d398f0e Compare August 4, 2026 08:04
@polakovicp
polakovicp force-pushed the ti_eset_emailattachments branch from d398f0e to ce44d37 Compare August 4, 2026 08:08
name: ti_eset
title: "ESET Threat Intelligence"
version: "1.9.0"
version: "1.10.0"

Copy link
Copy Markdown

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_eset/manifest.yml:12

Narrowing the Kibana constraint to ^9.4.0 drops support for 8.19/9.0/9.1 in a minor release; keep an 8.x branch in the range unless a 9.4-only feature is actually required.

Details

The constraint goes from ^8.19.4 || ~9.0.7 || ^9.1.4 to ^9.4.0, so every currently supported 8.19.x, 9.0.x, 9.1.x, 9.2.x and 9.3.x stack loses the ability to install or upgrade this integration, and the package version is only a minor bump (1.9.0 -> 1.10.0). The new agent features this PR introduces do not require it: run_as_cel, cel.program, cel.state and cel.redact are all documented for the httpjson input on the 8.19 branch (https://www.elastic.co/guide/en/beats/filebeat/8.19/filebeat-input-httpjson.html), and the cel input used by the new emailattachments stream predates 8.19 as well. If a specific 9.4-only fix is genuinely needed, that reason belongs in the changelog and the change must be recorded as a breaking change.

Recommendation:

Keep the 8.x branch in the constraint (raise the 8.x floor instead of removing it) unless a 9.4-only capability is documented:

conditions:
  kibana:
    version: "^8.19.4 || ~9.0.7 || ^9.1.4"
  elastic:
    subscription: "basic"

🤖 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.

@polakovicp, Can you tell me what was the reason to keeping only ^9.4.0 constraint?

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.

Not sure, I reverted this back to "^8.19.4 || ~9.0.7 || ^9.1.4"

Comment thread packages/ti_eset/manifest.yml Outdated
size: 96x96
type: image/svg+xml
vars:
- name: username

Copy link
Copy Markdown

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_eset/manifest.yml:34

Moving username/password from the policy template input to package-level vars orphans the values stored in existing policies; keep them where they are or document the credential re-entry as a breaking change.

Details

Existing package policies persist these two vars under inputs[httpjson].vars. After this change the same names exist only at package scope, and Fleet copies var values by scope on upgrade - it has no aliasing between input-level and package-level vars. Both new vars are required: true with no default, so upgrading an existing 1.9.x policy leaves them unset: the policy fails validation on upgrade and, once resolved, the ETI feeds authenticate with empty credentials until the user re-enters them.

Recommendation:

Either declare the credentials on both inputs of the policy template so existing policies keep their values:

policy_templates:
  - name: eset
    inputs:
      - type: httpjson
        title: ETI Legacy Feeds (TAXII 2.1)
        vars: &eti_credentials
          - name: username
            type: text
            title: ETI Username
            required: true
            show_user: true
          - name: password
            type: password
            title: ETI Password
            multi: false
            required: true
            secret: true
            show_user: true
      - type: cel
        title: ETI New-Generation Feeds (TAXII 2.1)
        vars: *eti_credentials

or keep the package-level vars and record the migration in the changelog:

- version: "1.10.0"
  changes:
    - description: Move ETI credentials to package-level variables. Existing agent policies must re-enter the ETI username and password after upgrade.
      type: breaking-change
      link: https://github.com/elastic/integrations/pull/19138

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

⚠️ Automated review — verify suggestions before applying.

Comment thread packages/ti_eset/changelog.yml
time:
field: eset.valid_until
max_age: 1m
source:

Copy link
Copy Markdown

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_eset/elasticsearch/transform/emailattachments_latest_ioc/transform.yml:20

The transform source has no query, so ingest-error documents from the new pipeline flow into the latest IOC index; filter out error.message documents and cold/frozen tiers.

Details

The new ingest pipeline deliberately produces failure documents: its on_failure block sets error.message and event.kind: pipeline_error. With an unfiltered source those documents are picked up by the latest transform and surface under the logs-ti_eset_latest.emailattachments alias that consumers query for active IOCs. They also have no eset.id, so they all collapse onto a single entry of the event.dataset + eset.id unique key. Excluding cold and frozen tiers additionally keeps the transform from scanning expensive storage.

Recommendation:

Add a source query:

source:
  index:
    - logs-ti_eset.emailattachments-*
  query:
    bool:
      must_not:
        - exists:
            field: error.message
        - terms:
            _tier:
              - data_frozen
              - data_cold

🤖 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.

You could add the query below, which will prevent sending any agent error documents to the destination indices.

source:
  index:
    - logs-ti_eset.emailattachments-*
  query:
    bool:
      must_not:
        - exists:
            field: error.message
Comment thread packages/ti_eset/data_stream/emailattachments/manifest.yml
},
"eset": {
"id": "indicator--00c42f20-62d2-4cb6-be87-2c451aaec4a4",
"labels": "malicious-activity",

Copy link
Copy Markdown

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_eset/data_stream/emailattachments/sample_event.json:25

sample_event.json stores eset.labels as a bare string while the pipeline always produces an array, so the committed sample (and the generated README) does not match real output; regenerate it with elastic-package test system -g.

Details

The foreach_eti_labels_ff89dc21 processor in elasticsearch/ingest_pipeline/default.yml uses an append sub-processor to build eset.labels, which always yields an array. This PR's own pipeline fixture agrees: _dev/test/pipeline/test-eset-ndjson.log-expected.json expects "labels": ["malicious-activity"] for the identical input document. Every sibling sample event stores the array form too, including data_stream/botnet/sample_event.json, which this branch regenerated with current tooling and which still has "labels": ["malicious-activity"] at the same position, so the tooling does not collapse single-element arrays. The scalar here therefore reflects a hand-edited file rather than one generated from a system-test document, and it is copied verbatim into the generated docs/README.md example event. There is no mapping impact because eset.labels is declared as keyword, but the published example misrepresents the shape users will query.

Recommendation:

Regenerate the file from a system test run (elastic-package test system -g -v) so it reflects the indexed document, and rebuild the docs. The eset block should read:

    "eset": {
        "id": "indicator--00c42f20-62d2-4cb6-be87-2c451aaec4a4",
        "labels": [
            "malicious-activity"
        ],
        "valid_until": "2024-03-20T14:15:42.000Z"
    },

🤖 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.

@polakovicp, can you make sure that we don't change the auto-generated file?

tag: set_threat_indicator_type_e912359f
field: threat.indicator.type
value: file
- set:

Copy link
Copy Markdown

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_eset/data_stream/emailattachments/elasticsearch/ingest_pipeline/default.yml:137

threat.indicator.name is populated with set + copy_from even though eti.name is discarded right afterwards; use a rename like the neighbouring eti.id and eti.description processors.

Details

This processor copies eti.name into threat.indicator.name and relies on the later remove_a0758d9e processor to delete the whole eti object. set with copy_from is the pattern for duplicating a value that must survive in both places (as set_threat_indicator_modified_at_5a74d882 correctly does for threat.indicator.last_seen), but here the source is thrown away, so the copy is a move. The two processors immediately above it, rename_eti_id_to_eset_id_e33c480b and rename_eti_description_to_threat_indicator_description_d13d7cb3, already use rename for exactly this situation. Using rename here removes the redundant if guard (ignore_missing covers it) and makes the pipeline's intent uniform. No behavioural change either way.

Recommendation:

Replace the set with a rename:

- rename:
    tag: rename_eti_name_to_threat_indicator_name
    field: eti.name
    target_field: threat.indicator.name
    ignore_missing: true

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

⚠️ Automated review — verify suggestions before applying.

@mergify

mergify Bot commented Aug 26, 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
@polakovicp
polakovicp force-pushed the ti_eset_emailattachments branch from cfd3bc6 to e73fb1e Compare August 26, 2026 13:16
@vera-review-bot

Copy link
Copy Markdown

🟢 Reviewed the latest commits e73fb1e — nothing new beyond already posted comments.

Review summary

Issues found across earlier commits d980032, ce44d37 — 3 low
  • 🔵 The emailattachments stream is the only one in the package with enabled: false, so the feed collects nothing until a user manually turns it on (link) (Resolved)
  • 🔵 sample_event.json stores eset.labels as a bare string while the pipeline always produces an array, so the committed sample (and the generated README) does not match real output (link) (Unresolved)
  • 🔵 threat.indicator.name is populated with set + copy_from even though eti.name is discarded right afterwards (link) (Unresolved)
Issues found across earlier commits d398f0e — 3 high, 2 medium, 1 low
  • 🟠 Narrowing the Kibana constraint to ^9.4.0 drops support for 8.19/9.0/9.1 in a minor release (link) (Unresolved)
  • 🟠 Moving username/password from the policy template input to package-level vars orphans the values stored in existing policies (link) (Unresolved)
  • 🟠 The 1.10.0 changelog entry is a literal PLACEHOLDER with link: TODO (link) (Resolved)
  • 🟡 The new transform sets num_failure_retries: -1 instead of unattended: true, so unlike the other seven ti_eset transforms it will not auto-recover (link) (Resolved)
  • 🟡 The transform source has no query, so ingest-error documents from the new pipeline flow into the latest IOC index (link) (Unresolved)
  • 🔵 The new data stream ships a single pipeline test document, leaving the drop branch and the non-malicious confidence mappings untested (link) (Resolved)
Issues found across earlier commits 0568535 — 2 high, 1 medium, 1 low
  • 🟠 The new emailattachments transform omits settings.unattended: true, unlike all seven existing ti_eset transforms. Add it (keeping num_failure_retries only if intentional) so a transient failure does not stop the transform and degrade Fleet health. (link) (Resolved)
  • 🟠 username/password are moved from the httpjson input's vars up to package-level vars, which changes where Fleet stores existing policy values (link) (Unresolved)
  • 🟡 The 1.10.0 changelog entry is a placeholder with link: TODO (link) (Resolved)
  • 🔵 cel.yml.hbs has no newline at end of file (link) (Resolved)
Issues found across earlier commits 368dd6e, 70f0e2e — 3 high, 3 medium
  • 🟠 The new emailattachments transform omits settings.unattended: true that all seven sibling transforms set (link) (Resolved)
  • 🟠 The new emailattachments data stream is not documented anywhere in _dev/build/docs/README.md (link) (Resolved)
  • 🟠 The 1.10.0 changelog entry is a literal PLACEHOLDER description with link: TODO (link) (Resolved)
  • 🟡 username/password move from the httpjson input's vars up to package-level vars, which changes where existing 1.9.x policies store them (link) (Unresolved)
  • 🟡 The pipeline test ships a single event that only exercises the malicious-activity label, leaving three of the four confidence branches and the non-indicator drop path untested (link) (Resolved)
  • 🟡 default_policy.json (and cel.yml.hbs) are committed without a trailing newline, which elastic-package format --fail-fast / elastic-package check flags (link) (Resolved)
Issues found across earlier commits d98003212d3f09 (5 commits) — 2 high, 2 medium, 2 low
  • 🟠 The 1.10.0 changelog entry is a PLACEHOLDER with link: TODO (link) (Resolved)
  • 🟠 username/password move from the httpjson input to package-level vars, which existing 1.9.0 policies cannot carry over (link) (Unresolved)
  • 🟡 The new emailattachments data stream is not documented anywhere in the README template (link) (Resolved)
  • 🟡 threat.indicator.first_seen is declared in fields/ecs.yml but nothing populates it, while the STIX valid_from value is discarded (link) (Unresolved)
  • 🔵 Two of the three on_failure processors have no tag and the first one is indented with 6 spaces instead of 4 (link) (Unresolved)
  • 🔵 The pipeline test fixture has a single malicious-activity document, leaving the other three confidence branches and the non-indicator drop path untested (link) (Resolved)
Issues found across earlier commits 6ac5a923bd470b (8 commits) — 1 high
  • 🟠 YAML syntax error in default.yml (link) (Resolved)
Issues found across earlier commits 9262482 — 1 critical, 1 high
  • 🔴 The newly added remove processor is mis-indented (2 spaces), nesting it inside the rename entry instead of being a sibling processor (link) (Resolved)
  • 🟠 YAML syntax error in default.yml (link) (Resolved)

Since this is a community PR, a new commit triggers another review — at most once every 30 minutes. I skip the PR while it's approved or has merge conflicts.

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

⚠️ Automated review — verify suggestions before applying.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

changelog-link-check:skip Integration:ti_eset ESET Threat Intelligence (Partner supported) Team:Security-Service Integrations Security Service Integrations team [elastic/security-service-integrations]

3 participants