New to Claude Skills? Learn how to install them →

mukul975 on GitHub

Modeling Threats with OpenCTI

Free

Centralize and visualize cyber threat intelligence effectively.

Get this skill

Free · Opens the source repo

What Modeling Threats with OpenCTI does

Modeling Threats with OpenCTI is a skill designed for cybersecurity professionals looking to build a comprehensive threat intelligence knowledge base. By leveraging the OpenCTI platform, analysts can deploy a robust environment using Docker Compose, allowing for the storage, organization, and visualization of structured cyber threat data as a knowledge graph. This skill enables users to model various cyber threat entities such as Threat Actors, Intrusion Sets, and Campaigns according to the STIX 2.1 standard, facilitating a clear understanding of the relationships and tactics employed by adversaries.

The skill utilizes the pycti Python client, which serves as the primary interface for interacting with the OpenCTI GraphQL API. Users can create and manage core STIX domain objects, build relationships to form an adversary graph, and automate the ingestion of threat intelligence from multiple sources. This capability is crucial for correlating Indicators of Compromise (IOCs) from diverse feeds, enabling analysts to produce structured intelligence outputs that can be utilized for detection engineering and incident response.

This tool is particularly beneficial for teams involved in threat modeling, as it allows for the mapping of observed activities to MITRE ATT&CK techniques, thereby supporting coverage and gap analysis. By consolidating fragmented threat intelligence into a single, queryable graph, organizations can enhance their situational awareness and improve their defensive strategies against cyber threats.

Overall, Modeling Threats with OpenCTI is an essential skill for cybersecurity analysts and threat intelligence teams aiming to streamline their threat modeling processes and enhance their operational effectiveness in a complex threat landscape.

When to use it

Use this skill when you need to build a centralized threat intelligence repository and visualize relationships between threat actors and their activities.

When not to use it

This skill may not be suitable for users who are not familiar with Docker or the STIX data model, as it requires specific technical knowledge to deploy and operate effectively.

What you can build with it

Centralized Threat Intelligence Repository

Build a comprehensive knowledge base of threat actors and their tactics using OpenCTI.

Correlating IOCs

Integrate and correlate indicators from multiple threat feeds into a single adversary graph.

Mapping to MITRE ATT&CK

Analyze and map observed activities to MITRE ATT&CK techniques for better coverage assessment.

How to install Modeling Threats with OpenCTI

View source

1. Install with the skills CLI

npx skills add mukul975/anthropic-cybersecurity-skills/modeling-threats-with-opencti --agent claude-code

2. Or install it manually

Download the skill folder and drop it into ~/.claude/skills/ for all projects, or .claude/skills/ to scope it to one repo. Restart Claude Code so it picks up the new skill.

Anthropic's agentic coding CLI, and the reference implementation of Agent Skills. Drop a skill folder into ~/.claude/skills and Claude Code loads it automatically whenever a task matches the skill's description. Claude Code docs

Inside SKILL.md

Written by mukul975

Modeling Threats with OpenCTI

Overview

OpenCTI (Open Cyber Threat Intelligence) is an open-source threat-intelligence platform developed by Filigran that lets analysts store, organize, visualize, and share structured cyber threat intelligence as a knowledge graph. Every object — Threat Actors, Intrusion Sets, Campaigns, Attack Patterns, Malware, Indicators, Observables, Vulnerabilities — is modeled on the STIX 2.1 standard, and the relationships between them (uses, attributed-to, targets, indicates) form a graph that reveals how adversaries operate end to end.

Architecturally, OpenCTI is built from a GraphQL API backed by Elasticsearch/OpenSearch and a graph database, a Redis stream, RabbitMQ message broker, import/export workers, and connectors. Connectors retrieve information from external sources (MITRE ATT&CK, MISP, AlienVault OTX, CISA, abuse.ch, etc.), convert it into STIX 2.1 bundles, and submit those bundles to the platform; workers then ingest the bundles into the graph. The official Python client, pycti (OpenCTIApiClient), is the programmatic interface analysts use to create entities, build relationships, and push STIX bundles.

This skill follows the official OpenCTI documentation (docs.opencti.io) and the OpenCTI-Platform/client-python (pycti) repository. It maps to MITRE ATT&CK T1589 (Gather Victim Identity Information) as part of the broader CTI analysis lifecycle — OpenCTI is where reconnaissance and adversary tradecraft observed across reporting is consolidated, deduplicated, and modeled so detection and response teams can act on it. The threat context is the volume and fragmentation of modern CTI: hundreds of vendor reports, IOC feeds, and ATT&CK updates that are useless until correlated into a single, queryable adversary picture.

When to Use

  • Building a centralized, STIX-native knowledge base of threat actors, campaigns, and TTPs
  • Correlating IOCs and reports from multiple feeds into a single adversary graph
  • Mapping observed activity to MITRE ATT&CK techniques for coverage and gap analysis
  • Producing structured intelligence (STIX bundles) for downstream detection engineering
  • Tracking attribution: which intrusion sets are attributed to which threat actors and campaigns
  • Automating CTI ingestion via connectors and the pycti API

Prerequisites

  • Docker and Docker Compose (OpenCTI is deployed as a container stack)
  • Python 3.8+ for the pycti client:
    pip install pycti stix2
    
  • An OpenCTI instance and an API token (Profile > API access in the UI)
  • Familiarity with the STIX 2.1 data model (SDOs, SROs, observables)
  • RabbitMQ, Redis, and Elasticsearch/OpenSearch reachable by the platform (handled by the reference compose)

Objectives

  • Deploy an OpenCTI platform with workers via Docker Compose
  • Authenticate to the GraphQL API with pycti using an API token
  • Create core STIX domain objects: Threat Actor, Intrusion Set, Campaign, Attack Pattern, Malware
  • Build relationships (uses, attributed-to, targets) to form the adversary graph
  • Enable connectors (MITRE ATT&CK, MISP) to auto-ingest intelligence
  • Submit STIX 2.1 bundles via send_stix2_bundle
  • Query the graph and export an actor's full TTP profile

MITRE ATT&CK Mapping

IDNameRelevance
T1589Gather Victim Identity InformationOpenCTI consolidates reconnaissance and victim/target intelligence observed across reporting into a structured, queryable knowledge graph that supports analysis of adversary targeting.

Workflow

Step 1: Deploy the OpenCTI platform

Use the official Docker Compose stack. Generate the required tokens/UUIDs and start the platform, workers, and dependencies.

git clone https://github.com/OpenCTI-Platform/docker.git opencti-docker
cd opencti-docker

# Generate required secrets (UUID v4 for tokens, base64 for app secret)
cat > .env <<EOF
OPENCTI_ADMIN_EMAIL=admin@opencti.local
OPENCTI_ADMIN_PASSWORD=$(openssl rand -hex 16)
OPENCTI_ADMIN_TOKEN=$(cat /proc/sys/kernel/random/uuid)
OPENCTI_BASE_URL=http://localhost:8080
MINIO_ROOT_USER=$(cat /proc/sys/kernel/random/uuid)
MINIO_ROOT_PASSWORD=$(cat /proc/sys/kernel/random/uuid)
RABBITMQ_DEFAULT_USER=guest
RABBITMQ_DEFAULT_PASS=guest
ELASTIC_MEMORY_SIZE=4G
CONNECTOR_HISTORY_ID=$(cat /proc/sys/kernel/random/uuid)
CONNECTOR_EXPORT_FILE_STIX_ID=$(cat /proc/sys/kernel/random/uuid)
EOF

# Increase vm.max_map_count for Elasticsearch, then start the stack
sudo sysctl -w vm.max_map_count=1048575
docker compose up -d

Access the UI at http://localhost:8080 and log in with the admin credentials from .env.

Step 2: Authenticate with pycti

Create an OpenCTIApiClient instance using your platform URL and API token.

from pycti import OpenCTIApiClient

opencti = OpenCTIApiClient(
    "http://localhost:8080",
    "YOUR_API_TOKEN",  # from Profile > API access, or OPENCTI_ADMIN_TOKEN
)

Step 3: Create core STIX domain objects

Create a Threat Actor, an Intrusion Set, a Campaign, and an Attack Pattern. pycti create() calls act as upserts when update=True.

# Threat Actor (group)
actor = opencti.threat_actor_group.create(
    name="APT-EXAMPLE",
    description="Financially motivated intrusion group tracked in this case.",
    threat_actor_types=["crime-syndicate"],
)

# Intrusion Set
intrusion_set = opencti.intrusion_set.create(
    name="EXAMPLE-SET",
    description="Cluster of activity sharing infrastructure and TTPs.",
)

# Campaign
campaign = opencti.campaign.create(
    name="Operation Example 2026",
    description="Spearphishing campaign targeting the finance sector.",
)

# Attack Pattern linked to MITRE ATT&CK (x_mitre_id maps to the technique)
technique = opencti.attack_pattern.create(
    name="Spearphishing Attachment",
    x_mitre_id="T1566.001",
)

Step 4: Build relationships to form the graph

Connect the objects with STIX relationships so the graph reflects how the adversary operates.

# Intrusion set attributed to the threat actor
opencti.stix_core_relationship.create(
    fromId=intrusion_set["id"],
    toId=actor["id"],
    relationship_type="attributed-to",
)

# Campaign attributed to the intrusion set
opencti.stix_core_relationship.create(
    fromId=campaign["id"],
    toId=intrusion_set["id"],
    relationship_type="attributed-to",
)

# Intrusion set uses the technique
opencti.stix_core_relationship.create(
    fromId=intrusion_set["id"],
    toId=technique["id"],
    relationship_type="uses",
)

Step 5: Add indicators and observables

Create an indicator with a STIX pattern and tie it to the intrusion set via an indicates relationship.

from dateutil.parser import parse

date = parse("2026-06-01").strftime("%Y-%m-%dT%H:%M:%SZ")

indicator = opencti.indicator.create(
    name="C2 domain for Operation Example",
    pattern_type="stix",
    pattern="[domain-name:value = 'malicious-c2.example']",
    x_opencti_main_observable_type="Domain-Name",
    valid_from=date,
)

opencti.stix_core_relationship.create(
    fromId=indicator["id"],
    toId=intrusion_set["id"],
    relationship_type="indicates",
)

Step 6: Submit a STIX 2.1 bundle directly

For bulk ingestion, build a STIX bundle and submit it with send_stix2_bundle — the recommended bulk-ingest path.

import json

with open("threat_report_bundle.json") as f:
    bundle = json.load(f)

opencti.stix2.import_bundle_from_json(
    json.dumps(bundle),
    update=True,
)

Step 7: Enable connectors for automated ingestion

Add connectors to the compose stack so external intelligence (MITRE ATT&CK, MISP) is ingested continuously. Each connector needs its own token.

# Append to docker-compose.yml under services:
  connector-mitre:
    image: opencti/connector-mitre:latest
    environment:
      - OPENCTI_URL=http://opencti:8080
      - OPENCTI_TOKEN=${CONNECTOR_MITRE_TOKEN}
      - CONNECTOR_ID=${CONNECTOR_MITRE_ID}
      - CONNECTOR_TYPE=EXTERNAL_IMPORT
      - CONNECTOR_NAME=MITRE ATT&CK
      - CONNECTOR_SCOPE=tool,report,malware,identity,attack-pattern,intrusion-set,campaign
      - MITRE_INTERVAL=7   # days
    restart: always
docker compose up -d connector-mitre

Step 8: Query the graph and export an actor profile

Read back the adversary's full picture for reporting and detection engineering.

# Resolve all techniques an intrusion set uses
iset = opencti.intrusion_set.read(filters={
    "mode": "and",
    "filters": [{"key": "name", "values": ["EXAMPLE-SET"]}],
    "filterGroups": [],
})

rels = opencti.stix_core_relationship.list(
    fromId=iset["id"],
    relationship_type="uses",
)
for r in rels:
    print(r["to"]["name"], r["to"].get("x_mitre_id"))

Tools and Resources

ToolPurposeSource
OpenCTI PlatformSTIX 2.1 threat-intel knowledge graphhttps://github.com/OpenCTI-Platform/opencti
OpenCTI DockerReference compose stackhttps://github.com/OpenCTI-Platform/docker
pyctiOfficial Python client for the GraphQL APIhttps://github.com/OpenCTI-Platform/client-python
OpenCTI ConnectorsImporters (MITRE, MISP, OTX, CISA, abuse.ch)https://github.com/OpenCTI-Platform/connectors
OpenCTI docsOfficial documentationhttps://docs.opencti.io/latest/
STIX 2.1 specUnderlying data modelhttps://oasis-open.github.io/cti-documentation/

STIX Object Cheat Sheet (pycti entities)

pycti entitySTIX typeUse
threat_actor_groupthreat-actorNamed adversary group
intrusion_setintrusion-setClustered activity / tracked set
campaigncampaignTime-bounded operation
attack_patternattack-patternMITRE ATT&CK technique
malwaremalwareTooling/implant
indicatorindicatorDetection pattern (STIX/Sigma/YARA)
vulnerabilityvulnerabilityCVE
stix_core_relationshiprelationshipuses, attributed-to, targets, indicates

Validation Criteria

  • OpenCTI platform and workers deployed and reachable at the base URL
  • pycti authenticates with a valid API token
  • Threat Actor, Intrusion Set, Campaign, and Attack Pattern objects created
  • Relationships (attributed-to, uses, indicates) built between objects
  • At least one indicator created and linked to an intrusion set
  • A STIX 2.1 bundle ingested via import_bundle_from_json
  • MITRE ATT&CK connector enabled and importing techniques
  • Intrusion-set TTP profile queryable and exportable

Frequently asked questions about Modeling Threats with OpenCTI

Similar skills