Full threatcl Spec
The following is the full specification. This can be generated using the following command:
threatcl generate boilerplate// To cater for multiple spec versions we specify this in our HCL filesspec_version = "0.2.3"
// You can include variables outside your threatmodel blocks
variable "variable_name" { value = "Variable text here"}
// To use this, simply swap in a text attribute for var.variable_name
// There may be multiple threatmodel blocks in a single file, but their names must be unique
threatmodel "threatmodel name" { // the author attribute is required author = "@xntrik"
// the including attribute is optional // you can inherit all the information from another threat model // // the included file must include only a single threatmodel block // // any duplicate fields will be overwritten by this threatmodel // // You can leverage go-getter's format for downloading too, this means that // you can refer to remote URLs, or Git Repos etc // See https://github.com/hashicorp/go-getter for examples // // There are some issues to select an individual file from a Git repo, as the // entire repo is downloaded by default. To use an individual file, you can // github.com/threatcl/threatcl|examples/aws-security-checklist.hcl // with the | being a separator between the git repo and the file to use // after cloning.
including = "shared/city-threatmodel.hcl"
// The description is optional description = "A description of the system being assessed"
// The link is optional link = "https://link/to/docs"
// The diagram_link is optional // If it ends in .jpg or .png then it'll be embedded in the resultant dashboard
// If a diagram_link isn't set, but the threatmodel includes a // data_flow_diagram, this will be automatically generated and included // when running threatcl dashboard
diagram_link = "https://link/to/diagram"
// created_at and updated_at are optional integer, UNIX time stamps created_at = 1594033151 updated_at = 1594033160
// the attributes block is optional, but recommended
attributes { new_initiative = "true" // boolean internet_facing = "true" // boolean
// initiative_size must be one of 'Undefined, Small, Medium, Large' initiative_size = "Undefined" }
// you can set mutiple additional attribute key/value blocks as well
additional_attribute "network_segment" { value = "DMZ" }
// Each threatmodel may contain a number of information_assets // the names must be unique per threatmodel though
information_asset "cred store" { // The description is optional description = "This is where creds are stored"
// information_classification must be one of 'Restricted, Confidential, Public' information_classification = "Confidential"
// source is optional, and can be used to specify if this asset was sourced // from an external resource, such as terraform source = "terraform" }
information_asset "special sauce" { // Here is how you can refer to your variables set above description = var.variable_name information_classification = "Confidential" }
// Each threatmodel may contain a number of usecases
usecase { // The description is required // Similar to threats, the description may also use multiline entries too description = "Users access data from the system" }
// Each threatmodel may contain a number of exclusions
exclusion { // The description is required // Similar to threats, the description may also use multiline entries too description = "Crypto operations are offloaded to a KMS" }
// Each threatmodel may contain a number of third party dependencies
third_party_dependency "dependency name" { // The description is required, and may use multiline entries description = "What the dependency is used for"
// The following boolean attributes are optional and will default to false if unset saas = "true" paying_customer = "true" open_source = "false" infrastructure = "false"
// The uptime dependency is required, and must be one of "none", "degraded", "hard", "operational" // This specifies the impact to our system if the dependency is unavailable uptime_dependency = "none"
// Uptime notes are optional uptime_notes = "If this dependency goes down users can't login" }
// Each threatmodel may contain a number of threats, these must be uniquely named
threat "threat name" { // The description is required description = "System is compromised by hackers"
// The impact is an optional array of potential impact values // The available values are 'Confidentiality, Integrity, Availability' impacts = ["Confidentiality", "Integrity", "Availability"]
// A threat may contain multiple control blocks
control "control name" { description = "The control must have a description"
// implemented is optional, but defaults to false implemented = true
// implementation_notes are optional implementation_notes = "This string is optional"
// risk_reduction, while optional, is recommended // this value takes an integer risk_reduction = 50
// a control may contain optional attribute blocks attribute "Attribute Name" { value = "This value string must be set though for each attribute" }
// a good use for these may be to refer to OWASP URLs attribute "OWASP Proactive Control" { value = "<link to control>" } }
// The stride is an optional array of STRIDE elements that apply to this threat // The available values are: // Spoofing // Tampering // Repudiation // Info Disclosure // Denial Of Service // Elevation Of Privilege stride = ["Spoofing", "Tampering", "Repudiation", "Info Disclosure", "Denial Of Service", "Elevation Of Privilege"]
// The information_asset_refs are an optional array of information_assets // the elements must much existing information_assets - as above information_asset_refs = ["cred store"] } // End of threat block
// You can import an external .hcl file that includes control descriptions // Remember to do this at the threatmodel block level // Similar to the "including" block, this can be a remote file too
// An example of what may be in controls.hcl: // // spec_version = "0.2.3" // component "control" "control_name" { // description = "A control that can be used in multiple places" // }
imports = ["controls.hcl"]
threat {
// To reference the above component control "Control Name" { description = import.control.control_name.description risk_reduction = 50 }
description = <<EOTDescriptions may be a multi-line entry as well.
For example, this is still part of the threat descriptionEOT }
// For more advanced importing of controls, you can also define // expanded "control" "components" in an external file. This allows you to // define all the attributes of a control, centrally, and import // them.
// Importing an expanded control is slightly different.
// An example of what may be in expanded_controls.hcl is below // (note, a single external file can include both expanded controls and // regular controls.)
// spec_version = "0.2.3" // component "control" "authentication_control" { // description = "Multi-factor authentication required" // implemented = true // implementation_notes = "Using TOTP for all admin accounts" // risk_reduction = 80 // // attribute "category" { // value = "Authentication" // }
imports = ["expanded_controls.hcl"]
threat { description = "Authentication is bypassed"
control_imports = ["import.control.authentication_control"]
}
// When this threat model is viewed or exported, it will expand the // referenced control into the "Authentication is bypassed" threat.
// The control_imports attribute is an array, so it can import multiple // controls too.
// As of 0.1.6 threatmodels may contain multiple data_flow_diagram_v2 blocks // The data_flow_diagram_v2 is a HCL representation of a data flow diagram // You can read more about security DFDs here https://docs.microsoft.com/en-us/learn/modules/tm-create-a-threat-model-using-foundational-data-flow-diagram-elements/
data_flow_diagram_v2 "level 0 diagram" {
// All blocks must have unique names // That means that a process, data_store, or external_element can't all // be named "foo"
process "update data" {}
// All these elements may include an optional trust_zone // Trust Zones are used to define trust boundaries
process "update password" { trust_zone = "secure zone" }
data_store "password db" { trust_zone = "secure zone"
// data_store blocks can refer to an information_asset from the // threatmodel information_asset = "cred store" }
external_element "user" {}
// To connect any of the above elements, you use a flow block // Flow blocks can have the same name, but their from and to fields // must be unique
flow "https" { from = "user" to = "update data" }
flow "https" { from = "user" to = "update password" }
flow "tcp" { from = "update password" to = "password db" }
// You can also define Trust Zones at the data_flow_diagram level
trust_zone "public zone" {
// Within a trust_zone you can then include processes, data_stores // or external_elements
// Make sure that either you omit the element's trust_zone, or that it // matches
process "visit external site" {}
external_element "OIDC Provider" {}
} }}