workingDog/SwiftSTIX

GitHub: workingDog/SwiftSTIX

Stars: 0 | Forks: 0

# SwiftSTIX `SwiftSTIX` is a Swift package for working with STIX 2.1 objects and TAXII 2.1 feeds. It is designed for: - decoding and encoding STIX 2.1 JSON in native Swift types - consuming TAXII 2.1 collections from Swift apps and services - testing TAXII clients against real-world feeds such as Pulsedive The package ships as a single module, `STIX2`. An experiment to use **Codex AI** to generate the code, then some polishing. ## STIX and TAXII [[1]](https://oasis-open.github.io/cti-documentation/) "Structured Threat Information Expression [STIX™] is a language and serialization format used to exchange [cyber threat intelligence (CTI)](https://www.oasis-open.org/committees/tc_home.php?wg_abbrev=cti). STIX enables organizations to share CTI with one another in a consistent and machine readable manner, allowing security communities to better understand what computer-based attacks they are most likely to see and to anticipate and/or respond to those attacks faster and more effectively. STIX is designed to improve many different capabilities, such as collaborative threat analysis, automated threat exchange, automated detection and response, and more." ## Features - Swift 6 package with `Codable` STIX 2.1 models - Polymorphic decoding through `STIXObject` and `STIXObservable` - Support for custom STIX objects and custom observables - STIX-friendly JSON date handling through `STIXJSON` - Lightweight TAXII 2.1 client for discovery, collections, and object retrieval - Tolerant TAXII envelope decoding for servers that return `next` as either a string or an integer ## Status Minimal testing as yet. This package should be usable for STIX 2.1 decoding and TAXII 2.1 client integration, but it is still early-stage: - focus is currently on STIX 2.1 - schema-backed models are present for standard SDO, SRO, and SCO types - TAXII support is read-oriented and currently covers discovery, collections, and objects endpoints ## Installation ### Swift Package Manager dependencies: [ .package(url: "https://github.com/workingDog/SwiftSTIX.git", branch: "main") ] Then add the product: targets: [ .target( name: "YourTarget", dependencies: [ .product(name: "SwiftSTIX", package: "SwiftSTIX") ] ) ] You can also import the product as `STIX2` if you prefer that product name. ## Quick Start ### Decode a STIX bundle import Foundation import STIX2 let data: Data = ... let decoder = STIXJSON.makeDecoder() let bundle = try decoder.decode(Bundle.self, from: data) for obj in bundle.objects ?? [] { switch obj.object { case .indicator(let indicator): print("Indicator:", indicator.name ?? "") case .relationship(let relationship): print("Relationship:", relationship.relationshipType) default: break } } ### Decode a TAXII envelope import Foundation import STIX2 let data: Data = ... let envelope = try STIXJSON.makeDecoder().decode(TAXIIEnvelope.self, from: data) print("More pages:", envelope.more ?? false) print("Objects:", envelope.objects.count) print("Next cursor:", envelope.next ?? "") ### Read from Pulsedive's test collection Pulsedive currently provides a free test collection that is useful for client integration work. import STIX2 let client = TAXIIClient(configuration: .pulsediveTest(apiKey: "")) let envelope = try await client.objects( collectionID: TAXIIClientConfiguration.pulsediveTestCollectionID, query: TAXIIObjectQuery(limit: 10, matchType: "indicator") ) for obj in envelope.objects { if case let .indicator(indicator) = obj.object { print(indicator.name ?? "") } } ## Public API Highlights - `Bundle` - `STIXObject` - `STIXObservable` - `STIXValue` - `STIXJSON` - `TAXIIClient` - `TAXIIClientConfiguration` - `TAXIIEnvelope` - `TAXIIObjectQuery` ## Package Layout - [`Sources/STIX2/Models/STIXModels.swift`](Sources/STIX2/Models/STIXModels.swift) Core STIX 2.1 model types - [`Sources/STIX2/Support/STIXCore.swift`](Sources/STIX2/Support/STIXCore.swift) Shared primitives, dynamic values, and JSON helpers - [`Sources/STIX2/Support/TAXIIClient.swift`](Sources/STIX2/Support/TAXIIClient.swift) TAXII 2.1 client support - [`Tests/STIX2Tests/STIX2Tests.swift`](Tests/STIX2Tests/STIX2Tests.swift) Decoding and request-construction coverage ## References The model layer was originally derived from: - [`oasis-open/cti-python-stix2`](https://github.com/oasis-open/cti-python-stix2) - [`oasis-open/cti-stix2-json-schemas`](https://github.com/oasis-open/cti-stix2-json-schemas) - [STIX 2.0 Specifications](https://oasis-open.github.io/cti-documentation/) - [TAXII 2.1 Specification](https://oasis-open.github.io/cti-documentation/) ## Development Run tests with: swift test ## Notes - The TAXII 2.1 specification defines the envelope `next` field as a string. This package accepts either `String` or `Int` on decode because some real-world servers return numeric cursors. - This package aims to be practical for interop work first, while still tracking the standards closely.