Skip to main content

Production-grade Abstract Syntax Tree parser for IDS rules (Suricata/Snort) with comprehensive validation and serialization support

Project description

surinort-ast

surinort-ast

Production-grade AST parser and analysis toolkit for Suricata/Snort rules

PyPI Version Python Versions License CI Status SARIF

GitHub Stars GitHub Issues Buy Me a Coffee


Overview

surinort-ast is a Python toolkit to parse, validate, serialize, and analyze IDS/IPS rules from Suricata, Snort2, and Snort3. It provides a typed AST, CLI workflows, and machine-readable outputs including JSON and SARIF 2.1.0.

Key Features

Feature Description
Typed AST Full Pydantic-backed AST for headers, options, and metadata
Multi-dialect Suricata, Snort2, and Snort3 support
Validation Syntax/semantic diagnostics with severity levels
Serialization JSON and protobuf support
SARIF 2.1.0 Parse/validate/analysis findings export for Code Scanning
CLI + Library Use as command-line tool or Python package
Coverage/Optimization Analysis Built-in analyzers for coverage and optimization insights
Streaming Mode Memory-efficient parsing for large rule sets

Supported Outputs

AST Data        JSON, protobuf
Diagnostics     Human-readable tables, SARIF 2.1.0
Analysis        Text reports, SARIF 2.1.0 findings
CI Integration  SARIF artifact + GitHub Code Scanning upload

Installation

From PyPI (Recommended)

pip install surinort-ast

From Source

git clone https://github.com/seifreed/surinort-ast.git
cd surinort-ast
python3 -m venv venv
source venv/bin/activate  # Windows: venv\Scripts\activate
pip install -e .

Optional Extras

pip install "surinort-ast[all]"
pip install "surinort-ast[serialization]"
pip install "surinort-ast[analysis]"
pip install "surinort-ast[cli-enhanced]"

Quick Start

# Parse rule file
surinort parse rules/local.rules

# Validate with strict mode
surinort validate rules/local.rules --strict

# Export parse findings to SARIF
surinort parse rules/local.rules --format sarif -o parse-results.sarif

Usage

Command Line Interface

# Parse to JSON
surinort parse rules/local.rules --json -o rules.json

# Validate and export SARIF
surinort validate rules/local.rules --format sarif -o validate-results.sarif

# Stats and coverage findings in SARIF
surinort stats rules/local.rules --format sarif -o stats-results.sarif

Available Options (Main Commands)

Command Description
surinort parse Parse rules (text, json, sarif)
surinort validate Validate rules with optional strict mode and SARIF output
surinort stats Rule statistics and optional SARIF coverage findings
surinort fmt Canonical formatting for rule files
surinort to-json Convert rules to JSON
surinort from-json Convert JSON back to rule text
surinort schema Print AST JSON schema

SARIF Flags

Option Description
--format sarif Print SARIF content as command output
--sarif-out <file> Write SARIF report while keeping default output mode
-o, --output <file> Write primary output to file

Python Library

Basic Usage

from surinort_ast import parse_rule, validate_rule, to_json

rule = parse_rule('alert tcp any any -> any 80 (msg:"HTTP"; sid:1;)')
diags = validate_rule(rule)
print(to_json(rule))

for diag in diags:
    print(diag.level, diag.code, diag.message)

SARIF API Usage

from surinort_ast import (
    diagnostics_to_sarif,
    parse_file,
    validate_rule,
)

rules = parse_file("rules/local.rules")
diagnostics = []
for rule in rules:
    diagnostics.extend(validate_rule(rule))

sarif = diagnostics_to_sarif(diagnostics, default_file_path="rules/local.rules")
with open("results.sarif", "w", encoding="utf-8") as f:
    f.write(sarif)

Additional SARIF Helpers

from surinort_ast import (
    coverage_report_to_sarif,
    optimization_results_to_sarif,
    to_sarif,
)

CI and GitHub Code Scanning (SARIF)

The project CI now supports SARIF generation and upload:

  1. Generate results.sarif from real validation diagnostics.
  2. Upload SARIF as workflow artifact.
  3. Upload SARIF to GitHub Code Scanning.

Minimal workflow example:

- name: Generate SARIF report
  run: |
    python - <<'PY'
    from pathlib import Path
    from surinort_ast import diagnostics_to_sarif, parse_file, validate_rule

    fixture_path = Path("tests/fixtures/simple_rules.txt")
    rules = parse_file(fixture_path)
    diagnostics = []
    for rule in rules:
        diagnostics.extend(validate_rule(rule))

    Path("results.sarif").write_text(
        diagnostics_to_sarif(diagnostics, default_file_path=str(fixture_path)),
        encoding="utf-8",
    )
    PY

- name: Upload SARIF to GitHub Code Scanning
  uses: github/codeql-action/upload-sarif@v3
  with:
    sarif_file: results.sarif

Requirements


Contributing

Contributions are welcome.

  1. Fork the repository
  2. Create your feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

Support the Project

If this project is useful in your workflows, you can support development:

Buy Me A Coffee

License

This project is licensed under the GPL-3.0-or-later license. See LICENSE.

Attribution


Built for practical IDS/IPS rule engineering and security automation

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

surinort_ast-2.0.1.tar.gz (416.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

surinort_ast-2.0.1-py3-none-any.whl (251.4 kB view details)

Uploaded Python 3

File details

Details for the file surinort_ast-2.0.1.tar.gz.

File metadata

  • Download URL: surinort_ast-2.0.1.tar.gz
  • Upload date:
  • Size: 416.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for surinort_ast-2.0.1.tar.gz
Algorithm Hash digest
SHA256 efa37797cb922810419cdeba6520235d1208748451070b7b5572d405d0c04e38
MD5 bae8509b085994768437ddc706a47d15
BLAKE2b-256 990b55fc5061d6a1fc814a239a2c6671342eb834374eccc5771ff17ec2b4aaa5

See more details on using hashes here.

Provenance

The following attestation bundles were made for surinort_ast-2.0.1.tar.gz:

Publisher: release.yml on seifreed/surinort-ast

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file surinort_ast-2.0.1-py3-none-any.whl.

File metadata

  • Download URL: surinort_ast-2.0.1-py3-none-any.whl
  • Upload date:
  • Size: 251.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for surinort_ast-2.0.1-py3-none-any.whl
Algorithm Hash digest
SHA256 adcdf2fa0a0e2f947ce8e57d5ad299025b7583f51ed34ae7b31e275d5f612cfc
MD5 4ed21bfa7eb6fabd96c269c155a40f28
BLAKE2b-256 40592b8ed14ccc7185248281a398a186fcede799dbb0ba79fbb2095478aceb3b

See more details on using hashes here.

Provenance

The following attestation bundles were made for surinort_ast-2.0.1-py3-none-any.whl:

Publisher: release.yml on seifreed/surinort-ast

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page