Skip to content

Conversation

@romain-filigran
Copy link
Member

Proposed changes

Related issues

Checklist

  • I consider the submitted work as finished
  • I have signed my commits using GPG key.
  • I tested the code for its functionality using different use cases
  • I added/update the relevant documentation (either on github or on notion)
  • Where necessary I refactored code to improve the overall quality

Further comments

@romain-filigran romain-filigran linked an issue Jan 4, 2026 that may be closed by this pull request
@romain-filigran romain-filigran added new use to identify new integration filigran team use to identify PR from the Filigran team labels Jan 4, 2026
@SamuelHassine SamuelHassine requested a review from Copilot January 8, 2026 21:04
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR introduces a new external import connector for ingesting Sigma detection rules from the SigmaHQ repository into OpenCTI as indicators. The connector fetches rule packages from GitHub releases, converts them to STIX format, and creates indicators with relationships to attack patterns and vulnerabilities.

Key changes:

  • New connector implementation with GitHub API client to fetch Sigma rule packages
  • STIX conversion logic that transforms Sigma rules into indicators with relationships
  • Configuration support for multiple rule package types (all rules, core, core+, core++, emerging threats)

Reviewed changes

Copilot reviewed 16 out of 17 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
external-import/sigmahq/src/sigmahq_client/api_client.py GitHub API client for downloading and parsing Sigma rule packages
external-import/sigmahq/src/connector/converter_to_stix.py Converts Sigma rules to STIX indicators with attack pattern and vulnerability relationships
external-import/sigmahq/src/connector/connector.py Main connector orchestration logic with state management
external-import/sigmahq/src/connector/settings.py Configuration model for connector and SigmaHQ-specific settings
external-import/sigmahq/src/requirements.txt Python dependencies including pycti, pydantic, and pySigma
external-import/sigmahq/README.md Documentation describing connector purpose and installation
external-import/sigmahq/Dockerfile Container image definition for the connector
external-import/sigmahq/docker-compose.yml Docker compose configuration example
external-import/sigmahq/config.yml.sample Sample configuration file

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

# Define headers in session and update when needed
self.session = requests.Session()

def get_lastest_published_version(self) -> dict[str, Any] | None:
Copy link

Copilot AI Jan 8, 2026

Choose a reason for hiding this comment

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

Corrected spelling of 'lastest' to 'latest'.

Copilot uses AI. Check for mistakes.
stix_objects.extend(stix_entities)
except Exception as err:
self.helper.connector_logger.error(
f"An exception occurred while converting SigmaHQ rule: {rule.filename}",
Copy link

Copilot AI Jan 8, 2026

Choose a reason for hiding this comment

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

The variable rule is a dictionary with keys 'filename' and 'rule_content', not an object with a .filename attribute. This will raise an AttributeError. Change to rule['filename'] or rule.get('filename').

Suggested change
f"An exception occurred while converting SigmaHQ rule: {rule.filename}",
f"An exception occurred while converting SigmaHQ rule: {rule.get('filename')}",

Copilot uses AI. Check for mistakes.
)

# get latest rule package version
release_metadata = self.client.get_lastest_published_version()
Copy link

Copilot AI Jan 8, 2026

Choose a reason for hiding this comment

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

Corrected spelling of 'get_lastest_published_version' to 'get_latest_published_version'.

Suggested change
release_metadata = self.client.get_lastest_published_version()
release_metadata = self.client.get_latest_published_version()

Copilot uses AI. Check for mistakes.
rules = self.client.download_and_convert_package(
asset["browser_download_url"]
)

Copy link

Copilot AI Jan 8, 2026

Choose a reason for hiding this comment

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

If no matching asset is found in the loop at lines 35-39, rules will remain None, causing a TypeError when attempting to iterate. Add a check after the asset loop to handle the case where rules is still None.

Suggested change
if rules is None:
self.helper.connector_logger.warning(
f"No matching asset found for rule package '{rule_package}'."
)
return stix_objects

Copilot uses AI. Check for mistakes.
Comment on lines +56 to +57
def download_and_convert_package(self, url):

Copy link

Copilot AI Jan 8, 2026

Choose a reason for hiding this comment

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

Missing docstring for the download_and_convert_package method. Should document the expected format of the url parameter and describe the return value structure (list of dictionaries with 'filename' and 'rule_content' keys).

Suggested change
def download_and_convert_package(self, url):
def download_and_convert_package(self, url):
"""
Download a Sigma rule package from a ZIP URL and convert its YAML files.
The given URL is expected to be an HTTP(S) URL pointing to a ZIP archive
that contains Sigma rule files. Only files with a ``.yml`` extension are
processed; directories and other file types inside the archive are ignored.
:param url: HTTP or HTTPS URL of the ZIP archive containing Sigma rules.
:return: A list of dictionaries, each representing a Sigma rule with:
- ``filename``: the path/name of the rule file inside the archive.
- ``rule_content``: the UTF-8 decoded text content of the rule file.
Returns ``None`` if an error occurs during download or extraction.
"""

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

filigran team use to identify PR from the Filigran team new use to identify new integration

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[sigmaHQ] New connector to ingest Sigma rules

2 participants