APIs and scripts for validating STIX 2.x documents against specification requirements and best practices.
Command-line script entry point and utilities for standalone STIX validation from the command line with comprehensive option support, along with exit code utilities for integration and automation.
Main entry point for the stix2_validator command-line script that provides complete CLI interface for STIX validation.
def main():
"""
Main entry point for the stix2_validator command-line script.
Returns:
None
Description:
Parses command line arguments, runs validation based on options,
prints results, and exits with appropriate status code. Handles
all command-line functionality including file processing, option
parsing, and result output.
Command-line usage:
stix2_validator [OPTIONS] [FILES...]
"""Example Usage:
# Validate a single STIX file
stix2_validator threat_indicators.json
# Validate multiple files with verbose output
stix2_validator --verbose file1.json file2.json
# Validate directory recursively with strict checking
stix2_validator --recursive --strict --version 2.1 stix_files/
# Validate with custom schema directory
stix2_validator --schemas /path/to/schemas indicators.json
# Enable only specific validation checks
stix2_validator --enable 101,201,301 threat_data.json
# Disable specific validation checks
stix2_validator --disable 102,111 --version 2.0 legacy_data.jsonCLI Options:
FILES: Whitespace separated list of STIX files or directories to validate--recursive, -r: Recursively descend into input directories--schemas, -s: Custom schema directory for additional validation--version: STIX specification version to validate against ("2.0" or "2.1")--verbose, -v: Print informational notes and verbose error messages--silent, -q: Silence all output to stdout--strict: Treat warnings as errors and fail validation--strict-types: Warn if custom object types are used--strict-properties: Warn if custom properties are used--enable, -e: Comma-separated list of checks to enable--disable, -d: Comma-separated list of checks to disable--enforce-refs: Ensure referenced objects are in the same bundle--interop: Run validator with interoperability validation settings--no-cache: Disable caching of external source values--refresh-cache: Clear cache and download fresh external values--clear-cache: Clear external source cache after validationFunctions and constants for processing validation results into standardized exit codes for command-line integration and automation.
def get_code(results):
"""
Determines the exit status code from validation results.
Parameters:
- results (List[FileValidationResults]): List of file validation results
Returns:
int: Exit status code (binary OR'd combination of status flags)
Description:
Analyzes validation results and returns appropriate exit code.
Status codes are binary OR'd together to communicate multiple
error conditions in a single exit code.
"""Exit Status Constants:
EXIT_SUCCESS = 0x0 # All documents valid
EXIT_FAILURE = 0x1 # Fatal system error
EXIT_SCHEMA_INVALID = 0x2 # Schema validation failed
EXIT_VALIDATION_ERROR = 0x10 # Validation error occurredExample Usage:
from stix2validator import run_validation, ValidationOptions
from stix2validator.codes import get_code, EXIT_SUCCESS
# Configure validation options
options = ValidationOptions(
files=["threat_data.json", "indicators.json"],
version="2.1",
strict=True
)
# Run validation
results = run_validation(options)
# Get exit code based on results
exit_code = get_code(results)
# Handle different exit scenarios
if exit_code == EXIT_SUCCESS:
print("All validations passed successfully")
elif exit_code & EXIT_SCHEMA_INVALID:
print("Schema validation failed for one or more files")
# Handle schema validation failures
elif exit_code & EXIT_VALIDATION_ERROR:
print("Validation error occurred")
# Handle validation errors
elif exit_code & EXIT_FAILURE:
print("Fatal system error occurred")
# Handle system failures
# Exit with appropriate code for shell integration
import sys
sys.exit(exit_code)#!/bin/bash
# Validate STIX files and handle different outcomes
stix2_validator --version 2.1 --strict threat_intel/*.json
exit_code=$?
case $exit_code in
0)
echo "All STIX files validated successfully"
# Continue with processing
;;
2)
echo "Schema validation failed - check file format"
exit 1
;;
16)
echo "Validation error - check file accessibility"
exit 1
;;
*)
echo "Unexpected validation result: $exit_code"
exit 1
;;
esacimport subprocess
import sys
from stix2validator.codes import EXIT_SUCCESS, EXIT_SCHEMA_INVALID, EXIT_VALIDATION_ERROR
def validate_stix_files(file_paths, version="2.1", strict=True):
"""
Validate STIX files using command-line interface.
Parameters:
- file_paths (List[str]): Paths to STIX files to validate
- version (str): STIX specification version
- strict (bool): Enable strict validation mode
Returns:
dict: Validation results summary
"""
cmd = ["stix2_validator", "--version", version]
if strict:
cmd.append("--strict")
cmd.extend(file_paths)
try:
result = subprocess.run(cmd, capture_output=True, text=True)
return {
"success": result.returncode == EXIT_SUCCESS,
"exit_code": result.returncode,
"stdout": result.stdout,
"stderr": result.stderr,
"schema_invalid": bool(result.returncode & EXIT_SCHEMA_INVALID),
"validation_error": bool(result.returncode & EXIT_VALIDATION_ERROR)
}
except subprocess.CalledProcessError as e:
return {
"success": False,
"exit_code": e.returncode,
"error": str(e)
}
# Usage example
files_to_validate = ["indicators.json", "malware.json", "threat_actors.json"]
validation_result = validate_stix_files(files_to_validate)
if validation_result["success"]:
print("✓ All STIX files are valid")
else:
print("✗ Validation failed:")
if validation_result["schema_invalid"]:
print(" - Schema validation errors found")
if validation_result["validation_error"]:
print(" - File access or parsing errors occurred")
print(f"Exit code: {validation_result['exit_code']}")
print(f"Output: {validation_result.get('stdout', '')}")# Example GitHub Actions workflow
name: STIX Validation
on: [push, pull_request]
jobs:
validate-stix:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Set up Python
uses: actions/setup-python@v2
with:
python-version: '3.9'
- name: Install STIX Validator
run: pip install stix2-validator
- name: Validate STIX Files
run: |
stix2_validator --version 2.1 --strict --recursive stix_data/
echo "Validation exit code: $?"
- name: Validate with Custom Rules
run: |
stix2_validator --schemas custom_schemas/ --enable 1,2,3 threat_intel/#!/usr/bin/env python3
"""
Advanced STIX validation script with comprehensive reporting.
"""
import argparse
import os
import sys
from pathlib import Path
from stix2validator import run_validation, ValidationOptions
from stix2validator.codes import get_code, EXIT_SUCCESS
from stix2validator.scripts.stix2_validator import main as cli_main
def batch_validate_directory(directory, recursive=True, version="2.1"):
"""
Batch validate all STIX files in a directory with detailed reporting.
"""
options = ValidationOptions(
files=[directory],
recursive=recursive,
version=version,
verbose=True
)
results = run_validation(options)
exit_code = get_code(results)
# Generate detailed report
total_files = len(results)
valid_files = sum(1 for r in results if r.is_valid)
invalid_files = total_files - valid_files
print(f"\n{'='*60}")
print(f"STIX Validation Report")
print(f"{'='*60}")
print(f"Directory: {directory}")
print(f"Recursive: {recursive}")
print(f"STIX Version: {version}")
print(f"Total Files: {total_files}")
print(f"Valid Files: {valid_files}")
print(f"Invalid Files: {invalid_files}")
print(f"Success Rate: {(valid_files/total_files)*100:.1f}%")
print(f"Exit Code: {exit_code}")
if invalid_files > 0:
print(f"\nInvalid Files:")
for result in results:
if not result.is_valid:
print(f" • {result.filepath}")
for obj_result in result.object_results:
for error in obj_result.errors:
print(f" - {error}")
return exit_code == EXIT_SUCCESS
if __name__ == "__main__":
parser = argparse.ArgumentParser(description="Batch STIX validation with reporting")
parser.add_argument("directory", help="Directory containing STIX files")
parser.add_argument("--version", default="2.1", help="STIX version (2.0 or 2.1)")
parser.add_argument("--no-recursive", action="store_true", help="Don't recurse into subdirectories")
args = parser.parse_args()
if not os.path.isdir(args.directory):
print(f"Error: {args.directory} is not a valid directory")
sys.exit(1)
success = batch_validate_directory(
args.directory,
recursive=not args.no_recursive,
version=args.version
)
sys.exit(0 if success else 1)Install with Tessl CLI
npx tessl i tessl/pypi-stix2-validator