# VCDB is the public breach dataset that has to admit its own sampling bias

> The VERIS Community Database collects publicly disclosed security incidents in a structured schema so researchers can work with raw breach records rather than summaries. Its most valuable feature is also its most awkward: the repository states plainly which incidents were selected on purpose and publishes the counts needed to normalise for it.

**vz-risk/VCDB** — VERIS Community Database

- Repository: https://github.com/vz-risk/VCDB
- Stars: 674 · Forks: 207
- Language: Python
- License: NOASSERTION
- Published: 2026-10-21 · Updated: 2026-10-21 · Language: en
- Canonical page: https://hysenlabs.com/projects/vz-risk-vcdb

## The gap VCDB fills is raw incident records, not more statistics

The README states the problem in plain terms. There are a handful of efforts to capture publicly disclosed security incidents, but no unrestricted, comprehensive raw dataset for download that is rich enough to support both community research and corporate decision making. Organisations do collect and disseminate aggregated collections, and the README says those either are not in a format that lends itself to the data manipulation and transformation research requires, or the underlying data are not freely and publicly available. The consequence it names is that this gap has long hampered researchers studying security incidents and left risk managers short of reliable data for their calculations. The framing matters for anyone judging whether to adopt the dataset. VCDB is not a summary of the Verizon Data Breach Investigations Report, and it is not a scanner feed. It is an attempt to publish incident level records in a schema that a researcher can load, reshape and analyse.

## Why the data is limited and what the maintainers can share

The README is unusually candid about the limits of the corpus. The Verizon RISK Team supports and participates in information sharing initiatives and research, and drives the annual Verizon Data Breach Investigations Report, which it keeps publicly available and free to download. The team says it regularly receives inquiries about the dataset and about sharing further, but that it is limited in what it can share in raw format because of agreements with its partners and customers. So the constraint is contractual, not technical, and the project is the visible part of a data sharing process that runs with industry partners. A second framing of the same risk appears in the opening paragraph, which notes that information sharing done poorly may mislead participants or create a learning opportunity for adversaries, while done correctly it benefits everyone through collective intelligence. Both sentences are reasons to read the schema documentation carefully before drawing conclusions from the records.

## The submitted, validated and overridden pipeline decides what counts as a record

The repository layout shows a working pipeline rather than a single file of records. There is a data directory, and the Claude Code support notes refer to a submitted, validated and overridden incident pipeline that is described in the CLAUDE.md file at the repository root, alongside the repository layout, common commands and coding conventions. New records are written as individual JSON files into a submitted directory, one per incident, named by UUID, and then they move through review into the validated state, with an overridden state for records that reviewers changed. A bin directory and a tools directory sit alongside the data, and the top level carries schema and label files, campaigns notes, a NEWS file and an Excel spreadsheet named VCDB_Standard_Excel.xlsx, which is presumably the encoding standard in a form a human can read. For a user, the practical question is which state the records you are analysing are in, and the repository is at least explicit that there is a pipeline and that not everything in it has been reviewed.

## The sampling warning is the most useful paragraph in the repository

A section headed as a warning on sampling explains that most VCDB issues are chosen at random, with a preference for those in the last year, but that healthcare issues and some priority incidents are selected specifically. Non random selections are identifiable from the value of a field called plus.sub_source, which is phidbr for healthcare issues and priority for priority issues. The repository then publishes the issue composition as of Jan 13, 2018, so that anyone who wants to remove the effect of the non random selection can normalise the actual incidents to a stated baseline.

```json
{
'2013': {'all': 1199, 'phidbr': 0, 'priority': 11},
'2014': {'all': 3885, 'phidbr': 30, 'priority': 113},
'2015': {'all': 1844, 'phidbr': 197, 'priority': 47},
'2016': {'all': 1996, 'phidbr': 516, 'priority': 75},
'2017': {'all': 1826, 'phidbr': 455, 'priority': 75},
'2018': {'all': 28, 'phidbr': 8, 'priority': 1}
}
```

Datasets that do this are rare, and it is the reason to trust the numbers that come out of VCDB. The counts are also dated, which means anyone extending the analysis to later years has to recompute the composition rather than reuse the published table.

## A Claude Code skill encodes issues into schema files with an AI tag

The repository ships support for Claude Code, Anthropic's command line coding agent, in two pieces. The CLAUDE.md file at the root is background the agent reads automatically at the start of every session, covering the repository layout, the incident pipeline, common commands and the conventions and gotchas of the project. The second piece is a skill in the .claude/skills/encode-veris-incident directory, described as a packaged, repeatable procedure for turning a GitHub issue that describes a data breach into a VERIS schema incident JSON file. Given an issue number or URL, the skill reads the issue and any linked sources, searches for an additional independent source to corroborate the breach, maps the facts to the schema in the vcdb-merged.json file following the VERIS coding style guide, runs a semantic lint plus JSON schema validation to catch missing or inconsistent fields, and writes the result into the submitted directory ready for the normal pipeline. The example invocation in the README is short.

```bash
Use the encode-veris-incident skill to encode issue #23572 into a VCDB incident. My GitHub handle is <your-github-handle>.
```

One detail deserves attention. Every incident the skill produces is tagged in the plus.analyst_notes field with the skill version and an Encoded by AI attribution, so a reviewer can always tell which skill revision and which AI produced a given record.

## The schema family explains what a record actually contains

The index at the end of the README lists the schema files, and the differences between them are the difference between the raw standard and the usable one. The verisc schema and labels files are the upstream VERIS definitions, and the vcdb_diff.json and vcdb_diff-labels.json files are the updates applied to them to produce the community database versions. The vcdb.json file is the resulting schema, vcdb-labels.json is the labels file, and vcdb-merged.json is the full schema combining the schema and the enumerations from the labels file. That merged file is the one the encoding skill targets. Two more files exist purely for tooling convenience: vcdb-enum.json contains just the enumerations, and vcdb-keynames-real.txt lists the keys in the schema, with a keynames-real.txt file at the top level of the tree as well. Anyone loading the data will spend their first hour with these files, since the schema is wide and flat by design, and knowing which enumeration list matches which schema version is what keeps an analysis from silently mixing definitions across releases.

## The analysis examples are R, and the licence sits in a file

The README demonstrates analysis with R, using the vcdb object, dplyr for reshaping and ggplot2 for plotting, with the verisr package providing enum CI helpers. The first example groups by a confidentiality and data disclosure field, counts by incident year and plots breaches against incidents.

```r
vcdb %>%
    dplyr::group_by(attribute.confidentiality.data_disclosure.Yes) %>%
    dplyr::count(timeline.incident.year) %>%
    dplyr::ungroup() %>%
    dplyr::rename(breach = attribute.confidentiality.data_disclosure.Yes) %>%
    dplyr::mutate(breach = ifelse(breach, "Breach", "Incident")) %>%
```

A second example builds a tile grid of the action enum against asset variety, and the rendered outputs are committed as figure files, one for the yearly plot and one for the grid. Two maintenance facts round out the picture. The repository listing reports the licence as a custom one that GitHub cannot classify, with the terms in the LICENSE.txt file, so the file rather than the metadata is what your reviewer should read. And the release tags are old, v2014-q4 and earlier quarterly releases from 2014, while the last push was on 2026-10-12 and the repository is not archived, so the data, the schema and the tooling move without new tagged versions.

## Conclusion

VCDB is worth using for anyone who has been limited to aggregated breach statistics and needs record level data with a documented schema, since the JSON files, the key name lists and the published sampling composition make it analysable rather than merely available. It is the wrong dataset for anyone who needs incident coverage after 2018, since the composition figures in the repository stop there, and the wrong choice if you cannot accept a corpus drawn mostly from publicly disclosed incidents, which by construction misses the cases that were never disclosed. Before you build on it, check three things: whether the incidents you care about are in the submitted, validated and overridden pipeline or still waiting for review, whether the sampling composition in the repository is recent enough for your years of interest, and whether the terms in LICENSE.txt match the use you intend, since the repository listing reports a custom licence that GitHub cannot classify. The last push was on 2026-10-12, so the data and the tooling are still moving, even though the newest release tag is from 2014.

## FAQ

### What is the VCDB and what does it contain?

It is the VERIS Community Database, a public collection of security incident records described in a VERIS schema. The README says there is no unrestricted, comprehensive raw dataset of publicly disclosed security incidents available for download, and that this project exists to provide one in a form that supports research.

### Why does the VCDB README warn about sampling?

Most issues are chosen at random with a preference for the last year, but healthcare issues and some priority incidents are selected deliberately, which is visible in the plus.sub_source field as phidbr or priority. The repository publishes the issue composition as of Jan 13, 2018 so that the non random selection can be normalised out.

### How do new incidents get added to the VCDB?

New records are written as individual JSON files into the submitted directory named by UUID, and then they move through the submitted, validated and overridden pipeline described in the CLAUDE.md file. A Claude Code skill can also encode a GitHub issue into a schema file and mark it with an Encoded by AI attribution.

### Which schema file should I use for analysis?

The vcdb-merged.json file is the full schema combining the schema and the enumerations from the labels file, and it is what the encoding skill targets. vcdb-enum.json holds just the enumerations and vcdb-keynames-real.txt lists the keys in the schema.

## Sources

- [Issues](https://github.com/vz-risk/VCDB/issues)
- [README](https://github.com/vz-risk/VCDB/blob/master/README.md)
- [Releases](https://github.com/vz-risk/VCDB/releases)
- [vz-risk/VCDB on GitHub](https://github.com/vz-risk/VCDB)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/vz-risk-vcdb
