Skip to content

[Google Threat Intelligence] Add Integration Package #13189

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 25 commits into from
Jun 23, 2025

Conversation

niraj-crest
Copy link
Contributor

  • Enhancement

What does this PR do?

  • Added 4 data streams (cryptominer, first_stage_delivery_vectors, infostealer, iot).
  • Added data collection logic for the data streams.
  • Added the ingest pipeline for the data streams.
  • Mapped fields according to the ECS schema and added Fields metadata in the appropriate yaml files.
  • Added dashboards and visualizations.
  • Added system test cases for the data stream.

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.

How to test this PR locally

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

@andrewkroh andrewkroh added New Integration Issue or pull request for creating a new integration package. dashboard Relates to a Kibana dashboard bug, enhancement, or modification. labels Mar 20, 2025
@jamiehynds jamiehynds added the Team:Security-Service Integrations Security Service Integrations team [elastic/security-service-integrations] label Mar 20, 2025
@elasticmachine
Copy link

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

@niraj-crest
Copy link
Contributor Author

Hey @jamiehynds & @andrewkroh
Can anyone please add reviewers to this PR?

@jamiehynds jamiehynds requested a review from a team March 26, 2025 08:25
@andrewkroh andrewkroh added the Crest Contributions from Crest developement team. label Mar 27, 2025
@kcreddy
Copy link
Contributor

kcreddy commented Mar 28, 2025

/test

Copy link
Contributor

@kcreddy kcreddy left a comment

Choose a reason for hiding this comment

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

@niraj-crest, could you fix the CI error?

Error: there is no owner for "packages/ti_google_threat_intelligence" in ".github/CODEOWNERS"

by adding a line into .github/CODEOWNERS

@niraj-crest niraj-crest force-pushed the ti_google_threat_intelligence branch from 0078531 to 1b3d6dd Compare April 1, 2025 04:42
@niraj-crest
Copy link
Contributor Author

Hello @kcreddy,
Added codeowners, can please run the tests again?

@kcreddy
Copy link
Contributor

kcreddy commented Apr 1, 2025

/test

@elastic-vault-github-plugin-prod

🚀 Benchmarks report

To see the full report comment with /test benchmark fullreport

@kcreddy
Copy link
Contributor

kcreddy commented Apr 1, 2025

@niraj-crest, looks like the PR is failing Check for blocked path changes.
The git diff git diff --name-only f9794072abccfc51e4549ecd7510d0d2248f2c72 1b3d6ddc5affe5f7215b2668ecdd1db7682202e9 is identifying files from blocked_paths.

Can you re-sync your branch with elastic:main?

@niraj-crest
Copy link
Contributor Author

@niraj-crest, looks like the PR is failing Check for blocked path changes. The git diff git diff --name-only f9794072abccfc51e4549ecd7510d0d2248f2c72 1b3d6ddc5affe5f7215b2668ecdd1db7682202e9 is identifying files from blocked_paths.

Can you re-sync your branch with elastic:main?

Done @kcreddy.

@kcreddy
Copy link
Contributor

kcreddy commented Apr 2, 2025

@niraj-crest, I don't think its done.

Screenshot 2025-04-02 at 11 25 27 AM

@kcreddy
Copy link
Contributor

kcreddy commented Apr 2, 2025

/test

Copy link

@niraj-crest
Copy link
Contributor Author

Hello @kcreddy,
CI is passing now, i guess you can start reviewing the PR.

@kcreddy
Copy link
Contributor

kcreddy commented Apr 3, 2025

@kcreddy,
CI is passing now, i guess you can start reviewing the PR.

@niraj-crest I've added few comments. I haven't looked into the entire PR yet. Will do.

@kcreddy
Copy link
Contributor

kcreddy commented Jun 4, 2025

/test

@niraj-crest
Copy link
Contributor Author

Hello @kcreddy / @efd6 /@andrewkroh
Please let me know if we have any other review comments.

Comment on lines 27 to 29
state.with({
"start_time": state.?cursor.last_timestamp.orValue((now - duration(state.initial_interval)).format("2006010215"))
}).as(state, state.with(
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
state.with({
"start_time": state.?cursor.last_timestamp.orValue((now - duration(state.initial_interval)).format("2006010215"))
}).as(state, state.with(
state.?cursor.last_timestamp.orValue((now - duration(state.initial_interval)).format("2006010215")).as(start_time,

since this is overwritten for every eval it doesn't need to be put in state. This will need bracket fixups.

Though, I would also reconsider doing the format here. Instead, that way you don't need to reparse each time you make an adjustment.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thank you for the suggestion!
We’ve updated the code to use start_time directly as recommended, which definitely helped simplify things.

Regarding your additional point about reconsidering the formatting, we explored that approach but ran into a timing issue due to the API's behavior. Specifically, the API enforces a 1-hour delay, and if we don’t round precisely to the hour, we risk calling a future window too early.

For example, if the current time is 10:21 and we start with an initial interval of 2h, we’ll fetch data for 08 and 09. When checking whether to proceed to the next hour, (09:21 + 1h) becomes 10:21, which might still be less than now (say 10:22) by the time the check happens. This leads us to attempt a 10:00 call prematurely and receive an error.

To avoid this, we’ve kept the strict hour-to-hour comparison using formatted values.
Please let us know if you have any further thoughts.

Copy link
Contributor

Choose a reason for hiding this comment

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

OK. That is also unfortunate. What we'd really like is a timestamp round function. elastic/mito#92

}).as(state, state.with(
request(
"GET",
state.url.trim_right("/") + "/api/v3/threat_lists/cryptominer/" + state.start_time + "?" + {
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
state.url.trim_right("/") + "/api/v3/threat_lists/cryptominer/" + state.start_time + "?" + {
state.url.trim_right("/") + "/api/v3/threat_lists/cryptominer/" + start_time + "?" + {

"cursor": {
"last_timestamp": (state.start_time.parse_time("2006010215") + duration("1h")).format("2006010215"),
},
"want_more": (state.start_time.parse_time("2006010215") + duration("1h")) < (now.format("2006010215")).parse_time("2006010215")
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
"want_more": (state.start_time.parse_time("2006010215") + duration("1h")) < (now.format("2006010215")).parse_time("2006010215")
"want_more": (start_time.parse_time("2006010215") + duration("1h")) < (now.format("2006010215")).parse_time("2006010215")

Copy link
Contributor

Choose a reason for hiding this comment

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

Same comments as above.

@niraj-crest niraj-crest requested a review from efd6 June 5, 2025 11:42
@niraj-crest
Copy link
Contributor Author

niraj-crest commented Jun 6, 2025

Hello @kcreddy / @efd6 ,
We’ve addressed all the review comments.
Kindly let us know if you have any additional suggestions. If everything looks good to you, we’d appreciate it if we could proceed with merging this PR.

@kcreddy
Copy link
Contributor

kcreddy commented Jun 9, 2025

/test

Comment on lines +12 to +14
must_not:
- match_phrase:
kibana.alert.rule.tags: IOC Stream
Copy link
Contributor

@kcreddy kcreddy Jun 9, 2025

Choose a reason for hiding this comment

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

This is indeed confusing as this PR change is dependent on future PRs. We should avoid this if possible in the future.

What is the difference between IOCs ingested from this PR's API i..e., Get Hourly Threat List vs the /ioc_stream API thats added in #13449?
Is one API better than the other, if so why don't we add only the better one?

@@ -0,0 +1,264 @@
- name: gti
Copy link
Contributor

Choose a reason for hiding this comment

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

Please kindly make a note of all these after items and create a follow up PR. Thanks!

# Bump this version to delete, reinstall, and restart the transform during
# package installation.
fleet_transform_version: 1.0.0
run_as_kibana_system: false
Copy link
Contributor

@kcreddy kcreddy Jun 9, 2025

Choose a reason for hiding this comment

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

After adding the pipeline, the transform turns Healthy as expected.

This behaviour is very strange. run_as_kibana_system shouldn't impact the transform health from a pipeline not being present, especially when we don't even have a pipeline by default #13189 (comment).

If its not too much, could you please kindly add a video capturing this behaviour?

Copy link
Contributor

@efd6 efd6 left a comment

Choose a reason for hiding this comment

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

My concerns have been addressed, but please wait for @kcreddy.

?"query": has(state.query) ? optional.of([state.query]) : optional.none(),
"limit": ["4000"],
"x-tool": ["Elastic"],
"User-Agent": ["v0.1.0"], // Include integration version here; must match the 'version' in package level manifest.yml
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
"User-Agent": ["v0.1.0"], // Include integration version here; must match the 'version' in package level manifest.yml
"User-Agent": ["v0.1.0"], // Keep this in sync with 'version' in package level manifest.yml.

Same change elsewhere that this comment exists.

Comment on lines +4 to +5
# This version must match the User-Agent version used in CEL code.
# Remember to update the User-Agent in CEL code when changing this version.
Copy link
Contributor

Choose a reason for hiding this comment

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

Comment on lines 27 to 29
state.with({
"start_time": state.?cursor.last_timestamp.orValue((now - duration(state.initial_interval)).format("2006010215"))
}).as(state, state.with(
Copy link
Contributor

Choose a reason for hiding this comment

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

OK. That is also unfortunate. What we'd really like is a timestamp round function. elastic/mito#92

@niraj-crest niraj-crest requested a review from kcreddy June 13, 2025 06:10
@kcreddy
Copy link
Contributor

kcreddy commented Jun 17, 2025

/test

Copy link
Contributor

@kcreddy kcreddy left a comment

Choose a reason for hiding this comment

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

Only waiting on 1 outstanding comment: #13189 (comment)

@kcreddy
Copy link
Contributor

kcreddy commented Jun 23, 2025

/test

@elasticmachine
Copy link

💚 Build Succeeded

History

Copy link

Quality Gate failed Quality Gate failed

Failed conditions
64.3% Coverage on New Code (required ≥ 80%)

See analysis details on SonarQube

Copy link
Contributor

@kcreddy kcreddy left a comment

Choose a reason for hiding this comment

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

LGTM. Thank you!
#14287 tracks list of pending issues for making the integration GA.

@kcreddy kcreddy merged commit 01ed0b5 into elastic:main Jun 23, 2025
6 of 7 checks passed
@elastic-vault-github-plugin-prod

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

@andrewkroh andrewkroh added the Integration:ti_google_threat_intelligence Google Threat Intelligence (Partner supported) label Jun 23, 2025
shmsr pushed a commit to shmsr/integrations that referenced this pull request Jun 30, 2025
- Added 4 data streams (cryptominer, first_stage_delivery_vectors, infostealer, iot).
- Added data collection logic for the data streams.
- Added the ingest pipeline for the data streams.
- Mapped fields according to the ECS schema and added Fields metadata in the appropriate yaml files.
- Added dashboards and visualizations.
- Added system test cases for the data stream.
@andrewkroh andrewkroh added the documentation Improvements or additions to documentation. Applied to PRs that modify *.md files. label Jul 1, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Crest Contributions from Crest developement team. dashboard Relates to a Kibana dashboard bug, enhancement, or modification. documentation Improvements or additions to documentation. Applied to PRs that modify *.md files. Integration:ti_google_threat_intelligence Google Threat Intelligence (Partner supported) New Integration Issue or pull request for creating a new integration package. 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.

6 participants