Roadmap
Capability plan by area and release target
This roadmap tracks capability work — what already exists, what is being built, and why each piece matters for a self-hosted TLS-inspection edge. It is a technical reading order, not a ticket dump: the living, tickable version of every item lives on the OpenSASE Roadmap project board (linked to this repo; each card carries an Area (component) and a Target grouping).
Targets (v0.1.x, v0.2.x, Later) are sequencing, not commitments — there are no dates. Security-sensitive work follows the verdict order passlist → bumplist → default bump: nothing on this page changes that posture without a documented rationale and decision-log evidence (see Contributing).
Snapshot
Plan of record
Scope for the next two releases, refreshed 2026-10-22. The full listing, including later targets and parked directions, lives on the OpenSASE Roadmap project board.
| Target | # | Item | Area |
|---|---|---|---|
| v0.1.x | #8 | Images: publish multi-arch (amd64 + arm64) GHCR images | images |
| v0.1.x | #11 | VPN: certificate renewal / rotation workflow (vpn-renew, expiry checks, client re-export) | vpn & pki |
| v0.1.x | #15 | Policy: fail-mode verdict test suite (splice / bump / INFECTED decision-log samples) | policy & inspection |
| v0.1.x | #25 | DNS-layer policy: dnsmasq RPZ + query logging into the decision log | home-appliance |
| v0.2.x | #9 | Images: cosign signing + provenance attestations in the release pipeline | release & supply-chain |
| v0.2.x | #10 | Kubernetes: ship prebuilt kustomize manifests + deployment docs | kubernetes |
| v0.2.x | #14 | Policy: remote category-list feeds with signed updates + hot reload | policy & inspection |
| v0.2.x | #16 | Observability: decision-log export + metrics endpoint | observability |
| v0.2.x | #19 | Home appliance: per-device policy + family visibility (Pi-hole-plus) | home-appliance |
| v0.2.x | #20 | Agent traffic: MCP tool calls as a first-class policy category | agent & ai traffic |
| v0.2.x | #21 | LLM provider egress: per-device authorization + counters (lightweight) | agent & ai traffic |
| v0.2.x | #22 | QUIC / HTTP-3: fail-closed first, then interception parity | policy & inspection |
| v0.2.x | #23 | Identity: step-ca integration — short-lived device certs, passive revocation | vpn & pki |
| v0.2.x | #26 | DLP verdicts: LEAK_BLOCK joins INFECTED (secret/credential egress) | policy & inspection |
| v0.2.x | #27 | Chat: Prosody XMPP server + inspection component (family chat on the edge) | chat (xmpp) |
| v0.2.x | #29 | Packaging: compose profiles — bare-minimum decrypt vs full appliance | home-appliance |
Status meaning: Todo is planned (open issue), In Progress is underway, and Done is merged and shipped. Closed issues drop off the table automatically; the board remains the working tracker between deploys.
Release & supply-chain
The release pipeline shipped. On a v* tag, CI Nix-builds all four images, runs the compose smoke gate (clamd verdicts plus decision-log assertions against the freshly built images), and only then pushes to GHCR, records digests, attaches SPDX SBOMs, verifies the tag signature, and opens a release with a digest table and changelog. v0.1.1 was cut this way, after rehearsing the full pipeline with workflow_dispatch six times. Those rehearsals surfaced and fixed seven image-runtime defects before any tag was cut.
Signing already covers source: commits are signed, releases are signed tags, SBOMs are attached. #9 extends that to the artifacts themselves — keyless cosign signatures and provenance attestations on every published image, so consumers can verify in-registry rather than trusting the registry.
Multi-arch images
release-images.yml currently builds on amd64 runners and pushes single-arch images. On Apple Silicon or Arm servers — the most common self-hosting hardware this project will meet — that means emulation or failure. #8 publishes proper amd64 + arm64 manifest lists — the same flake produces both arches, byte-identical from source, with no Docker cross-build layer.
Kubernetes
The base manifest layer exists and is declarative: k8s/manifests.cue (CUE, single service model shared with nix/images.nix) renders PVCs, Services, and Deployments for all four services via nix run .#k8s-manifests — committed output at k8s/manifests.yaml (kubectl apply -f). What remains is the hardening overlay: #10 adds PKI Secret injection, readiness gates on the VPN’s server.conf, and the deployment page (bootstrap order, security contexts per service).
VPN & PKI
The PKI tooling is declarative end to end: nix run .#vpn-init bootstraps the CA (nix/easyrsa3), and nix run .#vpn-getclient -- <cn> exports a per-device profile — no legacy service scripts. What is missing is the lifecycle: #11 adds renewal/rotation (the tls-auth HMAC failures in issue #3 are exactly what an un-re-provisioned client looks like after a server-side renewal), an expiry-check command, and documentation of what clients must re-provision after each operation type.
Two items sit behind external or architectural gates:
- #12 flips the default to
tls-cryptonce OpenVPN Connect for iOS supports it. Until thentls-authstays, and client profiles carry the static key in a<tls-auth>block. - #13 brings up IPv6. This is not a checkbox: on a TLS-inspection edge, a v6 path that bypasses the splice/bump/scan chain is a policy leak — inspection evades the verdict pipeline entirely. The fail-closed option (block v6 egress when v6 interception is not configured) is part of the feature, not an afterthought.
Policy & inspection
Policy lists (passlist / bumplist) are baked into the mitmproxy image at build time. That is correct for a sealed appliance and stale for an ops-driven edge, where category sets change on ops timescales, not release timescales. #14 adds subscription feeds with detached signatures, verified fail-closed before acceptance, and hot reload — deliberately designed so the trust boundary moves with the feature rather than around it.
#15 closes the enforcement gap: Contributing already requires policy-posture changes to state the verdict order and include decision-log samples, but nothing automated enforces it. A suite that drives real traffic through the edge and asserts on decisions.jsonl content — splice, bump, INFECTED, fail-closed — makes the posture CI-gated. Self-contained; suitable as a first contribution.
Observability
Every verdict is written to a local JSONL decision log — accurate, and invisible the moment you run more than one edge. #16 adds export and a metrics endpoint: verdict counters, scan-latency histograms, infected-blocked totals, plus log rotation (decision-log growth is currently unbounded). The objective is fleet-operable telemetry rather than container-local logging.
Requesting changes
Priorities respond to use cases:
- Re-prioritize an existing item: comment on its issue with the use case. Use-case comments move Targets; “+1” comments are not weighted.
- Design input is open on: #13 (IPv6 deployment assumptions), #14 (feed format), #16 (export/telemetry sinks).
- Propose new scope: open an issue and follow the scope conventions in Contributing (
feat(scope): subject, one change per branch). - Security-sensitive proposals are not feature requests — anything that looks like a vulnerability goes through Security, never a public issue.