Skip to content

Commit 8aadca3

Browse files
Add comprehensive GitHub Copilot instructions for OpenCTI connectors repository
Co-authored-by: SamuelHassine <1334279+SamuelHassine@users.noreply.github.com>
1 parent 6c5d1a7 commit 8aadca3

File tree

1 file changed

+301
-0
lines changed

1 file changed

+301
-0
lines changed

.github/copilot-instructions.md

Lines changed: 301 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,301 @@
1+
# OpenCTI Connectors Repository - Copilot Instructions
2+
3+
## Repository Overview
4+
5+
This is the **OpenCTI connectors** monorepo, containing 200+ Python-based connectors that integrate the OpenCTI threat intelligence platform with external tools and data sources. The repository uses a multi-connector architecture with shared utilities and strict validation pipelines.
6+
7+
**Key Statistics:**
8+
- **Language:** Python 3.11-3.12 (Alpine-based Docker images)
9+
- **Connector Types:** 128 external-import, 53 internal-enrichment, 28 stream, 6 internal-export-file, 6 internal-import-file
10+
- **Build System:** CircleCI with dynamic pipeline generation
11+
- **Testing:** pytest with isolated virtual environments per connector
12+
13+
## Critical Build & Validation Requirements
14+
15+
### Code Formatting (ALWAYS REQUIRED)
16+
17+
**Before committing any Python code changes, you MUST run both formatters:**
18+
19+
```bash
20+
# Install formatting tools (if not already installed)
21+
pip install isort==7.0.0 black==25.12.0 --user
22+
23+
# Run isort first
24+
isort --profile black --line-length 88 .
25+
26+
# Then run black
27+
black .
28+
```
29+
30+
**Note:** The CI will fail if code is not properly formatted. These commands MUST be run before pushing code.
31+
32+
### Linting Requirements
33+
34+
**1. Flake8 (Basic Linting)**
35+
```bash
36+
pip install flake8 --user
37+
flake8 --ignore=E,W .
38+
```
39+
40+
**2. Custom Pylint Plugin (STIX ID Validation - CRITICAL)**
41+
42+
This custom checker ensures STIX2 objects use deterministic IDs. **ALWAYS run this before committing connector code:**
43+
44+
```bash
45+
cd shared/pylint_plugins/check_stix_plugin
46+
pip install -r requirements.txt
47+
48+
# Run on your connector directory (example for external-import/mycconnector)
49+
PYTHONPATH=. python -m pylint ../../../external-import/myconnector \
50+
--disable=all \
51+
--enable=no_generated_id_stix,no-value-for-parameter,unused-import \
52+
--load-plugins linter_stix_id_generator
53+
```
54+
55+
**Common Issue:** If you create STIX2 objects, you MUST use deterministic ID generation via pycti or the new connectors-sdk models. Never let stix2 library auto-generate IDs.
56+
57+
### Running Tests
58+
59+
**Test Structure:** Each connector with tests has a `tests/test-requirements.txt` file. Tests run in isolated virtual environments.
60+
61+
**To run tests for a specific connector:**
62+
63+
```bash
64+
# Run test script with specific test-requirements.txt
65+
bash run_test.sh ./external-import/myconnector/tests/test-requirements.txt
66+
```
67+
68+
**Important Notes:**
69+
- The test script (`run_test.sh`) checks for changes from `master` branch
70+
- Tests only run if connector or connectors-sdk has changes (on non-master branches)
71+
- Test script installs latest pycti from GitHub master branch
72+
- If connector depends on connectors-sdk, it installs local version
73+
- Test output goes to `test_outputs/` directory
74+
- Tests use pytest with JUnit XML output
75+
76+
**Test Dependencies Common Pattern:**
77+
```
78+
pytest
79+
pycti
80+
connectors-sdk @ git+https://github.com/OpenCTI-Platform/connectors.git@master#subdirectory=connectors-sdk
81+
```
82+
83+
## Repository Structure
84+
85+
### Top-Level Directories
86+
87+
```
88+
├── .circleci/ # CI/CD configuration
89+
│ ├── config.yml # Main CircleCI workflow
90+
│ ├── scripts/ # Dynamic pipeline generation (generate_ci.py)
91+
│ └── vars.yml # Connector-specific build configurations
92+
├── .github/ # GitHub workflows & templates
93+
├── connectors-sdk/ # Shared SDK for connector development (Python 3.11+)
94+
├── external-import/ # 128 connectors for importing external threat intel
95+
├── internal-enrichment/ # 53 connectors for enriching existing data
96+
├── internal-export-file/ # 6 connectors for exporting data files
97+
├── internal-import-file/ # 6 connectors for importing data files
98+
├── stream/ # 28 connectors for streaming data
99+
├── shared/ # Shared utilities
100+
│ ├── pylint_plugins/ # Custom pylint plugins (STIX ID checker)
101+
│ └── tools/ # Manifest/schema generation scripts
102+
├── templates/ # Connector templates for each type
103+
└── tests/ # Repository-level tests
104+
```
105+
106+
### Standard Connector Structure
107+
108+
Every connector follows this pattern:
109+
110+
```
111+
external-import/myconnector/
112+
├── __metadata__/
113+
│ ├── connector_manifest.json # Connector metadata (title, description, etc.)
114+
│ ├── connector_config_schema.json # Config JSON schema (auto-generated)
115+
│ └── logo.png # Connector logo
116+
├── src/
117+
│ ├── connector/ # Main logic
118+
│ │ ├── connector.py # Core connector class
119+
│ │ ├── converter_to_stix.py # STIX conversion logic
120+
│ │ └── settings.py # Config validation
121+
│ ├── main.py # Entry point
122+
│ └── requirements.txt # Python dependencies
123+
├── tests/
124+
│ ├── tests_connector/ # Test modules
125+
│ ├── conftest.py # pytest configuration
126+
│ └── test-requirements.txt # Test dependencies
127+
├── .env.sample # Environment variable template
128+
├── docker-compose.yml # Docker deployment config
129+
├── Dockerfile # Container build
130+
├── entrypoint.sh # Container entrypoint
131+
└── README.md # Connector documentation
132+
```
133+
134+
## Creating New Connectors
135+
136+
**Use the provided script to scaffold a new connector:**
137+
138+
```bash
139+
cd templates
140+
sh create_connector_dir.sh -t <TYPE> -n <NAME>
141+
```
142+
143+
**Available types:** `external-import`, `internal-enrichment`, `stream`, `internal-import-file`, `internal-export-file`
144+
145+
**After creating, update these files:**
146+
1. Replace all `Template`/`template` references with your connector name
147+
2. Update `__metadata__/connector_manifest.json` with accurate information
148+
3. Configure environment variables in `.env.sample`
149+
4. Implement connector logic in `src/connector/connector.py`
150+
151+
## Key Configuration Files
152+
153+
### Root Level
154+
155+
- **`.flake8`** - Flake8 configuration (ignores: E203, E266, E501, W503, F403, F401)
156+
- **`.pre-commit-config.yaml`** - Pre-commit hooks (black, flake8, isort, GPG signing)
157+
- **`.pylintrc`** - Pylint configuration
158+
- **`ci-requirements.txt`** - CI dependencies: `isort==7.0.0 black==25.12.0 pytest==8.4.2`
159+
- **`Makefile`** - Manifest and schema generation commands
160+
- **`run_test.sh`** - Test execution script (checks for changes, runs pytest)
161+
- **`manifest.json`** - Global manifest (auto-generated from all connector manifests)
162+
163+
### CircleCI Pipeline
164+
165+
**Workflow Steps:**
166+
1. **ensure_formatting** - Runs isort and black checks (Python 3.12)
167+
2. **base_linter** - Runs flake8 with `--ignore=E,W`
168+
3. **linter** - Runs custom pylint plugin for STIX ID validation
169+
4. **test** - Runs pytest for changed connectors (parallelism: 4, Python 3.11)
170+
5. **build_manifest** - Generates manifest.json and config schemas
171+
6. **build** - Builds Docker images for changed connectors
172+
173+
**Important:** Tests and builds only run for connectors with changes (unless on master or connectors-sdk changed).
174+
175+
## Connectors SDK
176+
177+
**Location:** `connectors-sdk/`
178+
179+
**Purpose:** Provides models, exceptions, and utilities for building connectors.
180+
181+
**Installation:**
182+
```bash
183+
pip install "connectors-sdk @ git+https://github.com/OpenCTI-Platform/connectors.git@master#subdirectory=connectors-sdk"
184+
```
185+
186+
**Key Features:**
187+
- STIX2.1 compliant models with deterministic IDs
188+
- Pre-built classes for IOCs, Authors, Markings, Relationships
189+
- Exception handling utilities
190+
- Pydantic-based configuration validation
191+
192+
**Example Usage:**
193+
```python
194+
from connectors_sdk.models import IPV4Address, OrganizationAuthor, TLPMarking
195+
from connectors_sdk.models.octi import related_to
196+
197+
author = OrganizationAuthor(name="Example Author")
198+
ip = IPV4Address(value="127.0.0.1", author=author, markings=[TLPMarking(level="amber+strict")])
199+
stix_object = ip.to_stix2_object() # Deterministic ID generated
200+
```
201+
202+
## Dockerfile Pattern
203+
204+
All connectors use Alpine-based Python images:
205+
206+
```dockerfile
207+
FROM python:3.12-alpine
208+
ENV CONNECTOR_TYPE=EXTERNAL_IMPORT
209+
210+
COPY src /opt/opencti-connector-name
211+
212+
RUN apk --no-cache add git build-base libmagic libffi-dev && \
213+
cd /opt/opencti-connector-name && \
214+
pip3 install --no-cache-dir -r requirements.txt && \
215+
apk del git build-base
216+
217+
COPY entrypoint.sh /
218+
RUN chmod +x /entrypoint.sh
219+
ENTRYPOINT ["/entrypoint.sh"]
220+
```
221+
222+
**Note:** Some connectors use Python 3.11 (see `.circleci/vars.yml` for exceptions).
223+
224+
## Common Issues & Workarounds
225+
226+
### Issue: Test Script Fails with "fatal: Not a valid object name origin/master"
227+
**Workaround:** The script expects `origin/master` remote ref. In CI/local environments with shallow clones, you may need to fetch master branch first.
228+
229+
### Issue: Tests Not Running
230+
**Cause:** Test script only runs tests for connectors with changes (detected via git diff).
231+
**Workaround:** Set `CIRCLE_BRANCH=master` to force all tests to run, or make a change in the connector directory.
232+
233+
### Issue: Pylint Plugin Fails
234+
**Common Cause:** Creating STIX2 objects without deterministic IDs.
235+
**Fix:** Use pycti's `generate_id()` methods or connectors-sdk models.
236+
237+
### Issue: Import/Dependency Errors During Tests
238+
**Cause:** Tests install latest pycti from GitHub, which may have breaking changes.
239+
**Workaround:** Pin specific pycti version in test-requirements.txt if needed.
240+
241+
## Manifest & Schema Generation
242+
243+
**Commands (defined in Makefile):**
244+
245+
```bash
246+
# Generate single connector manifest
247+
make connector_manifest
248+
249+
# Generate all connector manifests
250+
make connectors_manifests
251+
252+
# Generate single connector config schema
253+
make connector_config_schema
254+
255+
# Generate all connector config schemas
256+
make connectors_config_schemas
257+
258+
# Generate global manifest.json
259+
make global_manifest
260+
```
261+
262+
**Process:** These scripts scan `__metadata__/connector_manifest.json` files and consolidate them.
263+
264+
## Python Version Requirements
265+
266+
- **Connectors SDK:** Python >=3.11, <3.13
267+
- **Most Connectors:** Python 3.12 (Alpine)
268+
- **Some Stream Connectors:** Python 3.11 (see `.circleci/vars.yml`)
269+
- **CI Environment:** Python 3.11 for tests, Python 3.12 for linting
270+
271+
## Important Notes
272+
273+
1. **ALWAYS format code** with black and isort before committing
274+
2. **ALWAYS run custom pylint plugin** when changing connector code that creates STIX objects
275+
3. **NEVER auto-generate STIX IDs** - use deterministic generation via pycti or connectors-sdk
276+
4. **Test isolation** - Each connector's tests run in a separate virtual environment
277+
5. **Commit signing** - All commits should be GPG signed (enforced by pre-commit hook)
278+
6. **Docker networking** - When running locally, connectors expect `docker_default` network
279+
7. **Environment variables** - Use `.env.sample` as template, never commit actual secrets
280+
281+
## Validation Checklist
282+
283+
Before submitting a PR with connector changes:
284+
285+
- [ ] Code formatted with `black .` and `isort --profile black .`
286+
- [ ] Passes flake8: `flake8 --ignore=E,W .`
287+
- [ ] Passes custom pylint: `cd shared/pylint_plugins/check_stix_plugin && PYTHONPATH=. python -m pylint <path>`
288+
- [ ] Tests pass: `bash run_test.sh <path-to-test-requirements.txt>`
289+
- [ ] Docker image builds: `docker build -t test .`
290+
- [ ] `__metadata__/connector_manifest.json` updated with accurate information
291+
- [ ] README.md updated with connector-specific instructions
292+
- [ ] No secrets in code or config files
293+
294+
## Trust These Instructions
295+
296+
These instructions are comprehensive and tested. Only search for additional information if:
297+
- Instructions are incomplete for your specific use case
298+
- You encounter an error not documented here
299+
- You need connector-specific implementation details
300+
301+
For connector development patterns, refer to existing connectors as examples. The codebase is consistent, so patterns from one connector generally apply to others of the same type.

0 commit comments

Comments
 (0)