Skip to main content

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

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-3.0.1.tar.gz (573.7 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-3.0.1-py3-none-any.whl (297.5 kB view details)

Uploaded Python 3

File details

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

File metadata

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

File hashes

Hashes for surinort_ast-3.0.1.tar.gz
Algorithm Hash digest
SHA256 90674d870ea77125f5caa4c15b92c6561f782d6edc581307b9c561140dc29f0e
MD5 3db65ae73d756056562b3d4df1e583fe
BLAKE2b-256 067b7da4c4b1ca3f77c567114c0bcfb28855e148ef69e7e6b4eb9ce6d3a2723b

See more details on using hashes here.

Provenance

The following attestation bundles were made for surinort_ast-3.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-3.0.1-py3-none-any.whl.

File metadata

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

File hashes

Hashes for surinort_ast-3.0.1-py3-none-any.whl
Algorithm Hash digest
SHA256 cb109b997a719d8ec729d186fbe14916dda0d56aed0dbc7b538e4052416370e7
MD5 3b65c57b651309dd00e0f0cebd0ee089
BLAKE2b-256 92a4a2fda1b4b4c7d3d6a2518ca8f5ab4027fb705437fc7aa387904c0b2a3d29

See more details on using hashes here.

Provenance

The following attestation bundles were made for surinort_ast-3.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.

Release history Release notifications | RSS feed

3.0.4

2 files

3.0.3

2 files

3.0.2

2 files

This release

3.0.1 This release

2 files

3.0.0

2 files

2.0.1

2 files

2.0.0

2 files

1.1.0

2 files

Supported by

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