Posted by:

David Greenwood

David Greenwood, Chief of Signal

If you are reading this blog post via a 3rd party source it is very likely that many parts of it will not render correctly. Please view the post on for the full interactive viewing experience.

In this post I will show you how to package your STIX Objects so that they can be shared with others and integrated with other software.

Note: this post is written for OASIS STIX version 2.1. The concepts discussed are not always correct for earlier versions of OASIS STIX.

The reason more-and-more companies are standardising their intelligence work on STIX 2.1 is partly due to its broad specification as covered in previous posts. In turn, other organisations and tools are now standardising on STIX 2.1.

Before you package your content into a STIX Bundle (more on that to follow), there are a few best practices I would like to share.

Data Marking Objects

Sharing of intelligence organisations is becoming increasingly important. Protocols (like TLP) are common place in defining who data can be shared with and how.

In STIX 2.1, Data Marking ("type": "marking-definition") STIX Meta Objects (SMOs) provide these designations.

Data Marking can be used in any STIX Object type including most commonly with SDOs, SCOs, and SROs.

Two marking definition types are defined in the STIX 2.1 specification:

  1. TLP, to capture TLP markings, and,
  2. Statement, to capture text marking statements.

Here is an example of me declaring a copyright "definition_type": "statement" for an Indicator Object;

As you will see in the json representation, inside the Indicator SDOs object_marking_refs Property I link it to the marking-definition-- SMO .

A TLP marking type can be achieved in much the same way, however this time the definition_type is tlp not statement.

Here is an example of both a Statement and TLP definition_type linked from an Indicator SDO.

It is very important to point out, TLP marking-definition--s must use the 4 TLP SMOs exactly as define in the specification, including IDs;

STIX SMO TLP specification

Data Markings can cover an entire STIX SRO, SDO, or SCO (as Object Markings) shown in the previous two examples. They can also be written to cover just part of the Object (as Granular Markings).

The actual structure of the marking-definition Object defining the type (TLP or Statement) remains unchanged.

However, the change happens inside the Object I want to apply the granular marking to. Instead of using the object_marking_refs Property, I instead use the property granular_markings.

Inside the granular_markings Property I then define the marking_ref, which points to the marking-definition Object defining the marking, and a list of values under the selectors Property. The selectors Property is a list of fields (and specific field values in the case of lists), the marking-definition should apply to;

"granular_markings": [
      "marking_ref": "marking-definition--5e57c739-391a-4eb3-b6be-7d15ca92d5ed",
      "selectors": [
      "marking_ref": "marking-definition--f88d31f6-486f-44da-b317-01333bde0b82",
      "selectors": [
      "marking_ref": "marking-definition--34098fce-860f-48ae-8e50-ebd3cc5e41da",
      "selectors": [

Lets imagine an example where you might want to do this. My scenario focuses on a STIX producer, “Signals Corps Bank” who imposes granular markings on an Indicator object.

Before sharing the Indicator SDO, Signals Corps Bank selects a few TLP marking definitions to apply to the Properties inside the Indicator SDO.

Three marking-definition Objects help restrict the usage of certain properties of the Indicator SDO based on its TLP marking type as follows;

  • marking-definition--5e57c739-391a-4eb3-b6be-7d15ca92d5ed
    • applies to the Indicator SDOs description fields
    • TLP for this marking-definition is Red
  • marking-definition--f88d31f6-486f-44da-b317-01333bde0b82
    • applies to the Indicator SDOs indicator_types.[1] field. Note, 1 denotes the second item in the indicator_types list (in this case attribution) – it is a zero-based list index
    • TLP for this marking-definition is Amber
  • marking-definition--34098fce-860f-48ae-8e50-ebd3cc5e41da
    • applies to the Indicator SDOs indicator_types.[0], name, and pattern fields
    • TLP for this marking-definition is Green

You will also note that the Threat Actor uses the same marking-definition (marking-definition--5e57c739-391a-4eb3-b6be-7d15ca92d5ed = TLP Red) as the Indicator Property uses for Granular Marking of the description field, however, the Threat Actor Object is using it globally to define the TLP level for the entire Object (all its properties).

Creating an Identity SDO

If you are creating content, you should usually attribute it to yourself (unless you wish to remain anonymous) using an Identity SDO using the global shared Property created_by_ref. You can create your Identity SDO once, and reuse it for all future attribution.

Do not forget to use SROs and/or Object Property values to attribute the Object to you via the Identity SDO.

Here is an example for the organisation, Signals Corps;

Note: if creating an identity for yourself you should not include a circular reference to the same Identity Object in the created_by_ref field. That is id Property = created_by_ref Property.

STIX Bundles

Throughout this series of posts I’ve been creating STIX Bundles to model the STIX Objects created on the graph.

A STIX Bundle is a .json document that provides a wrapper mechanism for packaging a complete set of STIX content together.

The Properties of a STIX Bundle are simple. A Bundle has the Properties; type, id, and a list of STIX objects it contains (SDOs, SCOs, SROs, SMOs, etc.)

To see the structure of a STIX Bundle, click “Download STIX 2.1 Bundle” in one of the graphs above.

The amount of data packed into a Bundle depends on a consumer.

Sometimes, in the case of report writing, it makes sense to package all the Objects into a single STIX Bundle to share (very similar to the Mandiant and FireEye reports shared in the first post).

If you are simply sharing bundles via GitHub, or though viewers (like I use), then it usually makes more sense to bundle all Objects into a single static bundle so external lookups do not need to be made.

In other cases, for example continual data sharing between consumer and producer, it makes more sense to ship Bundles with only new and updated Objects which can be cross-referenced and viewed alongside previously ingested Bundles.

How you deal with this depends largely on your consumers and how you give them access to your data, though in most intelligence sharing use-cases Bundles are usually generated with new content only.

Automating STIX 2.1 Content Creation

After reading the content over the last two months it is likely you want to start modelling some intelligence in STIX 2.1 and Bundle it up to share, if you have not already.

Luckily OASIS have built cti-python-stix2, a set of Python APIs that allow you to quickly start creating STIX 2.1 content.

In the final part of this series I will jump into how I used it to create the examples in these posts, and how to take them even further.

STIX 2.1 Certification (Virtual and In Person)

The content used in this post is a small subset of our full training material used in our STIX 2.1 training.

If you want to join a select group of certified STIX 2.1 professionals, subscribe to our newsletter below to be notified of new course dates.

Discuss this post

Signals Corps Slack

Never miss an update

Sign up to receive new articles in your inbox as they published.