VERIS: a vocabulary for recording incidents that links to ATT&CK and the CIS controls
Vocabulary for Event Recording and Incident Sharing (VERIS)
At a glance
- What is it?
- VERIS is a schema and toolchain for recording security incidents in a structured, machine readable form, with JSON schema files, validation scripts and mappings to the MITRE ATT&CK framework and the CIS Critical Security Controls. It suits a security team that wants consistent incident records across a whole portfolio of systems, and it is a data format with a long upgrade history rather than a finished product.
- Who is it for?
- VERIS fits a large organisation that records incidents across many systems and wants one structured format with a validation script and a mapping to ATT&CK rather than a free text log. It does not fit a small team that needs a fast incident write up, because the schema and the enumeration discipline are the point and both cost effort to apply.
- Can I use it commercially?
- Check first. The repository uses a licence we do not classify automatically, so read its LICENSE file before any commercial use.
- Is it still maintained?
- Yes. The repository last received commits 9 days ago.
- What is it written in?
- Mainly HTML, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
A vocabulary first, and a toolchain that comes with it
VERIS stands for Vocabulary for Event Recording and Incident Sharing, and the repository is a schema with a set of scripts around it. The homepage is verisframework.org, the primary language of the repository is recorded as HTML because much of the content is a browsable schema, and the last push was on 2026-10-14.
The release history shows a project with an unusual shape. There is v1.4.0 from 2025-11-26, and before that v1.3.4 from 2019-10-16 and v1.3.3.1 from 2019-10-03. Six years separate the two most recent releases, which tells you the schema itself is stable and the recent work is elsewhere, in the mappings and the toolchain.
The note to VERIS users at the top of the README explains the version history in more detail, and it is worth reading carefully because it describes a project in the middle of a deliberate sequence. The note says VERIS has been updated to version 1.3.2, which is primarily an update to add or modify a few enumerations, but it involves a significant change in the associated import scripts. From there the plan is to update to version 1.4, which will fix schema hierarchy issues that may affect tooling. The primary example given is making discovery_method and asset hierarchical like actor, action and attribute. And version 2.0 is reserved for major feature additions, with the primary one being considered being the addition of sequencing of the 4A's, timeline and discovery method, so that the sequence things happened in during an incident can be captured.
That last point is the one a user should weigh. The core 4A model of actor, action, attribute and asset is the stable part, and the timeline is the missing piece for incident chronology.
The licence is recorded as a custom one that GitHub cannot classify, with the terms in the LICENSE.txt file at the top of the repository.
The files at the top level, and what each one is for
The README's index section is the best available map of the project, and it is a list of files with a one line description each.
The schema side starts with verisc.json, the JSON schema definition, compliant with the proposed JSON standard, which is merged with verisc-labels.json to produce verisc-enum.json, verisc-merged.json and keynames-real.txt. The labels file is a list of enumerations with descriptions, and verisc-enum.json is the definition of the allowable enumerations within VERIS, while verisc-merged.json is the complete schema used for converting reviewed CSVs to JSON.
A note in the JSON Notes section explains why there are two files rather than one. The README points at the JSON schema definition site, and states that the enumerations are not enforced at the schema level, but instead there is a separate file with the enumerations, and that those may update a bit more often than the schema itself. Separating the two is what lets an enumeration be added without a schema revision, and it also means a consumer that only reads verisc.json is not seeing the allowed values.
The script side is a small toolchain in Python. checkValidity.py validates a JSON record against a schema file as well as additional rules, and is usable as a module. import_veris.py imports a CSV to JSON, choosing the correct import module and using the rules module and the checkValidity module. rules.py makes JSON files valid by adding unknowns, and adds rules such as adding asset.assets.web_app if hacking.vector.web_app is present. mergeSchema.py merges the schema file and the labels file to form the merged schema file, and update_labels.py and update_schema.py update an existing file from a diff file.
There is also a standard spreadsheet workflow. VERIS_Standard_Excel.xlsx is the standard Excel file used to produce importable data, bin/build_standard_excel.py reads a merged schema file and produces it, and import_stdexcel.py converts the Reviewed data in that workbook to a CSV to JSON. That is a human editing surface for people who do not want to write JSON by hand.
And there are conversion scripts for moving records forward, convert-1.3.py for VERIS 1.2 JSON records to 1.3, and convert_1.3.X_to_1.3.Y.py for 1.3.X to 1.3.Y.
Validation and tests, and a Python 2 era toolchain
The validation story is the part that makes VERIS a toolchain rather than a document, and the README describes it directly.
Each unit test is a VERIS json object wrapped inside another object, and each test object has three keys. The incident key should be a VERIS json object, the should key indicates whether the incident should pass or fail validation, and the message is a string that explains why the incident should or should not pass validation.
That is a good test design, because it lets the suite express negative cases as directly as positive ones, and the message field means a failure tells you which rule you broke rather than just that something broke.
Running the tests has its own requirements, and they date the project. Unit tests are written in nose, so you need to pip install nose, and then from the root of the repository you run nosetests, and Python will automatically run the tests in the tests folder. If you want detailed output you can run nosetests --nocapture.
The nose framework is long deprecated, and the fact that the validation suite is built on it means a new contributor is installing a package that no longer works on current Python in the way it used to. That is a real cost of picking up this repository today, and it is the kind of thing worth checking before committing a team to a schema.
The required packages list adds to the picture, and it is short. For Python, the tools require ipdb and simplejson. The dependencies directory in the repository is a mappings folder, and there is a verismm directory whose name suggests it holds the mapping and modelling tools, along with a style_guide directory and the veris_style_guide.md document.
The Python 2 era tooling is consistent with the release history. A schema project that has been stable since 2019 keeps the toolchain it had, and the cost shows up when someone tries to run the tests rather than when they use the schema.
Joined JSON and JSON-LD, two ways of making the records growable
The README describes a specific problem with scale and a specific answer to it.
As the amount of VERIS json grows, it becomes unwieldy, and the toolchain is being updated to allow a joined form of VERIS. There is a document for it, joined_veris_json.md, and the point of the change is that a single incident record, which nests assets and actions inside a hierarchy, becomes hard to query once the schema is deep enough.
The second answer is JSON-LD. The README explains that JSON-LD is a format for storing linked data, and that the verisc.jsonld file is the graph representation of the VERIS schema rather than the json-schema format, which is the main format for VERIS.
The distinction is worth holding onto. The JSON schema is what validators check a record against, and it is a tree. The JSON-LD file is the same schema expressed as a graph, which is what makes a joined form possible, because in a graph the shared pieces are shared rather than copied into every record that mentions them.
The XML version has been archived until the XML can be synced with the JSON schema, and the README states that the JSON schema represents the latest version of VERIS. So there is one current format, one archived one, and a graph projection for tooling that needs it.
For an organisation that already stores incidents in a graph or a relational warehouse, the joined form and the JSON-LD file are the parts that matter, because they are what let a VERIS record map onto something you already query.
The ATT&CK and CIS mappings, which is where the value sits
The two mapping sections are what turn VERIS from a data format into something an organisation can use for decisions, and the README is direct about the intent of each.
The VERIS Common Attack Framework, or VCAF, serves as a bridge to ATT&CK, covering the portions of VERIS not in ATT&CK with the aim of creating a holistic framework. At its core it is made of two components: the conceptual mapping between VERIS and ATT&CK, and an extension of ATT&CK with techniques that cover all possible Threat Actions present in VERIS. The README says this is helpful in using ATT&CK to make strategic decisions and understanding what tactical actions to take to address a strategic challenge. The mapping is an edge list, or a join table for the more SQL minded, in bin/vcaf-rev2020-v1_0_3.csv.
That edge list is a nice piece of design. A mapping expressed as a list of edges can be loaded into a graph database, joined in SQL, or diffed between versions, which a nested mapping document cannot do as cleanly.
The second mapping is to the Center for Internet Security Critical Security Controls. The README describes it as providing both pattern and control mappings for the CIS Critical Security Controls to VERIS, and says it is helpful in using VERIS to make consistent control decisions. The file is an xlsx workbook, bin/cis_csc_veris_map-rev2020-v1_0.xlsx, and there is a second file in the repository, cis_csc_veris_map-rev20XX-vY_Y_Y.csv, described as a VERIS to CIS CSC mapping for both VERIS patterns and actions.
Note the version stamps on all of these files. The mappings are dated rev2020 with a version suffix, which tells you they are point-in-time artefacts rather than living links, so an organisation using them needs a process for picking them up again when ATT&CK or the control set changes.
The practical trade of a shared vocabulary
Two questions decide whether VERIS is worth adopting, and both are about cost rather than capability.
The first is the value of standardisation against the friction of rigidity. The value is real. An incident recorded in VERIS can be compared across a portfolio, counted by action and asset, mapped to controls, and handed to an analyst without translation. A free text timeline cannot do any of that. But a schema that describes an incident in a fixed hierarchy is also a schema that does not fit some incidents, and the README shows the project anticipating that, with the plan to add sequencing of the 4As, timeline and discovery method in a future version so that the order of events can be captured.
The second is the version discipline, which the README is unusually open about. It asks users who are using VERIS to contact the maintainers to say how they use it and with what tools, and invites suggestions on changes through the same route, with the stated purpose being to make sure the changes have minimal impact on all users and allow for easy upgrade at the user's convenience. To that end the project has saved a v1.3 release for those who chose not to upgrade, along with a v1.3 branch.
That combination, a migration script per version step, a preserved old branch, and a request that you tell them what you are doing, describes a format with a large installed base and a small team. For a large organisation, that is a reasonable trade: you get a vocabulary that many others already speak, and you accept that upgrades need a conversion run.
For a small team with a handful of incidents a month, the trade is different. The schema discipline, the enumeration files and the version conversions are overhead, and a smaller format that matches what the team actually needs will serve them better. The README itself points out that a v1.3 release was kept for those who chose not to upgrade, which is a sensible way to handle exactly that kind of team.
Editorial conclusion
VERIS fits a large organisation that records incidents across many systems and wants one structured format with a validation script and a mapping to ATT&CK rather than a free text log. It does not fit a small team that needs a fast incident write up, because the schema and the enumeration discipline are the point and both cost effort to apply. Before adopting it, read the note to VERIS users at the top of the README, since it describes an in-flight version history with a 2.0 planned for feature additions, and check the changelog and the convert scripts, because moving records between schema versions is done by running a specific conversion script per version step.
Frequently asked questions
What is VERIS and what does it give an organisation?
VERIS is the Vocabulary for Event Recording and Incident Sharing, a schema and toolchain for recording security incidents in a structured form, with validation scripts, a standard Excel input sheet, and mappings to the MITRE ATT&CK framework through VCAF and to the CIS Critical Security Controls.
How do I run the VERIS validation tests?
The unit tests are written in nose, so you need to pip install nose, and then run nosetests from the root of the repository, where Python picks up the tests folder automatically. For detailed output you can run nosetests --nocapture.
What is the difference between verisc.json and verisc-labels.json in VERIS?
verisc.json is the JSON schema definition and verisc-labels.json is the list of enumerations with descriptions, and the two are merged to produce verisc-enum.json, verisc-merged.json and keynames-real.txt. The enumerations are not enforced at the schema level, so they are kept in a separate file that may update more often than the schema.
How do I upgrade VERIS records between schema versions?
The repository ships conversion scripts, with convert-1.3.py converting VERIS 1.2 json records to 1.3 and convert_1.3.X_to_1.3.Y.py handling 1.3.X to 1.3.Y. The project has also saved a v1.3 release and a v1.3 branch for users who chose not to upgrade.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/vz-risk-veris)Was this useful?