<!-- Copyright (c) 2026 defconxt. All rights reserved. -->
<!-- Licensed under AGPL-3.0 — see LICENSE file for details. -->
---
name: implementing-stix-taxii-feeds
description: >-
  Implement STIX 2.1 structured threat intelligence and TAXII 2.1 feed
  consumption for automated CTI sharing and platform integration.
domain: cybersecurity
subdomain: threat-intelligence
tags:
  - stix
  - taxii
  - cti-sharing
  - opencti
  - misp
  - threat-feeds
version: "1.0"
author: defconxt
license: AGPL-3.0
metadata:
  mitre-attack: []
---
# Implementing STIX/TAXII Feeds

## Overview

STIX (Structured Threat Information eXpression) 2.1 provides a standardized
language for threat intelligence, while TAXII (Trusted Automated eXchange of
Intelligence Information) 2.1 defines the transport protocol. This skill covers
producing and consuming STIX bundles, configuring TAXII clients/servers, integrating
feeds with MISP and OpenCTI, and building automated ingestion pipelines.

## Prerequisites

- Python 3.10+ with `stix2`, `taxii2-client`, `cti-taxii-client`
- TAXII 2.1 server access (MITRE ATT&CK, Anomali STAXX, or self-hosted)
- OpenCTI or MISP instance for feed storage
- Understanding of STIX Domain Objects (SDOs) and Relationships

```bash
pip install stix2 taxii2-client requests
```

## Key Concepts

### STIX 2.1 Object Types

**STIX Domain Objects (SDOs):**
- `attack-pattern`: TTP (maps to ATT&CK technique)
- `campaign`: named set of adversary activities
- `indicator`: detection pattern with valid_from/valid_until
- `intrusion-set`: threat actor group
- `malware`: malicious software instance
- `threat-actor`: individual or group identity
- `tool`: legitimate software used by adversaries

**STIX Cyber Observable Objects (SCOs):**
- `ipv4-addr`, `ipv6-addr`, `domain-name`, `url`
- `file` (with hashes), `email-addr`, `process`

**STIX Relationship Objects (SROs):**
- `relationship`: links two SDOs (e.g., "malware uses attack-pattern")
- `sighting`: observed instance of an indicator or SDO

### TAXII 2.1 Architecture

```
Discovery URL → API Root → Collections → Objects
  /taxii2/      /api/v21/   /collections/  /objects/
```

**Authentication:** Basic auth, API key, or certificate-based.

### Traffic Light Protocol (TLP)

| Marking | Sharing Scope |
|---------|--------------|
| TLP:CLEAR | Unrestricted |
| TLP:GREEN | Community sharing |
| TLP:AMBER | Organization + need-to-know |
| TLP:AMBER+STRICT | Organization only |
| TLP:RED | Named recipients only |

## Workflow

### Step 1: Poll TAXII Collection

```python
from taxii2client.v21 import Collection, Server
import json

# Connect to MITRE ATT&CK TAXII server
server = Server("https://cti-taxii.mitre.org/taxii2/")
api_root = server.api_roots[0]

# List collections
for collection in api_root.collections:
    print(f"{collection.id}: {collection.title}")

# Get Enterprise ATT&CK collection
collection = Collection(
    "https://cti-taxii.mitre.org/stix/collections/95ecc380-afe9-11e4-9b6c-751b66dd541e/"
)
objects = collection.get_objects()
bundle = json.loads(objects.text) if hasattr(objects, 'text') else objects
print(f"Objects retrieved: {len(bundle.get('objects', []))}")
```

### Step 2: Create STIX 2.1 Indicator

```python
import stix2

indicator = stix2.Indicator(
    name="Malicious C2 Domain",
    description="Domain used by APT29 for C2 communication",
    pattern="[domain-name:value = 'evil-c2.example.com']",
    pattern_type="stix",
    valid_from="2026-01-01T00:00:00Z",
    valid_until="2026-06-01T00:00:00Z",
    indicator_types=["malicious-activity"],
    confidence=85,
    object_marking_refs=[stix2.TLP_AMBER],
)
print(indicator.serialize(pretty=True))
```

### Step 3: Build STIX Bundle with Relationships

```python
import stix2

threat_actor = stix2.ThreatActor(
    name="APT29",
    threat_actor_types=["nation-state"],
    aliases=["Cozy Bear", "Midnight Blizzard"],
    roles=["agent"],
    sophistication="expert",
    primary_motivation="organizational-gain",
)

malware = stix2.Malware(
    name="SUNBURST",
    malware_types=["backdoor"],
    is_family=False,
)

relationship = stix2.Relationship(
    relationship_type="uses",
    source_ref=threat_actor.id,
    target_ref=malware.id,
    confidence=90,
)

bundle = stix2.Bundle(objects=[threat_actor, malware, relationship])
with open("apt29_bundle.json", "w") as f:
    f.write(bundle.serialize(pretty=True))
```

### Step 4: Validate STIX Bundle

```python
import stix2

with open("apt29_bundle.json") as f:
    bundle = stix2.parse(f.read())

for obj in bundle.objects:
    print(f"  {obj.type}: {getattr(obj, 'name', obj.id)}")
```

### Step 5: Push to OpenCTI

```python
import requests

OPENCTI_URL = "https://opencti.example.com"
OPENCTI_TOKEN = "your-token"

with open("apt29_bundle.json") as f:
    bundle_data = f.read()

resp = requests.post(
    f"{OPENCTI_URL}/graphql",
    headers={"Authorization": f"Bearer {OPENCTI_TOKEN}", "Content-Type": "application/json"},
    json={"query": "mutation { stixBundleImport(bundle: $bundle) }", "variables": {"bundle": bundle_data}},
)
print(resp.json())
```

## Verification

- [ ] TAXII collection polled successfully with valid STIX objects
- [ ] STIX indicators created with valid patterns and TLP markings
- [ ] STIX bundles validate with `stix2.parse()` without errors
- [ ] Relationships correctly link threat actors to malware/techniques
- [ ] Bundles imported into OpenCTI/MISP with correct entity resolution
- [ ] Feed polling automated on cron schedule

## References

- [STIX 2.1 Specification](https://docs.oasis-open.org/cti/stix/v2.1/stix-v2.1.html)
- [TAXII 2.1 Specification](https://docs.oasis-open.org/cti/taxii/v2.1/taxii-v2.1.html)
- [stix2 Python Library](https://stix2.readthedocs.io/)
- [OpenCTI Documentation](https://docs.opencti.io/)
- [MITRE ATT&CK TAXII](https://attack.mitre.org/resources/working-with-attack/)
