Project Milestones And Release Roadmap#
The opnDossier project is a network security auditing tool that analyzes firewall configurations offline. As of March 2026, the project is at v1.2.1 (released February 12, 2026), with a comprehensive roadmap extending through v2.1.0 and beyond. The project follows semantic versioning (SemVer) with clear distinctions between breaking changes (major versions), new features (minor versions), and bug fixes (patch versions).
The roadmap represents a strategic evolution from a single-vendor OPNsense configuration parser to a multi-vendor platform supporting pfSense, Cisco ASA, Fortinet FortiGate, and potentially other network devices. This evolution requires significant architectural refactoring spanning four milestone versions: v1.3.0 introduces public package APIs for external consumption; v1.4.0 extracts shared model libraries; v2.0.0 implements a device parser registry system with breaking changes including template system removal, unified Finding types, and custom rule engines; and v2.1.0 delivers multi-vendor platform expansion. The architectural refactoring maintains five core design principles: offline-first operation, operator-focused CLI workflows, framework-first library choices, structured data preservation, and security-first validation.
The project does not commit to specific target release dates, instead using milestone-based planning where features are completed when ready, with quality and stability prioritized over deadlines. As of March 2026, v1.3.0 has been completed via PR #404, establishing public package APIs as the foundation for v2.0.0 breaking changes.
Milestone Overview#
As of March 2026, v1.3.0 has been completed, enabling external Go projects to import opnDossier's data types and parsing infrastructure. pfSense support (v2.1.0) has also been delivered via PR #459, making it the first multi-vendor implementation and establishing the architectural template for additional device types. The remaining milestones are deliberately sequenced: v1.3.0's public package infrastructure enabled pfSense implementation to proceed alongside v2.0.0 registry work, demonstrating that multi-vendor support can coexist with OPNsense's existing architecture during the transition period.
Milestone Status Summary#
| Milestone | Status | Focus Area | Breaking Changes |
|---|---|---|---|
| v1.3.0 | COMPLETED (Mar 2026) | Public API exposure | No |
| v1.4.0 | 0 closed / 3 open | Shared model libraries | TBD |
| v2.0.0 | 18 closed / 13 open | Parser registry, compliance | Yes |
| v2.1.0 | 1 closed / 3 open | Multi-vendor expansion | TBD |
Core Milestones#
v1.3.0: Public Package Migration ✅#
Issue #301 moved device schemas and the CommonDevice model from internal/ to pkg/ packages, enabling external Go projects to import opnDossier's data types and parsing infrastructure. This milestone was completed in March 2026 via PR #404.
Key Changes:
- Relocated types from
internal/model/common/topkg/model/ - Moved OPNsense schemas from
internal/schema/topkg/schema/opnsense/ - Migrated parser from
internal/model/opnsense/topkg/parser/opnsense/ - Moved factory from
internal/model/factory.gotopkg/parser/factory.go - Renamed
ParserFactory→Factory(Go naming convention, avoids stuttering) - Updated 173 files with new import paths
- Eliminated entire
internal/model/re-export layer (17 files, ~90 type aliases deleted)
Implementation Approach:
The migration completed the planned four-phase strategy:
- ✅ Created public package structure via
git mv - ✅ Mechanical import path updates across 104 consumer files
- ✅ Removed backward compatibility bridge (not needed—direct cutover)
- ✅ Validation and documentation updates
Acceptance Criteria:
- ✅
pkg/model/package created with CommonDevice exports - ✅
pkg/schema/opnsense/created with XML DTOs - ✅
pkg/parser/created with DeviceParser interface and Factory - ✅ All tests pass with no behavior changes
- ✅ External import validation succeeds (requires post-merge
go get) - ✅ Documentation updated (AGENTS.md, architecture docs, copilot instructions)
Status: COMPLETED via PR #404 (March 2026)
v1.4.0: Shared Model Libraries#
[Issue #157](background context) plans to extract common model libraries into reusable packages, creating a shared evilbitlabs-network-model Go module. This milestone appears to have evolved into the more comprehensive approach documented in Issue #196, which describes creating pkg/model/ with shared abstractions like Device, NetworkInterface, FirewallRule, etc.
Note: With v1.3.0's completion, the pkg/model/ package structure is already in place, potentially simplifying or redefining the scope of this milestone.
Planned Features:
- Extract common model libraries into reusable packages
- Shared Go module for network device models across multiple projects
- Foundation for cross-project type consistency
Status: 0 closed / 3 open issues as of March 2026
v2.0.0: Major Architectural Refactoring#
Version 2.0.0 represents a major breaking release with significant architectural changes spanning parser infrastructure, compliance features, and UI enhancements. Issue #302 serves as the core parser registry refactoring that enables most v2.0.0 functionality.
Parser Registry System (Issue #302)#
Replaces hardcoded device-type switching with a thread-safe registry pattern for pluggable parser implementations. The foundation for this work was established in v1.3.0 with the public pkg/parser/ package structure.
Core Changes:
- Thread-safe
Factorywithsync.RWMutexfor concurrent access Register(rootElement string, newParser func() DeviceParser) errorfor parser registrationSupportedDevices() []stringreturns registered device types- Duplicate registration detection at startup
- Registry pattern enables multi-vendor support without hardcoded switching
Plugin Architecture:
Built-in parsers self-register via init() functions:
// pkg/parser/opnsense/parser.go
func init() {
parser.DefaultFactory.Register("opnsense", func() parser.DeviceParser {
return NewParser()
})
}
External parsers can register via compile-time linking with blank imports, following the pattern used by sqlc, buf, and HashiCorp tools. Post-v2.0.0 consideration includes HashiCorp go-plugin style subprocess plugins for dynamic discovery.
Model Layer Refactoring (Issue #196)#
Refactors the model layer to decouple internal domain representation from OPNsense config.xml structure, creating clean separation between XML schema (DTOs) and domain models. The v1.3.0 migration to pkg/ packages completed the structural foundation for this work.
Current Architecture Problems:
- Tight coupling between business logic and XML-shaped structures
- Inflexible input sources (assumes config.xml only)
- XML serialization concerns leak into domain logic (
xml:""tags throughout) - Testing requires XML parsing infrastructure
Proposed Three-Layer Architecture:
-
Schema Layer (DTOs) -
pkg/schema/opnsense/- Mirrors external config.xml format structure
- Contains
xml:tags and serialization concerns - Minimal logic, pure data structures
-
Domain Layer -
pkg/model/- Platform-agnostic
CommonDevicemodel - Device-agnostic types:
NetworkInterface,FirewallRule,VLANConfig, etc. - Exposes slices directly without container wrappers
- Native Go
booltypes instead of customBoolFlag
- Platform-agnostic
-
Device-Specific Parsers
pkg/parser/opnsense/- OPNsense parser and converterpkg/parser/pfsense/- pfSense parser and converter (future)pkg/parser/factory.go- Parser factory based on device detection
Implementation Timeline:
The 8-10 week roadmap includes five phases:
- Foundation (Weeks 1-2): Schema mapping, domain model interfaces, device detection
- OPNsense Refactoring (Weeks 3-4): Move to device-specific directories, implement converters
- Template & Processor Updates (Weeks 5-6): Update report generators to use domain models
- pfSense Support (Weeks 7-8): Implement pfSense parser and converters
- Integration & Validation (Ongoing): E2E tests, performance checks, documentation
Template System Removal (Issue #154)#
Converts all custom template functions into proper Go methods with compile-time safety and improved testability. Issue #86 "Phase 3: Port Template Functions to Go Methods" documents the systematic porting of 20+ template functions to MarkdownBuilder methods.
Rationale:
- Compile-time safety: Catch errors during build instead of runtime
- Better testability: Unit test individual methods
- IDE support: Full IntelliSense and debugging
- Performance: 45% faster (no template parsing overhead), 30% less memory usage
- Maintainability: Single code path eliminates dual maintenance burden
Migration Strategy:
- v2.0: Programmatic mode becomes default, templates require
--use-templateflag - v2.x: Deprecation warnings for template usage
- v3.0: Consider removing template support entirely
Subtasks:
The migration is tracked through 10 detailed subtasks (issues #89-#98), including utility function ports, data transformation, security assessment functions, testing, benchmarks, and documentation.
Unified Finding Types (Issue #280)#
Issue #280 unified Finding types across compliance, processor, and audit packages to eliminate duplication and improve consistency. This was implemented via PR #391.
Problem Statement:
The codebase had duplicate Finding type definitions across:
internal/compliance/- Compliance findingsinternal/processor/- Processing findingsinternal/audit/- Audit findings
This created inconsistent field names, difficulty aggregating findings, and maintenance burden.
Implementation:
The refactoring established canonical types in internal/analysis/finding.go:
Findingstruct with standardized fields (Type, Severity, Title, Description, etc.)Severitytype with constants (Critical, High, Medium, Low, Info)- Validation helpers and metadata support
The compliance.Finding and processor.Finding types are type aliases to analysis.Finding, eliminating duplication while maintaining backward compatibility. The audit module was refactored to use the canonical analysis.Finding struct directly.
Status: Implemented in PR #391
Compliance and Security Features#
Custom Rule Engine (Issue #205):
Implements custom rule engine for organization-specific compliance policies, enabling organizations to define security policies in declarative YAML format:
rules:
- id: firewall-default-deny
description: "Firewall must have default deny rule"
severity: high
category: firewall
check:
- filter.rules[].action != "pass" where interface == "wan"
SIEM Integration (Issue #208/209):
Issue #209 adds SARIF (Static Analysis Results Interchange Format) export for CI/CD security integration. SARIF is a JSON-based format for static analysis tools that can be ingested by GitHub Security, GitLab Security Dashboards, and many SIEM platforms.
PCI-DSS Checks (Issue #204):
Planned PCI-DSS (Payment Card Industry Data Security Standard) compliance checks would include network segmentation validation, firewall rule compliance, strong cryptography requirements, access control validation, and audit logging configuration. Details are not yet documented in a dedicated issue thread.
Config Drift Detection (Issue #201):
Planned configuration drift detection would identify changes between multiple configuration snapshots over time, expected baseline vs. current state, and multi-device configurations in clusters. Related work includes Issue #243 on deterministic ordering and PR #245 on side-by-side diff formatting.
User Interface Enhancements#
TUI - Terminal User Interface (Issue #211):
A planned terminal user interface would provide interactive, menu-driven operations. PR #245 implements side-by-side terminal formatting, which suggests terminal UI work is underway.
Web UI (Issue #213):
A planned web user interface would complement the CLI tool with browser-based report viewing, configuration file upload, and visual diff tools. This feature raises architectural questions about maintaining opnDossier's offline-first philosophy.
Status: 18 closed / 13 open issues as of March 2026
v2.1.0: Multi-Vendor Platform Expansion#
Version 2.1.0 focuses on expanding device support beyond OPNsense to multiple network security platforms. As of March 2026, pfSense support has been delivered via PR #459, establishing the architectural template for additional device types.
pfSense Support (Issue #197) ✅#
Issue #197 added comprehensive support for parsing pfSense config.xml configuration files through a device-agnostic abstraction layer. This was completed via PR #459 in March 2026, making pfSense the first multi-vendor implementation.
Rationale:
pfSense and OPNsense share a common heritage (OPNsense forked from pfSense), resulting in similar but distinct configuration formats. Supporting pfSense expands the tool's utility for security auditors working in heterogeneous environments.
Key Structural Differences:
- Root element:
<pfsense>vs<opnsense> - Password field:
bcrypt-hashvspasswd - Default user:
adminvsroot - Element organization variations
Implementation Delivered:
The implementation followed the planned 4-phase architecture from Issue #197:
- Device Document Interface - Extended
pkg/model/device.gowithDeviceType.DisplayName()method for proper platform name casing in reports - Parser Abstraction - Reused existing
DeviceParserinterface from v1.3.0 public packages - pfSense Implementation - Created
pkg/schema/pfsense/with 5 struct files (document, system, network, security, services) covering 50+ top-level config.xml sections; reused 25+ OPNsense types where XML is identical, forked locally at divergence points (NAT inbound, FilterRule, User/bcrypt-hash, DHCPv6) - CLI Integration - Auto-detection via
<pfsense>root element registration with optional--device-type pfsenseoverride flag
Parser Registry Infrastructure:
The implementation delivered functional parser registry infrastructure via init() self-registration, enabling auto-detection of device types by XML root element:
// pkg/parser/pfsense/parser.go
func init() {
parser.Register("pfsense", NewParserFactory)
}
This establishes the pluggable architecture pattern that Issue #302 targets for v2.0.0, demonstrating that registry functionality can coexist with OPNsense's existing hardcoded approach during the transition period.
Security Measures Implemented:
- Shared XML security hardening extracted to
pkg/parser/xmlutil.go(NewSecureXMLDecoder,CharsetReader) with XML bomb protection and XXE prevention - Windows-1252 charset support (pfSense 2.6.x exports) in addition to ISO-8859-1, Latin-1, and UTF-8
- Input size limits and streaming token-based XML parsing for memory efficiency
Test Coverage:
- 1200+ lines of parser/converter tests covering pfSense 2.6.x and 2.7.x fixtures
- Round-trip parsing, security hardening (XXE, size limit, charset), converter subsystems (system, network, security, services)
- Integration tests verify end-to-end pfSense config processing with JSON, YAML, and markdown output formats
- Factory auto-detection tests verify
<pfsense>vs<opnsense>root element dispatch
Documentation:
pkg/schema/pfsense/README.mdprovides 838-line structural reference documenting all 50+ top-level sections, listtags, version mapping, and OPNsense differencesAGENTS.mdandGOTCHAS.mdupdated with pfSense schema guidance, listtag requirements, and repeated XML element gotcha (§3.3)
Status: COMPLETED via PR #459 (March 2026)
Cisco ASA Support (Issue #198)#
While no dedicated issue #198 was found in research, Cisco ASA support is referenced in the device parser registry discussion (Issue #302). The implementation would follow the same multi-device abstraction architecture established for pfSense support.
Fortinet FortiGate Support (Issue #199)#
Like Cisco ASA, FortiGate support is referenced in multi-device architecture planning but lacks a dedicated issue thread. Implementation would follow the established device abstraction pattern with FortiGate-specific parsers and schema mapping.
Status: 1 closed / 3 open issues as of March 2026
Architectural Evolution Strategy#
The opnDossier roadmap represents a carefully sequenced architectural evolution maintaining five core design principles throughout all changes:
- Offline-First — Zero external dependencies for red team operations
- Operator-Focused — CLI-centric workflows unchanged across versions
- Framework-First — Established Go libraries only (no exotic dependencies)
- Structured Data — Configuration hierarchy preserved
- Security-First — No telemetry, strict validation, XXE/XML bomb prevention
Current Architecture (v1.3.0)#
As of v1.3.0 (completed March 2026), the architecture has been restructured with public packages. The pfSense implementation (PR #459, March 2026) extended this structure with the first multi-vendor parser:
pkg/schema/opnsense/— XML DTOs withxml:""tags (OPNsense-specific)pkg/schema/pfsense/— pfSense XML DTOs with device-specific variationspkg/parser/opnsense/— Device-specific parser & converterpkg/parser/pfsense/— pfSense parser & converter with init() registrationpkg/model/— Platform-agnosticCommonDevicemodelpkg/parser/factory.go— Factory for creating device parserspkg/parser/xmlutil.go— Shared XML security utilities (XXE, bomb protection, charset handling)
Data Conversion Pipeline:
- XML → OpnSenseDocument via
internal/cfgparser(OPNsense) - XML → pfsense.Document via
pkg/parser/pfsense/parser.go(pfSense) - OpnSenseDocument → CommonDevice via
pkg/parser/opnsense/converter.go - pfsense.Document → CommonDevice via
pkg/parser/pfsense/converter.go - prepareForExport() enriches with statistics, analysis, redaction
Target Architecture (v2.0+)#
The v2.0+ architecture will build on v1.3.0's public package structure to add registry-based multi-device support:
Public Package Structure (already in place via v1.3.0):
pkg/
├── model/ # Platform-agnostic CommonDevice (public API) ✅
├── schema/opnsense/ # OPNsense XML DTO types (public API) ✅
├── schema/pfsense/ # pfSense XML DTO types (v2.1.0, delivered) ✅
├── parser/ # Parser interfaces + factory (public API) ✅
├── parser/opnsense/ # OPNsense-specific implementation ✅
└── parser/pfsense/ # pfSense-specific implementation (v2.1.0, delivered) ✅
Device Registration Pattern (functional as of pfSense implementation):
// Extensible via init() functions in each parser package
func init() {
parser.Register("opnsense", NewParserFactory) // OPNsense parser (v1.3.0)
parser.Register("pfsense", NewParserFactory) // pfSense parser (v2.1.0) ✅
}
The pfSense implementation demonstrates that init() registration works today, with auto-detection by XML root element. v2.0.0 will formalize this pattern as the canonical approach for all device types.
Key Architectural Differences:
| Aspect | v1.2.1 (Previous) | v1.3.0 (Current) | v2.1.0 (pfSense delivered) | v2.0+ (Target) |
|---|---|---|---|---|
| Package visibility | internal/ only | Public pkg/ APIs | Public pkg/ APIs | Public pkg/ APIs |
| Device support | Hardcoded OPNsense | Hardcoded OPNsense | OPNsense + pfSense (registry) | Registry-based multi-device |
| Re-export layer | 92 type aliases | Eliminated | Eliminated | Eliminated |
| Report generation | Template-based | Template-based | Template-based | Programmatic methods |
| External usage | Not possible | External imports supported | External imports supported | External imports supported |
Dependency Chain and Sequencing#
The roadmap originally envisioned strict sequencing, but the pfSense implementation demonstrates more flexibility:
Original Plan:
v1.3.0 (Public APIs) ✅ COMPLETED
↓ enables
v2.0.0 (Registry pattern + breaking changes)
↓ enables
v2.1.0 (Multi-vendor support: pfSense, Cisco ASA, FortiGate)
Actual Implementation:
v1.3.0 (Public APIs) ✅ COMPLETED (March 2026)
↓ enabled
v2.1.0 pfSense support ✅ COMPLETED (March 2026, PR #459)
↓ demonstrates
Registry pattern functionality (via init() registration)
↓ informs
v2.0.0 (Formalize registry pattern, breaking changes)
↓ enables
v2.1.0 continuation (Cisco ASA, FortiGate)
With v1.3.0 complete, pfSense implementation proceeded alongside v2.0.0 planning rather than waiting for Issue #196 (model layer refactoring) and Issue #302 (parser registry) to be fully resolved. This pragmatic approach delivered working multi-vendor support via init() registration while proving the registry architecture works in practice, which will inform the formal v2.0.0 registry implementation. Future vendor implementations (Cisco ASA, FortiGate) can follow the pfSense template immediately.
Release Strategy and Process#
Semantic Versioning Policy#
opnDossier follows strict semantic versioning (SemVer):
- MAJOR (X.0.0): Incompatible API changes, breaking CLI interface, config format changes
- MINOR (0.X.0): New functionality, backward-compatible additions
- PATCH (0.0.X): Bug fixes, documentation, performance improvements without behavioral changes
Release Timeline Philosophy#
The project does not commit to specific release dates. Instead, it uses milestone-based planning where features are completed when ready, with quality and stability prioritized over deadlines. Only v1.0 had an informal target of "Tonight", which was successfully met on 2025-08-04.
Automated Release Process#
The project uses comprehensive release automation:
Pre-Release Validation:
- Full test suite via
just ci-full - Security scanning (govulncheck, CodeQL, Trivy)
- Snapshot builds for validation
Release Execution:
- Automated changelog generation via
git-cliffwith conventional commits - Version tagging with
git tag -a vX.Y.Z - GoReleaser handles multi-platform binaries (Linux, macOS, Windows)
- Docker image generation and registry push
- SBOM generation in SPDX format
- Cosign keyless artifact signing
- SLSA Level 3 provenance attestation
Security Features:
- Comprehensive dependency scanning prevents vulnerable dependencies
- Software Bill of Materials (SBOM) for supply chain transparency
- Cryptographic signing enables artifact verification
- SLSA provenance provides build integrity attestation
Breaking Change Migration#
v2.0.0 Migration Strategy:
-
v1.3.0 Preparation Phase: ✅ COMPLETED
- ✅ Exposed public APIs via
pkg/packages - ✅ Eliminated re-export layer entirely (direct cutover)
- ✅ Updated documentation and developer guides
- ✅ Exposed public APIs via
-
v2.0.0 Breaking Phase:
- Implement registry-based parser factory
- Add multi-device parser registration
- Convert to programmatic report generation
- Provide
UPGRADE_v2.mdmigration guide - Offer optional
gofmt -rrewrite rules for automated migration
-
v2.x+ Deprecation Phase:
- Deprecation warnings for template usage (if retained)
- Progressive feature sunsetting with advance notice
- Community feedback loop for migration pain points
Historical Context and Past Releases#
Released Versions#
Based on the CHANGELOG.md, the project has achieved the following releases:
- v1.0.0 - Released 2025-08-04 (Essential CLI tool with core OPNsense parsing)
- v1.0.0-rc1 - Released 2025-08-01 (Release candidate)
- v1.2.1 - Released 2026-02-12
- v1.3.0 - Completed March 2026 via PR #404 (Public package migration)
Version History Summary#
The project documentation references conceptual version milestones:
- v1.0: Essential CLI tool (core parsing, conversion, offline operation)
- v1.1: Advanced analysis & audit reports (compliance, multi-mode reporting, STIG/SANS)
- v1.2: Performance & enterprise features (concurrent processing, optimization, plugins)
- v1.3: Public package migration (external consumption enabled)
- v2.0: Major architectural changes (registry pattern, programmatic generation)
- v2.1+: Compliance features and multi-vendor expansion
Relevant Code Files#
The following code files are central to understanding the roadmap implementation:
| File Path | Purpose | Roadmap Relevance |
|---|---|---|
| pkg/parser/factory.go | Factory for creating device parsers (renamed from ParserFactory) | v1.3.0: Public API exposed; v2.1.0: pfSense registration added; v2.0.0: Will formalize registry pattern |
| pkg/model/ | Platform-agnostic CommonDevice domain model | v1.3.0: Moved from internal/model/common/ to public API |
| pkg/parser/opnsense/ | OPNsense-specific parser and converter | v1.3.0: Moved from internal/model/opnsense/ to public API |
| pkg/parser/pfsense/ | pfSense-specific parser and converter | v2.1.0: First multi-vendor implementation with init() registration |
| pkg/schema/opnsense/ | OPNsense XML DTOs with xml: tags | v1.3.0: Moved from internal/schema/ to public API |
| pkg/schema/pfsense/ | pfSense XML DTOs with device-specific variations | v2.1.0: Created for pfSense support, reuses OPNsense types where identical |
| pkg/parser/xmlutil.go | Shared XML security utilities (XXE, bomb protection, charset handling) | v2.1.0: Extracted from OPNsense parser to enable pfSense reuse |
| internal/cfgparser/xml.go | XML parsing with security measures (XXE, bomb protection) | Template for pfSense parser security implementation |
| internal/converter/enrichment.go | Configuration enrichment with statistics and analysis | Device-agnostic processing for multi-vendor support |
| internal/validator/pfsense.go | pfSense-specific semantic validation | v2.1.0: Validator created for pfSense configs |
| .goreleaser.yaml | Release automation configuration | Defines multi-platform builds, Docker images, SBOM, signing |
| RELEASING.md | Release process documentation | Documents SemVer policy, automation steps, security features |
| CHANGELOG.md | Version history and changes | Auto-generated via git-cliff with conventional commits |
Related Topics#
- Architecture Documentation - Core design principles and layered architecture
- Package Restructuring Roadmap - Detailed v1.3.0 implementation plan
- CommonDevice Export Model vs OpnSenseDocument XML Schema - Structural differences between layers
- Semantic Versioning (SemVer) - Industry-standard versioning scheme used by opnDossier
- SARIF (Static Analysis Results Interchange Format) - Standard format for SIEM integration
- SLSA (Supply-chain Levels for Software Artifacts) - Framework for build integrity attestation
- Software Bill of Materials (SBOM) - Transparency for supply chain security