Skip to content

feat(lab539-aitm-feed): add external import connector (#6703)#6704

Open
Lab539 wants to merge 1 commit into
OpenCTI-Platform:masterfrom
Lab539:feature/lab539-aitm-feed
Open

feat(lab539-aitm-feed): add external import connector (#6703)#6704
Lab539 wants to merge 1 commit into
OpenCTI-Platform:masterfrom
Lab539:feature/lab539-aitm-feed

Conversation

@Lab539

@Lab539 Lab539 commented Jun 12, 2026

Copy link
Copy Markdown

Proposed changes

  • Add external import connector for the Lab539 AiTM Feed, providing real-time Adversary-in-the-Middle (AiTM) infrastructure threat intelligence
  • Imports detections as STIX 2.1 indicators with linked IPv4/IPv6 and domain name observables, TLP:AMBER marking, and deterministic STIX IDs seeded from eventid
  • Incremental imports via timestamp-based filtering with lightweight pre-check via /last-event endpoint

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

API credentials are required to test this connector. Happy to provide these privately - please reach out via Filigran Slack or directly. Docker image is published at lab539/opencti-aitm-feed-connector:latest.

Copilot AI review requested due to automatic review settings June 12, 2026 17:29
@filigran-cla-bot filigran-cla-bot Bot added the cla:pending CLA signature required. label Jun 12, 2026
@filigran-cla-bot

filigran-cla-bot Bot commented Jun 12, 2026

Copy link
Copy Markdown

Contributor License Agreement

CLA signed 💚

Thank you @Lab539 for signing the Contributor License Agreement! Your pull request can now be reviewed and merged.

We appreciate your contribution to Filigran's open source projects! ❤️

This is an automated message from the Filigran CLA Bot.

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

Note

Copilot was unable to run its full agentic suite in this review.

Adds a new external-import OpenCTI connector for Lab539’s AiTM Feed, including configuration, API client, STIX conversion logic, containerization assets, and unit tests.

Changes:

  • Introduce connector runtime (settings, API client, scheduler, STIX bundle generation).
  • Add Docker/Docker Compose deployment artifacts and manifest/README documentation.
  • Add pytest-based unit tests and shared fixtures.

Reviewed changes

Copilot reviewed 18 out of 20 changed files in this pull request and generated 10 comments.

Show a summary per file
File Description
external-import/lab539-aitm-feed/src/main.py Adds connector entry point wiring settings → helper → connector run loop
external-import/lab539-aitm-feed/src/lab539_aitm_connector/settings.py Defines connector and feed configuration models and defaults
external-import/lab539-aitm-feed/src/lab539_aitm_connector/api_client.py Implements AiTM Feed API client for last-event and list endpoints
external-import/lab539-aitm-feed/src/lab539_aitm_connector/converter_to_stix.py Converts feed records into STIX Indicator + author identity + bundle dedupe
external-import/lab539-aitm-feed/src/lab539_aitm_connector/connector.py Implements OpenCTI connector run behavior, state tracking, and ingestion
external-import/lab539-aitm-feed/src/lab539_aitm_connector/init.py Exposes connector class as package public API
external-import/lab539-aitm-feed/src/requirements.txt Adds Python dependencies for the connector runtime
external-import/lab539-aitm-feed/Dockerfile Container build for connector execution
external-import/lab539-aitm-feed/docker-compose.yml Example deployment configuration
external-import/lab539-aitm-feed/src/.env.sample Sample env vars for local/docker usage
external-import/lab539-aitm-feed/.dockerignore Excludes dev/test artifacts from Docker build context
external-import/lab539-aitm-feed/metadata/connector_manifest.json Registers connector metadata for catalog/registry
external-import/lab539-aitm-feed/README.md Documents features, configuration, and deployment
external-import/lab539-aitm-feed/tests/conftest.py Adds shared pytest fixtures
external-import/lab539-aitm-feed/tests/test_api_client.py Unit tests for API client behavior and error handling
external-import/lab539-aitm-feed/tests/test_converter_to_stix.py Unit tests for STIX conversion, deterministic IDs, dedupe, TLP marking
external-import/lab539-aitm-feed/tests/test_settings.py Unit tests for settings validation and defaults
external-import/lab539-aitm-feed/tests/test-requirements.txt Test dependencies for running pytest

Comment on lines +81 to +86
if last_run is None:
self.helper.connector_logger.info(
f"{self.config.connector.name}: First run, pulling "
f"{self.config.aitm_feed.first_run_lookback_days} days of data"
)
records = self.client.get_records()
Comment on lines +45 to +51
def _get_ip_type(self, ip: str) -> str:
"""Return the STIX type for a given IP address."""
try:
ipaddress.IPv4Address(ip)
return "ipv4-addr"
except ValueError:
return "ipv6-addr"
Comment on lines +72 to +77
def _build_pattern(self, ip: str, ip_type: str, domain_value: str) -> str:
"""Build a STIX pattern from IP and domain values."""
pattern_parts = [f"[{ip_type}:value = '{ip}']"]
if domain_value:
pattern_parts.append(f"[domain-name:value = '{domain_value}']")
return " OR ".join(pattern_parts)
Comment on lines +41 to +44
tlp_level: Literal["white", "green", "amber", "amber+strict", "red"] = Field(
description="TLP marking level applied to all imported objects.",
default="amber",
)
Comment on lines +44 to +48
def _is_new_data_available(self) -> bool:
"""Lightweight check via last-event endpoint before pulling full dataset."""
state = self.helper.get_state()
last_event_id = state.get("last_event_id") if state else None
current_event_id = self.client.get_last_event()
Comment on lines +56 to +62
def _update_last_event_id(self) -> None:
"""Store the current latest eventid in connector state."""
current_event_id = self.client.get_last_event()
if current_event_id:
state = self.helper.get_state() or {}
state["last_event_id"] = current_event_id
self.helper.set_state(state)
Comment on lines +17 to +24
def get_last_event(self) -> str | None:
"""Lightweight check for new data. No auth required."""
try:
response = requests.get(f"{self.base_url}/last-event", timeout=10)
response.raise_for_status()
return response.json().get("eventid")
except Exception: # pylint: disable=broad-exception-caught
return None
requests==2.33.1
stix2==3.0.2
isodate==0.7.2
connectors-sdk @ git+https://github.com/OpenCTI-Platform/connectors.git@master#subdirectory=connectors-sdk
Comment on lines +18 to +22
| Object | Type | Description |
|--------|------|-------------|
| Indicator | `indicator` | STIX pattern combining IP and domain, with confidence score and detection metadata |
| IP Address | `ipv4-addr` / `ipv6-addr` | The infrastructure IP address |
| Domain Name | `domain-name` | The hostname or domain associated with the infrastructure |
Comment on lines +44 to +45
| Parameter | Docker environment variable | Default | Description |
|-----------|-----------------------------|---------|-------------|
@Lab539 Lab539 force-pushed the feature/lab539-aitm-feed branch from 7fca080 to df0852d Compare June 12, 2026 17:50
@filigran-cla-bot filigran-cla-bot Bot removed the cla:pending CLA signature required. label Jun 12, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat(connectors): add Lab539 AiTM Feed external import connector

3 participants