ti_opencti: fix incremental polling missing UI-edited indicators - #20382
Conversation
|
Pinging @elastic/security-service-integrations (Team:Security-Service Integrations) |
✅ Elastic Docs Style Checker (Vale)No issues found on modified lines! 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. |
| "after": has(state.cursor) && has(state.cursor.value) ? state.cursor.value : null, | ||
| "first": state.page_size, | ||
| "orderBy": "modified", | ||
| "orderBy": "updated_at", |
There was a problem hiding this comment.
Severity: 🔴 Critical confidence: high path: packages/ti_opencti/data_stream/indicator/agent/stream/cel.yml.hbs:57
The policy test expected files still contain the old CEL program (orderBy "modified", timestamp(e.node.modified), no updated_at in the GraphQL fragment), so elastic-package test policy fails; regenerate them with elastic-package test policy -g.
Details
This PR changes the rendered agent policy for the indicator data stream (orderBy value, the last_modified expression, and the added updated_at field in the IndicatorLine_node fragment), but neither policy test expectation was regenerated. In the checkout, packages/ti_opencti/data_stream/indicator/_dev/test/policy/test-default.expected line 39 and test-multi-values.expected line 39 still read "orderBy": "modified",, line 170 of both still reads body.data.indicators.edges.map(e, timestamp(e.node.modified)).max(), and the query fragment (test-default.expected line 230) still lists modified with no following updated_at. Policy tests compare the rendered policy byte-for-byte against these files, so both test-default and test-multi-values fail as committed.
Recommendation:
Regenerate both expectations from the package directory:
cd packages/ti_opencti
elastic-package test policy -gAfter regeneration, _dev/test/policy/test-default.expected and _dev/test/policy/test-multi-values.expected must show the new program, e.g.:
"orderBy": "updated_at", body.data.indicators.edges.map(e, timestamp(e.node.updated_at)).max()
and the IndicatorLine_node fragment must list updated_at after modified.
🤖 AI-Generated Review | Vera Review Bot | 📚 Knowledge base: integration-skills
⚠️ Automated review — verify suggestions before applying.
| target_field: threat.indicator.modified_at | ||
| - rename: | ||
| field: updated_at | ||
| target_field: opencti.indicator.updated_at |
There was a problem hiding this comment.
Severity: 🟠 High confidence: high path: packages/ti_opencti/data_stream/indicator/elasticsearch/ingest_pipeline/default.yml:103
The _id fingerprint is still built from standard_id + threat.indicator.modified_at, so a UI-edited indicator (new updated_at, unchanged modified) collides with the already-indexed document and is rejected by the data stream; add opencti.indicator.updated_at to the fingerprint fields.
Details
The premise of this fix is that a UI edit bumps updated_at while leaving the STIX modified timestamp untouched — exactly the case added to the docker mock, where the last indicator has modified: 2023-01-10T00:00:00.000Z and updated_at: 2023-01-17T05:54:09.355Z. The CEL change makes the agent re-fetch such indicators, but the fingerprint processor at lines 924-931 of this pipeline derives _id from opencti.indicator.standard_id and threat.indicator.modified_at only. Both values are identical to the copy already indexed, so the re-fetched document gets the same _id; the data stream write is a create op and Elasticsearch rejects it with a version conflict, dropping the update. The latest_ioc transform (unique_key event.id, sort event.ingested) therefore never sees the newer version either, so the edited score/labels never reach logs-ti_opencti_latest.indicator and the reported bug is not actually fixed end to end. The system test does not catch this: all nine indicators in the mock have distinct standard_id values, so no fixture returns the same indicator twice with a bumped updated_at.
Recommendation:
Include the new timestamp in the deduplication key so a UI-only edit produces a distinct document ID:
- fingerprint:
fields:
- opencti.indicator.standard_id # STIX ID is globally unique and consistent
- threat.indicator.modified_at
- opencti.indicator.updated_at
target_field: _id
ignore_missing: true
description: Generate consistent document ID for deduplication
tag: fingerprint_idConsider also extending _dev/deploy/docker/files/config.yml so one indicator is returned twice with the same standard_id and modified but a newer updated_at, which would exercise this path in the system test.
🤖 AI-Generated Review | Vera Review Bot | 📚 Knowledge base: integration-skills
⚠️ Automated review — verify suggestions before applying.
| "cursor": { "value": body.data.indicators.pageInfo.endCursor }, | ||
| "last_modified": has(body.data.indicators.edges) && body.data.indicators.edges.size() > 0 ? | ||
| body.data.indicators.edges.map(e, timestamp(e.node.modified)).max() | ||
| body.data.indicators.edges.map(e, timestamp(e.node.updated_at)).max() |
There was a problem hiding this comment.
Severity: 🟡 Medium confidence: low path: packages/ti_opencti/data_stream/indicator/agent/stream/cel.yml.hbs:188
The cursor expression calls timestamp(e.node.updated_at) unguarded while the pipeline treats the same field as optional (ignore_missing: true); guard the map so a null/absent updated_at cannot error the whole evaluation.
Details
The pipeline rename added in this PR declares ignore_missing: true for updated_at, i.e. the change assumes the field may be absent on some indicators. The CEL cursor computation makes the opposite assumption: body.data.indicators.edges.map(e, timestamp(e.node.updated_at)).max() converts every node's updated_at with no null or presence check, and timestamp() on a null value errors, which aborts evaluation of the whole program for that poll rather than dropping a single indicator. The two halves of the change should agree on whether updated_at is guaranteed.
Recommendation:
Either drop ignore_missing: true from the pipeline rename if updated_at is always returned, or filter the map so only usable values are converted:
"last_modified": body.data.indicators.edges
.map(e, has(e.node.updated_at) && e.node.updated_at != null, timestamp(e.node.updated_at))
.as(ts, ts.size() > 0 ? ts.max() : state.?last_modified.orValue(null))
🤖 AI-Generated Review | Vera Review Bot | 📚 Knowledge base: integration-skills
⚠️ Automated review — verify suggestions before applying.
| field: modified | ||
| target_field: threat.indicator.modified_at | ||
| - rename: | ||
| field: updated_at |
There was a problem hiding this comment.
Severity: 🔵 Low confidence: high path: packages/ti_opencti/data_stream/indicator/elasticsearch/ingest_pipeline/default.yml:102
No pipeline test fixture contains updated_at, so the new rename to opencti.indicator.updated_at is untested; add the field to at least one test input and its expected output.
Details
The indicator data stream has 20 pipeline test fixtures under _dev/test/pipeline/, and none of them include an updated_at key, so the processor added here never executes during elastic-package test pipeline. The mapping from source updated_at to opencti.indicator.updated_at (and its date type in fields/opencti.yml) is only exercised by the system test.
Recommendation:
Add the field to an existing input fixture, e.g. _dev/test/pipeline/test-hostname.json:
"modified": "2023-01-17T05:53:42.851Z",
"updated_at": "2023-01-17T05:53:43.100Z",then regenerate expectations with elastic-package test pipeline -g so the corresponding -expected.json asserts:
"updated_at": "2023-01-17T05:53:43.100Z"🤖 AI-Generated Review | Vera Review Bot | 📚 Knowledge base: integration-skills
⚠️ Automated review — verify suggestions before applying.
| - name: invalid_or_revoked_from | ||
| type: date | ||
| description: A time from which this indicator should be considered invalid or revoked. | ||
| - name: updated_at |
There was a problem hiding this comment.
Severity: 🟠 High confidence: medium path: packages/ti_opencti/elasticsearch/transform/latest_ioc/fields/opencti.yml:39
Adding opencti.indicator.updated_at to the latest_ioc transform fields without bumping _meta.fleet_transform_version means the transform is not reinstalled on upgrade, so the new mapping never reaches the destination index; bump fleet_transform_version (and the dest.index suffix) in transform.yml.
Details
This PR adds opencti.indicator.updated_at (type: date) to the latest_ioc transform's output field definitions, but elasticsearch/transform/latest_ioc/transform.yml is untouched: _meta.fleet_transform_version stays at 0.8.0 and dest.index stays at logs-ti_opencti_latest.dest_indicator-5.
The comment at the top of that same transform.yml states the rule directly: "You must also bump the fleet_transform_version for any change to this transform configuration to take effect." Field definitions are part of that configuration -- they are what generates the destination index mapping. Without the bump, Fleet does not delete/reinstall the transform on upgrade, and the already-existing -5 destination index keeps its old mapping.
The concrete consequence is a field type conflict. elasticsearch/transform/latest_ioc/manifest.yml sets date_detection: false together with a strings_as_keyword dynamic template, so an undeclared string field is dynamically mapped as keyword. opencti.indicator.updated_at therefore lands as keyword in logs-ti_opencti_latest.indicator while it is date in logs-ti_opencti.indicator-*. That is exactly the "query time field type conflicts" the transform.yml comment warns about, and it breaks range queries and date sorting on the latest IoC view.
Precedent in this repo: PR 20002 (the change released as ti_opencti 2.15.1 / ti_abusech 4.1.2) made a fields-only edit to the transform fields/ directory and bumped both fleet_transform_version (0.6.0 -> 0.7.0) and the dest.index suffix (-3 -> -4) on every affected transform.
Recommendation:
Bump the transform version so the change takes effect, and bump the destination index suffix so a new index is created with the updated mapping, in packages/ti_opencti/elasticsearch/transform/latest_ioc/transform.yml:
dest:
index: "logs-ti_opencti_latest.dest_indicator-6"
aliases:
- alias: "logs-ti_opencti_latest.indicator"
move_on_creation: true
_meta:
managed: true
# Bump this version to delete, reinstall, and restart the transform during
# package installation.
fleet_transform_version: 0.9.0The move_on_creation: true alias already handles cutover, so consumers of logs-ti_opencti_latest.indicator follow the new index automatically.
🤖 AI-Generated Review | Vera Review Bot | 📚 Knowledge base: integration-skills
⚠️ Automated review — verify suggestions before applying.
| "lang": "en", | ||
| "created": "2018-02-05T08:04:53.000Z", | ||
| "modified": "2023-01-17T05:53:45.716Z", | ||
| "updated_at": "2023-01-17T05:53:46.716Z", |
There was a problem hiding this comment.
Severity: 🔵 Low confidence: medium path: packages/ti_opencti/_dev/deploy/docker/files/config.yml:149
The system-test mock's Relay cursors still encode modified sort keys even though the program now requests orderBy: "updated_at", so the fixture no longer reflects what OpenCTI would return; regenerate the cursor values from each node's updated_at.
Details
OpenCTI Relay cursors are base64 of [<sort-value-epoch-ms>, "<standard_id>"], so the encoded timestamp tracks whatever orderBy selects. This PR switches orderBy to updated_at, but the fixture's cursors were not regenerated.
Page 1's endCursor is WzE2NzM5MzQ4MjU3MTYsImluZGljYXRvci0tYmM2MjJhNjEt..., which decodes to [1673934825716, "indicator--bc622a61-52e0-5785-91d3-c7371f07f15d"]. Epoch 1673934825716 is 2023-01-17T05:53:45.716Z -- that node's modified (config.yml:148), not its updated_at of 2023-01-17T05:53:46.716Z (config.yml:149, added here). A real server ordering by updated_at would emit 1673934826716.
The same drift is worse on the last node of page 3: its cursor encodes 1673934847355 (2023-01-17T05:54:07.355Z), which was the modified value this PR rewrote to 2023-01-10T00:00:00.000Z, so it now corresponds to no field on that node at all.
This does not fail the test today -- the mock matches requests by regex and simply echoes these strings back, and the CEL program only consumes pageInfo.endCursor. It is a fixture-fidelity issue: the mock no longer models the pagination behaviour the new orderBy actually produces, which weakens its value as a regression guard for exactly the cursor/ordering interaction this PR changes.
Recommendation:
Recompute each cursor / endCursor from the node's updated_at. For the last node of page 1 (updated_at: 2023-01-17T05:53:46.716Z -> epoch 1673934826716):
# base64('[1673934826716,"indicator--bc622a61-52e0-5785-91d3-c7371f07f15d"]')
cursor: "WzE2NzM5MzQ4MjY3MTYsImluZGljYXRvci0tYmM2MjJhNjEtNTJlMC01Nzg1LTkxZDMtYzczNzFmMDdmMTVkIl0="Apply the same substitution to pageInfo.endCursor for that page, and to the remaining per-edge cursors, then update the after value in the matching request_body regex of the following rule so the mock still matches.
🤖 AI-Generated Review | Vera Review Bot | 📚 Knowledge base: integration-skills
⚠️ Automated review — verify suggestions before applying.
| fields: | ||
| - opencti.indicator.standard_id # STIX ID is globally unique and consistent | ||
| - threat.indicator.modified_at | ||
| - opencti.indicator.updated_at |
There was a problem hiding this comment.
Severity: 🟡 Medium confidence: high path: packages/ti_opencti/data_stream/indicator/elasticsearch/ingest_pipeline/default.yml:928
Adding opencti.indicator.updated_at to the fingerprint makes the README's 'High Availability and Deduplication' section wrong; update the doc template to say the ID is derived from standard_id, modified and updated_at, and that updates are stored as new documents.
Details
The fingerprint now hashes standard_id + threat.indicator.modified_at + opencti.indicator.updated_at, but packages/ti_opencti/docs/README.md still documents the old behaviour in two places:
- Line 97: "Each indicator gets a consistent ID based on its
standard_idandmodifiedtimestamp." That is no longer the field set used. - Line 99: "When an indicator is updated in OpenCTI, the new version replaces the old one in Elasticsearch." With updated_at in the hash, an updated indicator now produces a different _id, so the new version does not replace the old document - both are kept in logs-ti_opencti.indicator-* and only the latest_ioc transform collapses them to one entry in logs-ti_opencti_latest.indicator.
That second sentence is exactly what a user would rely on to reason about storage growth and about which index to query, so leaving it stale is misleading. The generated docs/README.md is built from packages/ti_opencti/_dev/build/docs/README.md, so the source template is where the text needs to change.
Recommendation:
Update the deduplication bullets in _dev/build/docs/README.md (then regenerate docs/README.md):
- **Automatic Deduplication**: The integration uses a fingerprint-based document ID to prevent duplicates. Each indicator version gets a consistent ID based on its `standard_id`, `modified` and `updated_at` timestamps.
- **No Manual Configuration Needed**: Deduplication works automatically - just deploy the integration to multiple agents.
- **Update Handling**: When an indicator is updated in OpenCTI, a new document is indexed alongside the previous version in `logs-ti_opencti.indicator-*`. The `latest_ioc` transform keeps only the most recent version per indicator in `logs-ti_opencti_latest.indicator`, which is the index detection rules and dashboards should query.🤖 AI-Generated Review | Vera Review Bot | 📚 Knowledge base: integration-skills
⚠️ Automated review — verify suggestions before applying.
| target_field: threat.indicator.modified_at | ||
| - rename: | ||
| field: updated_at | ||
| target_field: opencti.indicator.updated_at |
There was a problem hiding this comment.
Severity: 🔵 Low confidence: high path: packages/ti_opencti/data_stream/indicator/elasticsearch/ingest_pipeline/default.yml:103
The new updated_at rename is missing from the README's "Timestamps are mapped as follows" table; add a row for updated_at -> opencti.indicator.updated_at.
Details
packages/ti_opencti/docs/README.md lines 271-281 contain a hand-maintained table listing every source timestamp and its destination field (created, modified, valid_from, valid_until, invalid_or_revoked_from). This PR adds a fifth source timestamp, updated_at -> opencti.indicator.updated_at, but the table was not updated, so it no longer lists all timestamp mappings. Only the auto-generated field reference table (line 321) picked up the new field. The table lives in packages/ti_opencti/_dev/build/docs/README.md.
Recommendation:
Add the missing row to the timestamp table in _dev/build/docs/README.md, after the modified row:
| Source | Destination | Description |
|-------------|-------------------------------|-------------|
| created | event.created | Time of the indicator's creation |
| modified | threat.indicator.modified_at | Time of the indicator's last modification |
| updated_at | opencti.indicator.updated_at | Time the indicator record was last updated in the OpenCTI platform, including UI edits, enrichment and scoring changes |🤖 AI-Generated Review | Vera Review Bot | 📚 Knowledge base: integration-skills
⚠️ Automated review — verify suggestions before applying.
| Authorization: "Bearer test_api_key" | ||
| Content-Type: application/json | ||
| request_body: '/"variables":\{"after":"WzE2NzM5MzQ4NDA4MTAsImluZGljYXRvci0tNWY5NWEyNmEtZjlmMC01ZjhkLTlkMzctYzkxMjUzOTQ2MmUzIl0=","filters":\{"filterGroups":\[\],"filters":\[\{"key":"entity_type","operator":"eq","values":\["Indicator"\]\},\{"key":"revoked","operator":"eq","values":\["false"\]\},\{"key":"updated_at","operator":"gt","values":\["2023-01-17T05:54:00.81Z"\]\}\],"mode":"and"\},"first":3,"orderBy":"modified","orderMode":"asc"\}/' | ||
| request_body: '/"variables":\{"after":"WzE2NzM5MzQ4NDA4MTAsImluZGljYXRvci0tNWY5NWEyNmEtZjlmMC01ZjhkLTlkMzctYzkxMjUzOTQ2MmUzIl0=","filters":\{"filterGroups":\[\],"filters":\[\{"key":"entity_type","operator":"eq","values":\["Indicator"\]\},\{"key":"revoked","operator":"eq","values":\["false"\]\},\{"key":"updated_at","operator":"gt","values":\["2023-01-17T05:54:01.81Z"\]\}\],"mode":"and"\},"first":3,"orderBy":"updated_at","orderMode":"asc"\}/' |
There was a problem hiding this comment.
Severity: 🔵 Low confidence: medium path: packages/ti_opencti/_dev/deploy/docker/files/config.yml:423
The system-test mock's pageInfo.endCursor values still encode modified-based sort keys even though the request now sorts by updated_at; regenerate them from the updated_at values so the fixture matches real server behaviour.
Details
This request asserts after="WzE2NzM5MzQ4NDA4MTAsImluZGljYXRvci0tNWY5NWEyNmEtZjlmMC01ZjhkLTlkMzctYzkxMjUzOTQ2MmUzIl0=", which base64-decodes to [1673934840810, "indicator--5f95a26a-..."]. 1673934840810 is 2023-01-17T05:54:00.810Z - the modified value of the last node in the previous response, not its updated_at (2023-01-17T05:54:01.810Z). The same holds for the earlier endCursor at line 203, which decodes to the modified value 2023-01-17T05:53:45.716Z rather than the updated_at 2023-01-17T05:53:46.716Z.
OpenCTI's Relay cursors encode the active sort key, so now that the query sends orderBy: "updated_at" a real server returns cursors built from updated_at. The test still passes because the CEL program treats the cursor as opaque and echoes it back, but the fixture no longer represents a real response. That matters here specifically: this PR exists because the cursor sort key and the incremental filter key were out of sync, and a fixture that keeps the old sort key in its cursors would not reproduce that class of bug.
Recommendation:
Rebuild the mocked cursors from the updated_at values of the last node in each page. For the second page's endCursor (line 411), base64 of [1673934841810,"indicator--5f95a26a-f9f0-5f8d-9d37-c912539462e3"], and mirror the same value in this request's after:
request_body: '/"variables":\{"after":"WzE2NzM5MzQ4NDE4MTAsImluZGljYXRvci0tNWY5NWEyNmEtZjlmMC01ZjhkLTlkMzctYzkxMjUzOTQ2MmUzIl0=","filters":\{"filterGroups":\[\],"filters":\[\{"key":"entity_type","operator":"eq","values":\["Indicator"\]\},\{"key":"revoked","operator":"eq","values":\["false"\]\},\{"key":"updated_at","operator":"gt","values":\["2023-01-17T05:54:01.81Z"\]\}\],"mode":"and"\},"first":3,"orderBy":"updated_at","orderMode":"asc"\}/'🤖 AI-Generated Review | Vera Review Bot | 📚 Knowledge base: integration-skills
⚠️ Automated review — verify suggestions before applying.
🚀 Benchmarks reportTo see the full report comment with |
|
✅ All changelog entries have the correct PR link. |
| body.data.indicators.edges.map(e, timestamp(e.node.modified)).max() | ||
| : | ||
| state.?last_modified.orValue(null) | ||
| "last_modified": body.data.indicators.edges |
There was a problem hiding this comment.
Severity: 🟡 Medium confidence: medium path: packages/ti_opencti/data_stream/indicator/agent/stream/cel.yml.hbs:187
Advancing last_modified after every page means the 'updated_at > last_modified' filter tightens mid-pagination while the 'after' cursor is also applied, so indicators that share the boundary millisecond are dropped; only promote the high-water mark when hasNextPage is false.
Details
state.last_modified is recomputed on every page as the max updated_at of that page, and it feeds the filter {"key": "updated_at", "operator": "gt", "values": [state.last_modified]} (cel.yml.hbs:136-140). Because after (the Relay cursor) and that filter are sent together and ANDed server-side, the second and subsequent requests of a pagination run apply a strictly-greater cut at exactly the previous page's last sort value. Any indicator whose updated_at equals that value but which sorts after the cursor is excluded by the filter even though search_after would have returned it, and it is excluded again on the next poll because last_modified has already moved past it, so it is never ingested. The PR's own system-test fixture shows both constraints on the same request: _dev/deploy/docker/files/config.yml line 99 expects after: WzE2NzM5MzQ4MjY3MTYs... together with updated_at gt 2023-01-17T05:53:46.716Z, which is page 1's maximum. Same-millisecond ties are realistic in OpenCTI because connector imports and bulk enrichment stamp many entities within the same millisecond. Since orderMode is asc, the final page always carries the run's maximum, so the high-water mark can be promoted once at the end of the run and the filter kept fixed while paging; an interrupted run then simply re-reads from the previous mark, which is idempotent because the ingest pipeline derives a deterministic _id.
Recommendation:
Keep the incremental filter constant for the duration of a pagination run and only advance it on the last page:
"want_more": body.data.indicators.pageInfo.hasNextPage,
"cursor": { "value": body.data.indicators.pageInfo.endCursor },
// Keep the updated_at filter fixed while paging so that the `after`
// cursor alone drives pagination; orderMode is asc, so the final page
// carries the maximum updated_at for the whole run.
"last_modified": body.data.indicators.pageInfo.hasNextPage ?
state.?last_modified.orValue(null)
:
body.data.indicators.edges
.map(e, has(e.node.updated_at) && e.node.updated_at != null, timestamp(e.node.updated_at))
.as(ts, ts.size() > 0 ? ts.max() : state.?last_modified.orValue(null))The policy test expectations (_dev/test/policy/test-default.expected, test-multi-values.expected) and the mocked request bodies in _dev/deploy/docker/files/config.yml need regenerating to match, since requests 2 and 3 would then carry the pre-run updated_at value instead of each page's maximum.
🤖 AI-Generated Review | Vera Review Bot | 📚 Knowledge base: integration-skills
⚠️ Automated review — verify suggestions before applying.
| # newer versions go on top | ||
| - version: "2.15.2" | ||
| changes: | ||
| - description: Fix incremental polling missing UI-edited indicators. |
There was a problem hiding this comment.
Severity: 🔵 Low confidence: medium path: packages/ti_opencti/changelog.yml:4
The 2.15.2 changelog only mentions the polling fix, but this release also adds opencti.indicator.updated_at and recreates the latest_ioc destination index (-5 to -6), which leaves the old index behind; add entries for both.
Details
Two user-visible changes ship in 2.15.2 that the changelog does not mention. First, a new field opencti.indicator.updated_at is added to both the data stream and the latest_ioc transform output. Second, elasticsearch/transform/latest_ioc/transform.yml bumps dest.index from logs-ti_opencti_latest.dest_indicator-5 to -6; the comment in that file states the old destination index is not automatically removed, so on upgrade the latest view is rebuilt from scratch and the -5 index remains and must be cleaned up by hand. Version 2.15.1 set the precedent of describing the transform destination change in its own changelog entry.
Recommendation:
Add entries covering the new field and the transform destination recreation:
- version: "2.15.2"
changes:
- description: Fix incremental polling missing UI-edited indicators.
type: bugfix
link: https://github.com/elastic/integrations/pull/20382
- description: Add `opencti.indicator.updated_at` field.
type: enhancement
link: https://github.com/elastic/integrations/pull/20382
- description: Recreate the `latest_ioc` transform destination index. The previous destination index is not removed automatically and can be deleted manually after the upgrade.
type: enhancement
link: https://github.com/elastic/integrations/pull/20382🤖 AI-Generated Review | Vera Review Bot | 📚 Knowledge base: integration-skills
⚠️ Automated review — verify suggestions before applying.
Review summaryIssues found across the latest commits 6dd879f — 1 medium, 1 low
Issues found across earlier commits 822722a — 1 medium, 2 low
Issues found across earlier commits 25311f7 — 1 high, 1 low
Issues found across earlier commits ae8b84f — 1 critical, 1 high, 1 medium, 1 low
🤖 AI-Generated Review | Vera Review Bot | 📚 Knowledge base: integration-skills
|
💚 Build Succeeded
History
|
|
Tick the box to add this pull request to the merge queue (same as
|
|
Package ti_opencti - 2.15.2 containing this change is available at https://epr.elastic.co/package/ti_opencti/2.15.2/ |
Proposed commit message
Checklist
changelog.ymlfile.