Last updated on Thursday, February 28th, 2019 by Alexander Saint Croix
In this tutorial we are going to discuss methods of modeling cyber threat intelligence using the Cisco Threat Intelligence Model. We will also introduce best practices for client developers using the Cisco Threat Intelligence API (CTIA).
Nothing comes from nothing, and CTIM didn't spring from a vacuum. In order to better understand why CTIM and CTIA are the way they are, it helps to have a little bit of understanding of the business and technological context in which they arose.
First, let us be clear what we mean when we talk about Cyber Threat Intelligence. The Center for Internet Security provides this useful definition:
Cyber threat intelligence is what cyber threat information becomes once it has been collected, evaluated in the context of its source and reliability, and analyzed through rigorous and structured tradecraft techniques by those with substantive expertise and access to all-source information.
There are three processes taking place in sequence here:
It might help to think of each of these processes as part of a data refining pipeline. In the same way that an oil refinery converts crude petroleum into a variety of refined petroleum products, this data refining pipeline gathers raw data (such as information about how computer software behaves in a variety of contexts). It then progressively refines that data by decomposing and structuring it, enriching it by placing it in context with data from other origins, with its own varying levels of refinement. Refining it in this way allows us to isolate the parts of the data that help us make more informed decisions. The end result is what we call actionable intelligence.
So, in order to understand the origins of where the Cisco Threat Intelligence Model comes from, we must consider the technology that immediately preceeded it: Threat Grid.
Without getting lost in the details, Threat Grid is a sandbox designed to safely perform controlled detonation of malware samples. This is how that works, in general:
Each sample can easily yield hundreds of megabytes of observation data. By the end of 2015, Threat Grid was processing upwards of 1,000,000 samples each month, and generating hundreds of terabytes of raw cyber threat intelligence each month.
That's a lot of raw material. Certainly more than can easily be displayed in a web app (but not impossible--Threat Grid does pretty wondrous things with all of its data). However, one of the things that the system could tell us with great confidence is whether or not a given sample was malicious.
And so, for reasons that are logical and entirely forgivable given the options at the time, customers started using Threat Grid as a verdict service. They wanted to know whether their email attachments were safe to open. All of them. This was not an ideal situation, because sandboxes aren't optimized for this use case. They're for performing a deeper inspection on samples.
We were generating and storing an awful lot of data, when most of the time what people really wanted was a simple yes or no.
But we knew they really needed more than that. People would need some context about why we thought a given sample was malicious, and if so, what it meant for their organization. Most importantly, we knew that if evidence of a threat was detected on their network, they probably needed help deciding what to do about it.
And so, at the end of 2015 we started working on a prototype for a fast verdict lookup service. We called it the Cisco Threat Intelligence API (CTIA).
Building on the work of the Open API Initiative, we wanted to build our prototype of CTIA as a robust REST API standard that had executable human-readable and machine-readable documentation, enabling service discovery platforms later on. For this we chose a Swagger 2.0 implementation.
For our early data model, and learning from the complexity of storing Threat Intelligence in Threat Grid, we chose to borrow many concepts from the emerging Structured Threat Intelligence Expressions (STIX™), which defines itself as:
a structured language for describing cyber threat information so it can be shared, stored, and analyzed in a consistent manner.
However, we didn't focus on implementing an exchange for STIX data, such as a TAXII service. STIX is a fine wireline format, but our main emphasis was on rapid storage and retrieval to accelerate analysis and to ease incident response.
And this is a very important distinction between the model that became CTIM, and its roots in STIX. We weren't trying to build an exchange for threat intelligence indicators. Our raw data wasn't so much the patterns we were looking out for, it was actual behavior that we could observe malware engaging in, right in front of us. We have petabytes of such data, it just needed to be refined, but also placed into an actionable context.
And so, development of our REST API began apace.
Once the CTIA prototype was built in the Spring of 2016, and we started showing demonstrations of what we could do with it, we realized that we needed to isolate the model from the API. We could build other tools on top of that model, and the first such tool was our Incident Response Orchestration Hub.
So, we spun off the Cisco Threat Intelligence Model (CTIM) project from CTIA, and over the course of the next several years we continued to build those tools on top of our elegant model and lightning fast API, both of which are Open Source.
In 2018 we released the fruits of that tool development effort to the public. We call it Cisco Threat Response. Today it is used by over 3600 Security Operations Centers around the world.
By December of 2018, we had added support for OAuth2 client credentials, allowing Cisco Threat Response users to start writing their own tools and to curate their own Cyber Threat Intelligence resources. And as we partner with other teams throughout Cisco's burgeoning Security Business Group, and other partners in the Threat Intelligence industry, it has become clear that we needed to start writing better documentation for client developers, and for users looking to model their data in CTIM.
This tutorial is written in the hopes that it will enable developers and threat analysts to more easily model their cyber threat intelligence assets using the Cisco Threat Intelligence Model (CTIM) and Cisco Threat Intelligence API (CTIA).
This tutorial is nowhere near exhaustive. I gloss over the history of this project, and do not cover the entire CTIM entity model. Instead, this guide focuses on the most common entity types encountered by threat analysts and tool developers.
By the time you finish this tutorial, you should have learned the following:
This section contains documentation and best practices for defining cyber threat observables, as well as the most common entity types:
In addition to having a common core set of fields built from a base entity definition, all entities in CTIM are sourceable
, and describable
, as defined in our common schema
All CTIM entities are derived from the base entity.
External IDs (XIDs) are extremely valuable tools in your toolkit when encoding threat intelligence data in CTIM. If you are careful and consistent about how you generate your external IDs, you can reap many benefits including faster searches, and even avoid creating duplicate entities.
To this end, we recommend the following best practices:
The structure of our recommended external ID string will look like this:
<prefix>-<entity-type>-<sha256-hash>
<prefix>
part helps reduce (and, if I choose a suitable prefix string, even eliminate) the chance that I'll have a collision with another namespace. Prefix strings are extremely useful when creating bundles, in order to help us prevent the creation of duplicate entities, as we'll learn later.<entity-type>
part is there for my convenience, to help me reason about relationship
entities, as we will also learn later.<sha256-hash>
part is generated from some deterministic collection of strings. Because it is a SHA256 digest, it's exceptionally unlikely that we will accidentally collide with another external ID string. The important thing to note here, is that the hash is deterministic. It is not a hash of a random number, or a hash of the timestamp from when we ran the importer, but something that we can recreate at any time, so long as we know the inputs. For example:$ echo "CTIM Modeling Tutorial|example-indicator-title|2019-02-28" | sha256sum
1df6883f3a46c66165bc910d6ca0d46234f0fe616a0c3d617e3e4e9caacc3878
If we pick a good descriptive prefix string ctim-tutorial
, we can put all three of these parts together to build the final external ID string for this entity:
"ctim-tutorial-indicator-1df6883f3a46c66165bc910d6ca0d46234f0fe616a0c3d617e3e4e9caacc3878"
Note: Translating this process to the language of your choice is left as an exercise to the reader.
All of the entities that we cover in this tutorial have the property of being sourceable. What this means, essentially, is that we may specify where the intelligence in the entity comes from. All of the fields for sourceable entities are optional, and they include the following:
Naturally, if we don't know where intel comes from, we are less likely to trust it. Even though it is an optional field in the schema, all client developers should mark their intel with source
and source_uri
fields, whenever it is appropriate.
The source
and source_uri
fields do not describe the source of the CTIM entity, but the source of the cyber threat intelligence captured within that entity. So, for example, if someone in the Cisco Threat Response team is packaging up data from the National Vulnerability Database, we would list the source
as the "National Vulnerability Database", and the source_uri
as "https://nvd.nist.gov".
The source
field can be a very useful field when searching through your stored intelligence, and can dramatically speed up CTIA queries for your data later on. It is a very useful and important field, and all client developers are strongly encouraged to use it consistently.
All of the entities that we cover in this tutorial have the property of being describable. What this means, essentially, is that we can provide additional descriptive text for them. All describable entity fields are optional, and they include the following:
In CTIM, an Observable is a recognizable token which we can use as the basis of our investigation. Observables include things like domain names, IP addresses, file hashes, URLs and other values of similar nature.
Observables are not top level entities in CTIM. They are inline data types, included as part of both Sighting and Judgement entities, which we will learn about later.
Observables must have both of the following fields:
ip
, domain
, md5
, sha256
, url
). The definitive set of observable type identifiers that are supported in CTIM is available at https://github.com/threatgrid/ctim/blob/master/src/ctim/schemas/vocabularies.cljc.Not all information that can be observed in a system is necessarily a good candidate for an observable record. Ideally, observables are only created when they have direct bearing on a cyber threat incident. Tokens that we can observe but which we have no reason to believe are relevant to new or ongoing cyber threats do not, therefore, need to be captured as observables in CTIM.
Example: We can observe that a user's keyboard is beige, but we don't record an observable about that fact, because keyboard color is not relevant to any known threat. However, if we notice that their system is trying to contact a known malware command and control domain, we would definitely record that fact. This seems like a trivial and obvious distinction to point out, but we will use it later to help guide our thinking when we create
Sighting
andJudgement
entities.
{"type": "domain",
"value": "google.com"}
An Indicator is a test, or a collection of criteria for identifying the activity, or presence of a cyber threat. Those threats could be malware, patterns of activity that might precede an attack or indicate an attack in progress, or the presence of tools and other infrastructure for the same.
"indicator"
."2525-01-01:00:00:00.000Z"
. See below for examples.source
of the threat intelligence.These are the most important of the many optional fields. A full list of optional fields can be found in the Indicator Schema.
["Info", "Low", "Medium", "High", "None", "Unknown"]
.["Info", "Low", "Medium", "High", "None", "Unknown"]
.Broadly speaking, indicators come in two types:
{
"type": "indicator",
"source": "Modeling Threat Intelligence in CTIM Tutorial",
"source_uri": "https://github.com/threatgrid/ctim/blob/master/src/doc/tutorials/modeling-threat-intel-ctim.md",
"title": "Example Indicator Title",
"short_description": "Example indicator entity, provided for purposes of illustrating the correct construction of indicators in a CTIM tutorial.",
"valid_time": {
"start_time": "2019-02-28T00:00:00.000Z",
"end_time": "2525-01-01T00:00:00.000Z"
},
"confidence": "None",
"severity": "None",
"tags": ["example"],
"tlp": "white",
"producer": "Cisco Systems",
"external_ids": [
"ctim-tutorial-indicator-5206f31d14f7b1965dc97c1ec8febfbe45439e8872ff19782f6ac7c49a0ffc68"
],
"id": "transient:ctim-tutorial-indicator-5206f31d14f7b1965dc97c1ec8febfbe45439e8872ff19782f6ac7c49a0ffc68"
}
A judgement about the intent or nature of an observable. For example, is it malicious, meaning it is malware and subverts system operations? It could also be clean and be from a known benign, or trusted source. It could also be common, something so widespread that it's not likely to be malicious.
Since a core goal of the CTIA is to provide a simple verdict service, these judgements are the basis for the returned verdicts. These are also the primary means by which users of the CTIA go from observables on their system, to the indicators and threat intelligence data in CTIA.
Judgement entities are distinct from many others in that they do not inherit from describable
, but from described
. This means that Judgement entities are required to have source
and source_uri
fields..
Judgements do not inherit describable
, so do not have titles, long descriptions, or short descriptions.
["Info", "Low", "Medium", "High", "None", "Unknown"]
["Info", "Low", "Medium", "High", "None", "Unknown"]
"2525-01-01:00:00:00.000Z"
. Judgement valid times should be appropriate for the volatility of the observable. For example, domains and IP addresses can change hands very quickly and cease being malicious, so a valid_time
of 30 days is probably warranted for them. However, sha256 hashes for a malicious executable are going to be malicious essentially forever, so we would set the end_time
to "2525-01-01:00:00:00.000Z"
.Judgements allow us to apply a disposition to an observable, and to provide a little bit of metadata about how certain we are in that assessment. Valid disposition numbers and names are defined in the CTIM schema, but are summarized here:
{1 "Clean"
2 "Malicious"
3 "Suspicious"
4 "Common"
5 "Unknown"}
One of the services that CTIA provides is the ability to compare multiple judgements for a given observable and very quickly render a verdict based on them.
The rules for exactly how this is performed are a bit complex, but here are some basics to know:
Clean > Malicious > Suspicious > Unknown
, so a false positive can always be overruled by explicitly creating a judgement with a Clean
disposition.A Verdict indicates the most recent and most relevant disposition for a given cyber observable, as well as the Judgement from which the verdict was derived.
{
"type" : "judgement",
"source": "Modeling Threat Intelligence in CTIM Tutorial",
"source_uri": "https://github.com/threatgrid/ctim/blob/master/src/doc/tutorials/modeling-threat-intel-ctim.md",
"valid_time" : {
"start_time" : "2019-03-01T19:22:45.531Z",
"end_time" : "2019-03-31T19:22:45.531Z"
},
"observable" : {
"type" : "ip",
"value" : "187.75.16.75"
},
"external_ids" : [ "ctim-tutorial-judgement-4340e8cc49ff428e21ad1467de4b40246eb0e3b8da96caa2f71f9fe54123d498" ],
"disposition" : 2,
"disposition_name" : "Malicious",
"priority" : 95,
"id" : "transient:ctim-tutorial-judgement-4340e8cc49ff428e21ad1467de4b40246eb0e3b8da96caa2f71f9fe54123d498",
"severity" : "High",
"tlp" : "green",
"timestamp" : "2019-03-01T19:22:45.531Z",
"confidence" : "High"
}
A Sighting is a record of the appearance of a cyber threat Indicator match at a given date and time. This can be a pattern match in a rule matching engine or expert system, or an observable feed based indicator such as an IP or domain blacklist.
Sightings can optionally include cyber threat observables, such as domain names, URLs, IP addresses, file hashes, registry keys, and more. When a sighting includes an observable and has a relationship to an Indicator, it provides threat intelligence context about the observable, allowing a threat analyst or incident responder to understand why the observable warranted the creation of a Sighting.
["Info", "Low", "Medium", "High", "None", "Unknown"]
["Info", "Low", "Medium", "High", "None", "Unknown"]
["detected" "blocked" "allowed" "contained"]
Target entries are structured as follows:
{"type": "network.firewall",
"observables": [{"type": "ip", "value": "187.75.16.75"}],
"observed_time": {"start_time" : "2019-03-01T20:01:27.368Z"}}
Earlier we discussed that not everything we are able to observe merits being turned into an observable. For sightings, this is made even more explicit by the inclusion of the relations
field, which allows us to provide additional context about the observable that is the object of the sighting.
For example, imagine if we have a known malicious domain baddomain.com
. At the time that we saw the domain being contacted (triggering the creation of a Sighting), we might know that the domain resolved to the IPv4 address 8.8.8.8
. We know from months of tracking this malicious domain that it is bad news. However, we would not create a 2nd Judgement on the associated IPv4 address. This is because the IP isn't the actual observable that triggered our malicious judgement. It's useful context, but it isn't actually a malicious IP address. (It's actually the IP address of Google's DNS servers).
Instead, the fact that this domain resolved to this IP address at the time of the sighting should be captured in the relations
key of the Sighting.
{
"origin": "Modeling Threat Intelligence in CTIM Tutorial",
"origin_uri": "https://github.com/threatgrid/ctim/blob/master/src/doc/tutorials/modeling-threat-intel-ctim.md",
"source": {"type":"domain", "value": "baddomain.com"},
"target": {"type":"ip", "value": "8.8.8.8"},
"relation": "Resolved_To"
}
{
"type" : "sighting",
"source": "Modeling Threat Intelligence in CTIM Tutorial",
"source_uri": "https://github.com/threatgrid/ctim/blob/master/src/doc/tutorials/modeling-threat-intel-ctim.md",
"observables" : [ {
"type" : "ip",
"value" : "187.75.16.75"
} ],
"external_ids" : [ "ctim-tutorial-sighting-7b36e0fa2169a3ca330c7790f63c97fd3c9f482f88ee1b350511d8a51fcecc8d" ],
"id" : "transient:ctim-tutorial-sighting-7b36e0fa2169a3ca330c7790f63c97fd3c9f482f88ee1b350511d8a51fcecc8d",
"count" : 1,
"severity" : "High",
"tlp" : "green",
"timestamp" : "2019-03-01T20:01:27.368Z",
"confidence" : "High",
"observed_time" : {
"start_time" : "2019-03-01T20:01:27.368Z"
}
}
Ultimately, CTIM allows us to model our threat intelligence as a hypertext graph. In this graph, each entity is a node with its own URI, and the nodes of this graph are connected via Relationships, which form its edges.
In addition to being derived from the base
, sourceable
, and describable
entity definitions defined above, relationships require the following fields:
The polarity of relationships describes the direction that the arrow points on a directed graph: Relationships always point FROM the source_ref
, and TOWARD the target_ref
in the relationship.
Therefore, there are some relation_type
fields which are expected to be used in certain scenarios. In our Common Relation Types document, we define, for example, that a judgement would be "based on" an indicator, but not vice versa. Relationships from Indicators do not point toward Judgements. So, to represent this relationship, we'd have the Judgement entity identified as the source_ref
, and the indicator entity identified as the target_ref
. These fields are not interchangeable, and the polarity of the relationship does matter. Please read through the documentation on common relation types for more information.
{
"type" : "relationship",
"source": "Modeling Threat Intelligence in CTIM Tutorial",
"source_uri": "",
"source_ref" : "transient:ctim-tutorial-judgement-4340e8cc49ff428e21ad1467de4b40246eb0e3b8da96caa2f71f9fe54123d498",
"target_ref" : "transient:ctim-tutorial-indicator-c56de1c94c1ce862c4e6d9883393aacc58275c0c4dc4d8b48cc4db692bf11e4f",
"relationship_type" : "based-on",
"external_ids" : [ "ctim-tutorial-relationship-2c1f3fcaf89d294bf7d038f470f6cb4a81dc1fad6ff5deeed18a41bf6fe14e4d" ]
}
Note: At this point you may be wondering what all of these "transient:..."
ids are all about. We'll dig into those details in the next section.
In order to really understand bundles, we need to take a step back and take another look at Relationships.
Up until this point we have intentionally glossed over an important detail in the creation of relationships: how do we create them if we don't have the URLs for the entities we want to relate?
If a Relationship entity requires 2 IDs, and if IDs in CTIA are always URIs, then we need the URI for the source_ref
, and the URI for the target_ref
before we can specify a Relationship. As you might imagine, this can become burdensome.
This is how we used to assemble relationships, before bundles:
GET
request) or create and POST
the source entity in order to get its URI for the source_ref
(1-2 HTTP requests)GET
request) or create and POST
the target entity in order to get its URI for the target_ref
(1-2 HTTP requests)POST
a Relationship entity (1 HTTP request).It used to require 3-5 HTTP requests for every relationship. If you knew that both the source and target entities were brand new, you could get the job done with only 3 POST
requests. However, even with persistent sessions, this was never going to scale to our needs.
And so, we added the bundle import API mechanism to CTIA. The purpose of the bundle import mechanism is twofold:
id
field, but are identical in every other way.[ ] The new way: Using transient IDs
In addition to the required "type":"bundle"
field and the strongly recommended source
and source_uri
fields, bundles can contain lists of various CTIM entity types. Most of them are outside the scope of this tutorial, but they are all defined in great depth in the CTIM Bundle schema.
At long last, we have our example bundle:
{
"type" : "bundle",
"source" : "Modeling Threat Intelligence in CTIM Tutorial",
"source_uri" : "https://github.com/threatgrid/ctim/blob/master/src/doc/tutorials/modeling-threat-intel-ctim.md",
"sightings" : [ {
"observables" : [ {
"type" : "ip",
"value" : "187.75.16.75"
} ],
"type" : "sighting",
"source" : "Modeling Threat Intelligence in CTIM Tutorial",
"external_ids" : [ "ctim-tutorial-sighting-7b36e0fa2169a3ca330c7790f63c97fd3c9f482f88ee1b350511d8a51fcecc8d" ],
"source_uri" : "https://github.com/threatgrid/ctim/blob/master/src/doc/tutorials/modeling-threat-intel-ctim.md",
"id" : "transient:ctim-tutorial-sighting-7b36e0fa2169a3ca330c7790f63c97fd3c9f482f88ee1b350511d8a51fcecc8d",
"count" : 1,
"severity" : "High",
"tlp" : "green",
"timestamp" : "2019-03-01T22:26:29.229Z",
"confidence" : "High",
"observed_time" : {
"start_time" : "2019-03-01T22:26:29.229Z"
}
} ],
"judgements" : [ {
"valid_time" : {
"start_time" : "2019-03-01T22:26:29.229Z",
"end_time" : "2019-03-31T22:26:29.229Z"
},
"observable" : {
"type" : "ip",
"value" : "187.75.16.75"
},
"type" : "judgement",
"source" : "Modeling Threat Intelligence in CTIM Tutorial",
"external_ids" : [ "ctim-tutorial-judgement-4340e8cc49ff428e21ad1467de4b40246eb0e3b8da96caa2f71f9fe54123d498" ],
"disposition" : 2,
"source_uri" : "https://github.com/threatgrid/ctim/blob/master/src/doc/tutorials/modeling-threat-intel-ctim.md",
"disposition_name" : "Malicious",
"priority" : 95,
"id" : "transient:ctim-tutorial-judgement-4340e8cc49ff428e21ad1467de4b40246eb0e3b8da96caa2f71f9fe54123d498",
"severity" : "High",
"tlp" : "green",
"timestamp" : "2019-03-01T22:26:29.229Z",
"confidence" : "High"
} ],
"indicators" : [ {
"description" : "The IP Blacklist is automatically updated every 15 minutes and contains a list of known malicious network threats that are flagged on all Cisco Security Products. This list is estimated to be 1% of the total Talos IP Reputation System.",
"valid_time" : {
"start_time" : "2019-03-01T22:26:29.229Z",
"end_time" : "2525-01-01T00:00:00.000Z"
},
"producer" : "Cisco TALOS",
"type" : "indicator",
"source" : "Modeling Threat Intelligence in CTIM Tutorial",
"external_ids" : [ "ctim-tutorial-indicator-c56de1c94c1ce862c4e6d9883393aacc58275c0c4dc4d8b48cc4db692bf11e4f" ],
"short_description" : "The TALOS IP Blacklist lists all known malicious IPs in the TALOS IP Reputation System.",
"title" : "TALOS IP Blacklist Feed",
"source_uri" : "https://github.com/threatgrid/ctim/blob/master/src/doc/tutorials/modeling-threat-intel-ctim.md",
"id" : "transient:ctim-tutorial-indicator-c56de1c94c1ce862c4e6d9883393aacc58275c0c4dc4d8b48cc4db692bf11e4f",
"tlp" : "green"
} ],
"relationships" : [ {
"type" : "relationship",
"source" : "Modeling Threat Intelligence in CTIM Tutorial",
"source_uri" : "https://github.com/threatgrid/ctim/blob/master/src/doc/tutorials/modeling-threat-intel-ctim.md",
"source_ref" : "transient:ctim-tutorial-judgement-4340e8cc49ff428e21ad1467de4b40246eb0e3b8da96caa2f71f9fe54123d498",
"target_ref" : "transient:ctim-tutorial-indicator-c56de1c94c1ce862c4e6d9883393aacc58275c0c4dc4d8b48cc4db692bf11e4f",
"relationship_type" : "based-on",
"external_ids" : [ "ctim-tutorial-2c1f3fcaf89d294bf7d038f470f6cb4a81dc1fad6ff5deeed18a41bf6fe14e4d" ],
"short_description" : "judgement ctim-tutorial-judgement-4340e8cc49ff428e21ad1467de4b40246eb0e3b8da96caa2f71f9fe54123d498 is based-on indicator ctim-tutorial-indicator-c56de1c94c1ce862c4e6d9883393aacc58275c0c4dc4d8b48cc4db692bf11e4f"
}, {
"type" : "relationship",
"source" : "Modeling Threat Intelligence in CTIM Tutorial",
"source_uri" : "https://github.com/threatgrid/ctim/blob/master/src/doc/tutorials/modeling-threat-intel-ctim.md",
"source_ref" : "transient:ctim-tutorial-sighting-7b36e0fa2169a3ca330c7790f63c97fd3c9f482f88ee1b350511d8a51fcecc8d",
"target_ref" : "transient:ctim-tutorial-indicator-c56de1c94c1ce862c4e6d9883393aacc58275c0c4dc4d8b48cc4db692bf11e4f",
"relationship_type" : "sighting-of",
"external_ids" : [ "ctim-tutorial-0664295d5da504180b4f232a0d5e95908fcbd6eb052b6e97f294ddfb6a7b11b8" ],
"short_description" : "sighting ctim-tutorial-sighting-7b36e0fa2169a3ca330c7790f63c97fd3c9f482f88ee1b350511d8a51fcecc8d is sighting-of indicator ctim-tutorial-indicator-c56de1c94c1ce862c4e6d9883393aacc58275c0c4dc4d8b48cc4db692bf11e4f"
} ]
}
As described above, we supply the external ID prefix to CTIA via the external-key-prefixes
query parameter. So, in order to POST
our bundle to CTIA, you'd run the following command:
curl -X POST --header 'Content-Type: application/json' --header 'Accept: application/json' --header 'Authorization: <your auth>' -d '{"type":"bundle", \
"source": "Modeling Threat Intelligence in CTIM Tutorial", \
... }' 'https://localhost:3000/ctia/bundle/import?external-key-prefixes=ctim-tutorial-'
When the bundle is posted, CTIA will perform the following:
ctim-tutorial-
prefix.external_ids
to the ones supplied in the bundle are found in storage, then all relationship references to that entity in the bundle will be replaced with references to the URI for the existing entity in storage. Duplicate entities with the same "ctim-tutorial-"
external IDs will not be created."ctim-tutorial-"
external IDs is found in storage, CTIA will create a new entity and replace the transient ID reference in any relationships with the URI for the newly created entity.POST
the relationship entities to storage using its bulk
route.Can you improve this documentation? These fine people already did:
Alexander R. Saint Croix & Michael PendergrassEdit on GitHub
cljdoc is a website building & hosting documentation for Clojure/Script libraries
× close