Skip to content

feat(trellix-tie): create stream connector to push file reputations via OpenDXL (#6741)#6742

Open
SamuelHassine wants to merge 3 commits into
masterfrom
feature/6741-trellix-tie-stream
Open

feat(trellix-tie): create stream connector to push file reputations via OpenDXL (#6741)#6742
SamuelHassine wants to merge 3 commits into
masterfrom
feature/6741-trellix-tie-stream

Conversation

@SamuelHassine

@SamuelHassine SamuelHassine commented Jun 15, 2026

Copy link
Copy Markdown
Member

Proposed changes

New stream connector that pushes OpenCTI file-hash indicators to Trellix Threat Intelligence Exchange (TIE) as enterprise file reputations, over the OpenDXL fabric.

On each indicator create / update carrying a STIX file-hash pattern, the connector:

  • parses the pattern for MD5 / SHA-1 / SHA-256 hashes;
  • sets the TIE enterprise reputation for those hashes (configurable trust level, default KNOWN_MALICIOUS) via the OpenDXL TIE client (dxltieclient.TieClient.set_file_reputation), attaching the indicator name and a configurable comment.

This is the standard way threat intelligence platforms integrate with the McAfee/Trellix ecosystem: Trellix EDR exposes no outbound IOC REST API, so reputations are published to TIE over OpenDXL. Authentication uses an ePO-provisioned dxlclient.config (broker list + client certificate) referenced by path; the DXL connection is established lazily and reused.

Related issues

Closes #6741

Types of changes

  • New feature (non-breaking change which adds functionality)

Checklist

  • Unit tests for the client (OpenDXL mocked) and the connector (coverage > 80% on new code)
  • Code formatting (black, isort) and linting (flake8, STIX id pylint) pass
  • Generated __metadata__ config schema and documentation
  • Added/updated the connector README.md, config.yml.sample, docker-compose.yml and connector_manifest.json

Further comments

File/cert hashes only (MD5/SHA-1/SHA-256) - TIE reputations do not cover domains/URLs/IPs. Requires a DXL broker and an ePO-provisioned client certificate (standard OpenDXL provisioning). Delete events are ignored (reputations are not removed); resetting to NOT_SET is out of scope for the first version.

Maintainer review and fix pass

An independent senior review hardened the connector and addressed the automated review threads:

  • connector.py: the live stream id is now validated at the start of run() so a placeholder/blank CONNECTOR_LIVE_STREAM_ID fails fast at startup instead of only when the first event arrives; check_stream_id rejects the placeholder case-insensitively (catching the compose default CHANGEME) and rejects empty/whitespace-only values.
  • connector.py: process_message no longer swallows the root cause behind a broad except Exception - it catches only the expected parse errors (json.JSONDecodeError / KeyError / TypeError) and chains via raise ... from err; the per-event logs pass structured context via the meta= keyword.
  • README.md: fixed the TOC anchor, aligned the minimum OpenCTI version with the manifest (6.8.12), corrected the CONNECTOR_TYPE default (STREAM), rewrote the Usage section for a stream connector, and fixed the logger example typo.
  • config.yml.sample / docker-compose.yml: marked CONNECTOR_SCOPE as required (the connectors-sdk base config has no default for scope).
  • Tests: moved the stream-id validation coverage to check_stream_id / run() (parametrized placeholder/blank cases plus a fail-fast-at-startup assertion).
  • Dependencies: bumped the pinned pycti to 7.260615.0 to match the current connectors-sdk, and merged current master to de-stale so the local connectors-sdk used by run_test.sh pins the same pycti and the test environment resolves consistently.

Status

All GitHub Actions checks are green (tests on both event runs, lint/format, STIX ID linter, signed-commits) and there are 0 unresolved review threads; codecov/patch / codecov/project were green on the prior commit and reconcile asynchronously (the change keeps coverage intact and adds tests). mergeStateStatus is BLOCKED only because reviewDecision is REVIEW_REQUIRED - the PR needs one approving review from a maintainer other than me (as the author I cannot self-approve). The branch carries a de-stale merge commit, so it should be squash-merged.

…ia OpenDXL (#6741)

Add a stream connector that pushes OpenCTI file-hash indicators to Trellix TIE
as enterprise file reputations over the OpenDXL fabric - the standard McAfee/
Trellix integration mechanism (Trellix EDR has no outbound IOC REST API). On each
indicator create/update with a STIX file-hash pattern, it sets the TIE reputation
(configurable trust level) for the MD5/SHA-1/SHA-256 hashes via
dxltieclient.TieClient.set_file_reputation. Authentication uses an ePO-provisioned
dxlclient.config file; the DXL connection is established lazily. Includes client +
connector unit tests (OpenDXL mocked), generated config schema/doc, README,
manifest, config sample and docker-compose.
Copilot AI review requested due to automatic review settings June 15, 2026 20:44
@codecov

codecov Bot commented Jun 15, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 84.00000% with 20 lines in your changes missing coverage. Please review.
✅ All tests successful. No failed tests found.

Files with missing lines Patch % Lines
stream/trellix-tie/src/main.py 0.00% 13 Missing ⚠️
...m/trellix-tie/src/trellix_tie_client/api_client.py 90.74% 5 Missing ⚠️
stream/trellix-tie/src/connector/connector.py 95.00% 2 Missing ⚠️

❗ There is a different number of reports uploaded between BASE (3e51b9e) and HEAD (92eb53e). Click for more details.

HEAD has 115 uploads less than BASE
Flag BASE (3e51b9e) HEAD (92eb53e)
connectors 119 4
Additional details and impacted files
@@             Coverage Diff             @@
##           master    #6742       +/-   ##
===========================================
- Coverage   32.30%    0.32%   -31.98%     
===========================================
  Files        1985     1899       -86     
  Lines      122106   119622     -2484     
===========================================
- Hits        39441      389    -39052     
- Misses      82665   119233    +36568     
Files with missing lines Coverage Δ
stream/trellix-tie/src/connector/__init__.py 100.00% <100.00%> (ø)
stream/trellix-tie/src/connector/settings.py 100.00% <100.00%> (ø)
...eam/trellix-tie/src/trellix_tie_client/__init__.py 100.00% <100.00%> (ø)
stream/trellix-tie/src/connector/connector.py 95.00% <95.00%> (ø)
...m/trellix-tie/src/trellix_tie_client/api_client.py 90.74% <90.74%> (ø)
stream/trellix-tie/src/main.py 0.00% <0.00%> (ø)

... and 1119 files with indirect coverage changes

📢 Thoughts on this report? Let us know!

🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@Filigran-Automation Filigran-Automation added the filigran team Item from the Filigran team. label Jun 15, 2026

Copilot AI 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.

Pull request overview

Adds a new stream connector (stream/trellix-tie) that listens to the OpenCTI live stream and, on indicator create/update events containing STIX file-hash patterns, pushes enterprise file reputations to Trellix TIE over OpenDXL.

Changes:

  • Introduces a small OpenDXL/TIE client (TrellixTieClient) plus STIX pattern hash extraction.
  • Implements the stream connector logic and Pydantic-based settings via connectors-sdk.
  • Adds unit tests and ships deployment/metadata assets (Dockerfile, compose, config sample, generated schema/docs, manifest, README).

Reviewed changes

Copilot reviewed 21 out of 21 changed files in this pull request and generated 12 comments.

Show a summary per file
File Description
stream/trellix-tie/src/trellix_tie_client/api_client.py OpenDXL/TIE client wrapper + STIX hash extraction + error wrapping.
stream/trellix-tie/src/trellix_tie_client/init.py Exposes client/error/extractor as package API.
stream/trellix-tie/src/connector/settings.py Connector settings models (stream config + Trellix-specific config).
stream/trellix-tie/src/connector/connector.py Stream message handling and publishing reputations to TIE.
stream/trellix-tie/src/connector/init.py Connector package exports.
stream/trellix-tie/src/main.py Entrypoint wiring settings → helper → connector.
stream/trellix-tie/src/requirements.txt Connector runtime dependencies (pycti, connectors-sdk, OpenDXL libs).
stream/trellix-tie/tests/conftest.py Pytest fixtures/mocking for OpenCTI helper instantiation.
stream/trellix-tie/tests/test_main.py Smoke tests for settings/helper/connector instantiation.
stream/trellix-tie/tests/test-requirements.txt Test dependencies (incl. main requirements + pytest).
stream/trellix-tie/tests/tests_trellix_tie_client/test_api_client.py Unit tests for hash extraction and OpenDXL client behavior (mocked).
stream/trellix-tie/tests/tests_connector/test_connector.py Unit tests for connector message processing behavior.
stream/trellix-tie/tests/tests_connector/test_settings.py Unit tests for settings validation.
stream/trellix-tie/Dockerfile Container build for the connector.
stream/trellix-tie/entrypoint.sh Container entrypoint launching main.py.
stream/trellix-tie/docker-compose.yml Example deployment configuration via environment variables.
stream/trellix-tie/config.yml.sample Example YAML config for manual deployment.
stream/trellix-tie/README.md Connector documentation (purpose, config, deployment, behavior).
stream/trellix-tie/metadata/connector_manifest.json Connector catalog manifest entry.
stream/trellix-tie/metadata/connector_config_schema.json Generated config JSON schema.
stream/trellix-tie/metadata/CONNECTOR_CONFIG_DOC.md Generated config documentation from schema.

Comment thread stream/trellix-tie/src/connector/connector.py Outdated
Comment thread stream/trellix-tie/src/connector/connector.py
Comment thread stream/trellix-tie/src/connector/connector.py
Comment thread stream/trellix-tie/src/connector/connector.py
Comment thread stream/trellix-tie/README.md Outdated
Comment thread stream/trellix-tie/README.md Outdated
Comment thread stream/trellix-tie/README.md Outdated
Comment thread stream/trellix-tie/src/connector/connector.py
Comment thread stream/trellix-tie/docker-compose.yml Outdated
Comment thread stream/trellix-tie/config.yml.sample Outdated

Copilot AI 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.

Pull request overview

Copilot reviewed 21 out of 21 changed files in this pull request and generated 8 comments.

Comment thread stream/trellix-tie/src/connector/connector.py
Comment thread stream/trellix-tie/src/connector/connector.py
Comment thread stream/trellix-tie/src/connector/connector.py
Comment thread stream/trellix-tie/docker-compose.yml
Comment thread stream/trellix-tie/config.yml.sample Outdated
Comment thread stream/trellix-tie/README.md
Comment thread stream/trellix-tie/README.md Outdated
Comment thread stream/trellix-tie/__metadata__/connector_manifest.json
Address the Copilot review on the new Trellix TIE stream connector and keep it
installable against current master:

- connector.py: validate the live stream id at the start of run() so a
  placeholder/blank id fails fast at startup instead of only when the first event
  arrives; check_stream_id now rejects the placeholder case-insensitively and
  rejects empty/whitespace-only values.
- connector.py: process_message catches only the expected parse errors
  (json.JSONDecodeError / KeyError / TypeError) and chains via raise ... from err
  (no longer swallowing the root cause behind a generic ValueError); the
  per-event logs pass structured context via the meta= keyword.
- README.md: fixed the TOC anchor, aligned the minimum OpenCTI version with the
  manifest (6.8.12), corrected the CONNECTOR_TYPE default (STREAM), rewrote the
  Usage section for a stream connector, and fixed the logger example typo.
- config.yml.sample / docker-compose.yml: mark CONNECTOR_SCOPE as required
  (the connectors-sdk base config has no default for scope).
- src/requirements.txt: bump the pinned pycti to 7.260615.0 to match the current
  connectors-sdk (support_version stays >=6.8.12).
@SamuelHassine

Copy link
Copy Markdown
Member Author

Review-and-fix pass summary

Independent senior re-review of the full stream/trellix-tie connector plus the 20 open Copilot threads (they de-dupe to a handful of distinct issues).

Code/test fixes (commit 061a9a5):

  • connector.py (fail-fast + chaining): run() now validates the live stream id before listen_stream(), so a placeholder/blank CONNECTOR_LIVE_STREAM_ID fails fast at startup; check_stream_id rejects the placeholder case-insensitively (catching the compose default CHANGEME) and rejects empty/whitespace-only ids. process_message no longer wraps everything in a broad except Exception - it catches only the expected parse errors (json.JSONDecodeError / KeyError / TypeError) and chains via raise ... from err, and the per-event logs pass context via meta=.
  • README.md: fixed the TOC anchor, aligned the minimum OpenCTI version with the manifest (6.8.12), corrected the CONNECTOR_TYPE default (STREAM), rewrote the Usage section for a stream connector, and fixed the logger example typo.
  • config.yml.sample / docker-compose.yml: marked CONNECTOR_SCOPE as required (the connectors-sdk base config has no default for scope).
  • Tests: moved the stream-id coverage to check_stream_id / run() (parametrized placeholder/blank cases plus a fail-fast-at-startup assertion).

One reviewer suggestion not applied verbatim: a thread asked to add exc_info=True to the caught-exception log. pycti's connector_logger (AppLogger) methods are def error(self, message, meta=None) and do not accept exc_info (it would raise a TypeError), so I used the repo's meta= pattern instead; the caught TrellixTieAPIError already chains its root cause via raise ... from err in the client.

CI fix (de-stale):

  • The branch was behind master, and run_test.sh installs the local connectors-sdk from the checked-out tree. The stale copy still pinned pycti==7.260609.0, which would conflict with the 7.260615.0 reinstalled from opencti master on the push-event test run. Merging current master updates the local connectors-sdk pin (the connector's own support_version stays >=6.8.12).

Verification:

  • black / isort --profile black / flake8 --ignore=E,W clean and all 32 unit tests pass locally. All GitHub Actions checks are green on the new head (both Test stream/trellix-tie runs, lint/format, STIX ID linter, signed-commits). codecov/patch / codecov/project were green on the prior commit and reconcile asynchronously; coverage is maintained (tests added, none removed). filigran/cla satisfied (organization member).
  • Review threads: 0 unresolved (all 20 replied to and resolved). Both new commits are GPG-signed.

Remaining (non-CI) blocker: mergeStateStatus is BLOCKED only because reviewDecision is REVIEW_REQUIRED - the PR needs one approving review from a Filigran maintainer other than me. As the author I cannot self-approve. Once approved, recommend squash-merge (the branch carries a de-stale merge commit).

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

Labels

filigran team Item from the Filigran team.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat(trellix-tie): create stream connector to push file reputations via OpenDXL

4 participants