Package: ocsf-validator
OCSF Schema ValidatorA utility to validate contributions to theOCSF
schema, intended to prevent human error
when contributing to the schema in order to keep the schema machine-readable.OCSF provides several include mechanisms to facilitate reuse, but this means
individual schema files may be incomplete. This complicates using off-the-shelf
schema definition tools for validation.Queryis a federated search solution that normalizes
disparate security data to OCSF. This validator is adapted from active code and
documentation generation tools written by the Query team.Getting StartedPrerequisitespython >3.11pipA copy of theOCSF schemaInstallationYou can install the validator withpip:$ pip install ocsf-validatorUsageYou can run the validator against your working copy of the schema to identify problems before submitting a PR. Invoke the validator usingpythonand provide it with the path to the root of your working copy.Examples:$ python -m ocsf_validator .
$ python -m ocsf_validator ../ocsf-schemaTestsThe validator performs the following tests on a copy of the schema:The schema is readable and all JSON is valid. [FATAL]The directory structure meets expectations. [WARNING]The targets in$include,profiles, andextendsdirectives can be found. [ERROR]All required attributes in schema definition files are present. [WARNING]There are no unrecognized attributes in schema definition files. [WARNING]All attributes in the attribute dictionary are used. [WARNING]There are no name collisions within a record type. [WARNING]All attributes are defined in the attribute dictionary. [WARNING]If any ERROR or FATAL tests fail, the validator exits with a non-zero exit code.Technical OverviewThe OCSF metaschema is represented as record types by filepath, achieved as follows:Record types are represented using Python's type system by defining them as PythonTypedDicts intypes.py. This allows the validator to take advantage of Python's reflection capabilities.Files and record types are associated by pattern matching the file paths. These patterns are named inmatchers.pyto allow mistakes to be caught by a type checker.Types are mapped to filepath patterns intype_mapping.py.The contents of the OCSF schema to be validated are primarily represented as aReaderdefined inreader.py.Readers load the schema definitions to be validated from a source (usually from a filesystem) and contain them without judgement. Theprocess_includesfunction and other contents ofprocessor.pymutate the contents of aReaderby applying OCSF's various include mechanisms.Validators are defined invalidators.pyand test the schema contents for various problematic conditions. Validators should passExceptions to a special errorCollectordefined inerrors.py. This module also defines a number of custom exception types that represent problematic schema states. TheCollectorraises errors by default, but can also hold them until they're aggregated by a larger validation process (e.g., theValidationRunner).TheValidationRunnercombines all of the building blocks above to read a proposed schema from a filesystem, validate the schema, and provide useful output and a non-zero exit code if any errors were encountered.ContributingAfter checking out, you'll want to install dependencies:poetry installBefore committing, run the formatters and tests:poetry run isort
poetry run black
poetry run pyright
poetry run pytestIf you're adding a validator, do the following:Write yourvalidate_function invalidate.pyto apply a function to the relevant keys in a reader that will run your desired validation. Seevalidators.pyfor examples.Add any custom errors inerrors.py.Create an option to change its severity level inValidatorOptionsand map it in the constructor ofValidationRunnerinrunner.py.Invoke the new validator inValidationRunner.validate.