A comprehensive TypeScript library for STIX 2.1 (Structured Threat Information Expression) providing type-safe interfaces and runtime validation for threat intelligence sharing.
- ✅ Complete STIX 2.1 Coverage - All SDOs, SROs, SCOs, and Meta Objects
- 🔒 Type Safety - Full TypeScript type definitions with strict mode
- ✔️ Runtime Validation - Zod schemas for all STIX object types
- 🎯 Spec Compliant - Strictly follows the STIX 2.1 specification
- 🛠️ Utility Functions - Helpers for ID generation, validation, and serialization
- 📦 Zero Dependencies (runtime) - Only Zod as a dependency
- 🧪 Well Tested — 2600+ tests; 100% line, statement, function, and branch coverage on
src/(see Testing)
npm install @octavelaventure/stiximport { IndicatorSchema, generateStixId, getCurrentTimestamp } from 'stix';
// Create a STIX Indicator
const indicator = {
type: 'indicator',
spec_version: '2.1',
id: generateStixId('indicator'),
created: getCurrentTimestamp(),
modified: getCurrentTimestamp(),
name: 'Malicious File Hash',
pattern: '[file:hashes.MD5 = "d41d8cd98f00b204e9800998ecf8427e"]',
pattern_type: 'stix',
pattern_version: '2.1',
valid_from: getCurrentTimestamp(),
indicator_types: ['malicious-activity'],
};
// Validate the indicator
const validated = IndicatorSchema.parse(indicator);
console.log('Valid indicator:', validated.name);import { BundleSchema, createBundle, addToBundle } from 'stix';
// Create a bundle
let bundle = createBundle();
// Add objects to the bundle
bundle = addToBundle(bundle, indicator);
bundle = addToBundle(bundle, malware);
bundle = addToBundle(bundle, relationship);
// Validate the entire bundle
const validatedBundle = BundleSchema.parse(bundle);
console.log(`Bundle contains ${validatedBundle.objects?.length || 0} objects`);import { validateStixObject, formatErrorMessage } from 'stix';
import { z } from 'zod';
const result = validateStixObject(someObject);
if (result.success) {
console.log('Valid STIX object:', result.data.type);
} else {
console.error('Validation failed:', result.message);
}
// Or with direct schema validation
try {
const malware = MalwareSchema.parse(data);
console.log('Valid malware:', malware.name);
} catch (error) {
if (error instanceof z.ZodError) {
console.error(formatErrorMessage(error));
}
}All 18 STIX Domain Objects are fully supported:
attack-pattern- Attack patterns and tacticscampaign- Threat campaignscourse-of-action- Defensive actionsgrouping- Object groupingsidentity- Individuals, organizations, groupsindicator- Indicators of compromiseinfrastructure- Infrastructure used by threat actorsintrusion-set- Intrusion campaignsmalware- Malware instancesmalware-analysis- Malware analysis resultsnote- Annotations and notesobserved-data- Observed cyber dataopinion- Opinions about STIX objectsreport- Threat reportsthreat-actor- Threat actorstool- Tools used by threat actorsvulnerability- Software vulnerabilitieslocation- Geographic locations (STIX 2.1)
relationship- Relationships between objectssighting- Sightings of indicators/observables
All 18 cyber-observable types:
artifact- Binary artifactsautonomous-system- Autonomous systemsdirectory- File directoriesdomain-name- Domain namesemail-addr- Email addressesemail-message- Email messagesfile- Filesipv4-addr- IPv4 addressesipv6-addr- IPv6 addressesmac-addr- MAC addressesmutex- Mutual exclusion objectsnetwork-traffic- Network trafficprocess- System processessoftware- Software applicationsurl- URLsuser-account- User accountswindows-registry-key- Windows registry keysx509-certificate- X.509 certificates
bundle- Collections of STIX objectslanguage-content- Translations and alternate contentmarking-definition- Data marking definitions (TLP, etc.)
import { generateStixId, parseStixId } from 'stix';
// Generate valid STIX IDs
const id = generateStixId('indicator');
// 'indicator--8e2e2d2b-17d4-4cbf-938f-98ee46b3cd3f'
// Parse STIX IDs
const parsed = parseStixId(id);
console.log(parsed?.type); // 'indicator'
console.log(parsed?.uuid); // '8e2e2d2b-17d4-4cbf-938f-98ee46b3cd3f'import {
getCurrentTimestamp,
createTimestampFromMillis,
createTimestampFromISO,
} from 'stix';
const now = getCurrentTimestamp();
// '2024-01-15T10:30:45.123Z'
const fromMillis = createTimestampFromMillis(1704067200000);
// '2024-01-01T00:00:00.000Z'
const fromISO = createTimestampFromISO('2024-01-15');
// '2024-01-15T00:00:00.000Z'import { createStixObjectProperties } from 'stix';
const props = createStixObjectProperties('malware', {
labels: ['trojan'],
confidence: 85,
created_by_ref: 'identity--...',
});
const malware = {
...props,
name: 'TrojanXYZ',
malware_types: ['trojan'],
is_family: false,
};import { validateStixObject, isValidStixId, validateStixObjects } from 'stix';
// Validate single object
const result = validateStixObject(someObject);
if (result.success) {
console.log('Valid!');
}
// Check if string is valid STIX ID
if (isValidStixId('indicator--123')) {
console.log('Valid ID format');
}
// Validate multiple objects
const results = validateStixObjects([obj1, obj2, obj3]);
const allValid = results.every(r => r.success);import { toJSON, fromJSON, prettyPrint, toSortedJSON } from 'stix';
// Serialize to JSON
const json = toJSON(indicator, { indent: 2, sortKeys: true });
// Parse from JSON
const obj = fromJSON(jsonString);
// Pretty print
console.log(prettyPrint(indicator));
// Canonical representation
const canonical = toSortedJSON(indicator);import {
formatValidationError,
formatErrorMessage,
getErrorSummary,
} from 'stix';
import { z } from 'zod';
try {
IndicatorSchema.parse(invalidData);
} catch (error) {
if (error instanceof z.ZodError) {
// Structured format
const formatted = formatValidationError(error);
console.log(formatted.errors);
// Multi-line message
console.error(formatErrorMessage(error));
// One-line summary
console.log(getErrorSummary(error));
}
}import {
generateStixId,
getCurrentTimestamp,
createStixObjectProperties,
createBundle,
addToBundle,
} from 'stix';
// Create an identity (analyst)
const identity = {
...createStixObjectProperties('identity', {
labels: ['organization'],
}),
name: 'ACME Threat Intelligence',
identity_class: 'organization',
};
// Create a threat actor
const threatActor = {
...createStixObjectProperties('threat-actor', {
created_by_ref: identity.id,
labels: ['nation-state'],
}),
name: 'APT-X',
threat_actor_types: ['nation-state'],
sophistication: 'advanced',
resource_level: 'government',
primary_motivation: 'organizational-gain',
};
// Create malware
const malware = {
...createStixObjectProperties('malware', {
created_by_ref: identity.id,
}),
name: 'BadMalware',
malware_types: ['trojan', 'remote-access-trojan'],
is_family: false,
};
// Create relationship
const relationship = {
...createStixObjectProperties('relationship'),
relationship_type: 'uses',
source_ref: threatActor.id,
target_ref: malware.id,
};
// Create indicator
const indicator = {
...createStixObjectProperties('indicator', {
created_by_ref: identity.id,
labels: ['malicious-activity'],
}),
name: 'Malware File Hash',
pattern: '[file:hashes.MD5 = "d41d8cd98f00b204e9800998ecf8427e"]',
pattern_type: 'stix',
pattern_version: '2.1',
valid_from: getCurrentTimestamp(),
indicator_types: ['malicious-activity'],
};
// Bundle everything together
let bundle = createBundle();
bundle = addToBundle(bundle, identity);
bundle = addToBundle(bundle, threatActor);
bundle = addToBundle(bundle, malware);
bundle = addToBundle(bundle, relationship);
bundle = addToBundle(bundle, indicator);
// Validate and export
const validated = BundleSchema.parse(bundle);
console.log(`Created bundle with ${validated.objects?.length} objects`);import {
getBundleById,
filterBundleByType,
getBundleRelationships,
findRelatedObjects,
} from 'stix';
// Get specific object by ID
const indicator = getBundleById(bundle, 'indicator--...');
// Filter by type
const allMalware = filterBundleByType(bundle, 'malware');
const allIndicators = filterBundleByType(bundle, 'indicator');
// Get all relationships
const relationships = getBundleRelationships(bundle);
// Find related objects
const related = findRelatedObjects(bundle, threatActor.id);
console.log(`Found ${related.length} related objects`);The library is built with TypeScript and provides full type safety:
import type {
Indicator,
Malware,
ThreatActor,
Relationship,
Bundle,
StixObject,
} from 'stix';
function processIndicator(indicator: Indicator) {
// TypeScript knows all properties
console.log(indicator.pattern);
console.log(indicator.pattern_type);
console.log(indicator.valid_from);
}
function processBundleObjects(bundle: Bundle) {
bundle.objects?.forEach(obj => {
// obj is typed as StixObject (union of all types)
console.log(obj.type, obj.id);
// Type narrowing
if (obj.type === 'indicator') {
console.log(obj.pattern); // TypeScript knows this is an Indicator
}
});
}- Real-world Use Cases - Start here for runnable code examples
- Generation Utilities - ID generation, timestamps, object creation
- Validation Utilities - Object validation and type guards
- Conversion Utilities - JSON serialization, error formatting
- Quick Reference - Quick lookup for common patterns
- Guides & Examples
- STIX 2.1 Specification - Official specification
- Node.js 18+
- npm or yarn
# Install dependencies
npm install
# Run tests
npm test
# Run tests with UI
npm run test:ui
# Type check
npm run type-check
# Lint
npm run lint
# Format code
npm run format
# Run all checks
npm run checkThe library has comprehensive tests (Vitest, v8 coverage). npm run test:coverage enforces 100% line, statement, function, and branch coverage on src/ (see vitest.config.ts).
npm run test:run # Run all tests once
npm run test:coverage # Run tests with coverage (must meet thresholds)
npm test # Run tests in watch mode
npm run test:ui # Open Vitest UIAfter npm run test:coverage, open coverage/index.html for the HTML report.
This library strictly follows the STIX 2.1 specification published by OASIS. All object types, properties, and validation rules are implemented according to the specification.
Key compliance features:
- ✅ All required properties enforced
- ✅ Optional properties correctly typed
- ✅ Enum values validated
- ✅ Pattern validation for identifiers
- ✅ Timestamp format (RFC 3339) validation
- ✅ Relationship type constraints
- ✅ Object reference validation
See SPEC_COMPLIANCE_VERIFICATION.md for detailed compliance notes.
Contributions are welcome! Please:
- Follow the existing code style
- Write tests for new features
- Update documentation
- Ensure all checks pass (
npm run check)
ISC License
This library is built according to the STIX 2.1 specification maintained by the OASIS Cyber Threat Intelligence (CTI) Technical Committee.