{"id":48305763,"url":"https://github.com/rchiofalo/rustgate","last_synced_at":"2026-04-05T00:02:04.686Z","repository":{"id":345643300,"uuid":"1156777945","full_name":"rchiofalo/rustgate","owner":"rchiofalo","description":"Secure mTLS message router in Rust — group-based routing, WebSocket, server federation, NATS scaling, certificate enrollment, CRL/FIPS support. Single binary, edge-ready.","archived":false,"fork":false,"pushed_at":"2026-03-31T07:56:08.000Z","size":834,"stargazers_count":1,"open_issues_count":87,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-03-31T08:30:27.671Z","etag":null,"topics":["certificate-enrollment","crl","cursor-on-target","federation","fips","helm","kubernetes","message-router","mtls","nats","rust","websocket"],"latest_commit_sha":null,"homepage":null,"language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/rchiofalo.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":".github/CODEOWNERS","security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-02-13T03:22:15.000Z","updated_at":"2026-03-31T07:56:10.000Z","dependencies_parsed_at":null,"dependency_job_id":"b688fcf2-3984-4f38-bb84-4d4fcb5a8e43","html_url":"https://github.com/rchiofalo/rustgate","commit_stats":null,"previous_names":["rchiofalo/rustgate"],"tags_count":6,"template":false,"template_full_name":null,"purl":"pkg:github/rchiofalo/rustgate","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rchiofalo%2Frustgate","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rchiofalo%2Frustgate/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rchiofalo%2Frustgate/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rchiofalo%2Frustgate/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/rchiofalo","download_url":"https://codeload.github.com/rchiofalo/rustgate/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rchiofalo%2Frustgate/sbom","scorecard":{"id":1245072,"data":{"date":"2026-03-20T08:39:35Z","repo":{"name":"github.com/rchiofalo/rustgate","commit":"72d89a37d1742d218fb665641d26209f6ea6e111"},"scorecard":{"version":"v5.3.0","commit":"c22063e786c11f9dd714d777a687ff7c4599b600"},"score":6.9,"checks":[{"name":"Dependency-Update-Tool","score":10,"reason":"update tool detected","details":["Info: detected update tool: Dependabot: .github/dependabot.yml:1"],"documentation":{"short":"Determines if the project uses a dependency update tool.","url":"https://github.com/ossf/scorecard/blob/c22063e786c11f9dd714d777a687ff7c4599b600/docs/checks.md#dependency-update-tool"}},{"name":"Code-Review","score":0,"reason":"Found 0/21 approved changesets -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/c22063e786c11f9dd714d777a687ff7c4599b600/docs/checks.md#code-review"}},{"name":"Dangerous-Workflow","score":10,"reason":"no dangerous workflow patterns detected","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/c22063e786c11f9dd714d777a687ff7c4599b600/docs/checks.md#dangerous-workflow"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/c22063e786c11f9dd714d777a687ff7c4599b600/docs/checks.md#binary-artifacts"}},{"name":"Security-Policy","score":10,"reason":"security policy file detected","details":["Info: security policy file detected: SECURITY.md:1","Info: Found linked content: SECURITY.md:1","Info: Found disclosure, vulnerability, and/or timelines in security policy: SECURITY.md:1","Info: Found text in security policy: SECURITY.md:1"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/c22063e786c11f9dd714d777a687ff7c4599b600/docs/checks.md#security-policy"}},{"name":"Maintained","score":0,"reason":"project was created within the last 90 days. Please review its contents carefully","details":["Warn: Repository was created within the last 90 days."],"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/c22063e786c11f9dd714d777a687ff7c4599b600/docs/checks.md#maintained"}},{"name":"Token-Permissions","score":10,"reason":"GitHub workflow tokens follow principle of least privilege","details":["Info: jobLevel 'actions' permission set to 'read': .github/workflows/codeql.yml:22","Info: jobLevel 'contents' permission set to 'read': .github/workflows/codeql.yml:20","Info: jobLevel 'contents' permission set to 'read': .github/workflows/nightly.yml:19","Info: jobLevel 'contents' permission set to 'read': .github/workflows/nightly.yml:45","Warn: jobLevel 'contents' permission set to 'write': .github/workflows/release-binary.yml:22","Warn: jobLevel 'contents' permission set to 'write': .github/workflows/release-binary.yml:90","Info: jobLevel 'actions' permission set to 'read': .github/workflows/release-binary.yml:91","Info: jobLevel 'actions' permission set to 'read': .github/workflows/release.yml:24","Info: jobLevel 'contents' permission set to 'read': .github/workflows/release.yml:26","Info: jobLevel 'actions' permission set to 'read': .github/workflows/scorecard.yml:21","Info: jobLevel 'contents' permission set to 'read': .github/workflows/scorecard.yml:18","Info: topLevel 'contents' permission set to 'read': .github/workflows/ci.yml:11","Info: topLevel 'contents' permission set to 'read': .github/workflows/codeql.yml:13","Info: topLevel 'contents' permission set to 'read': .github/workflows/nightly.yml:10","Info: topLevel 'contents' permission set to 'read': .github/workflows/release-binary.yml:14","Info: topLevel 'contents' permission set to 'read': .github/workflows/release.yml:14","Info: topLevel permissions set to 'read-all': .github/workflows/scorecard.yml:10"],"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/c22063e786c11f9dd714d777a687ff7c4599b600/docs/checks.md#token-permissions"}},{"name":"Pinned-Dependencies","score":10,"reason":"all dependencies are pinned","details":["Info:  24 out of  24 GitHub-owned GitHubAction dependencies pinned","Info:  13 out of  13 third-party GitHubAction dependencies pinned","Info:   2 out of   2 containerImage dependencies pinned"],"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/c22063e786c11f9dd714d777a687ff7c4599b600/docs/checks.md#pinned-dependencies"}},{"name":"License","score":9,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Warn: project license file does not contain an FSF or OSI license."],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/c22063e786c11f9dd714d777a687ff7c4599b600/docs/checks.md#license"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/c22063e786c11f9dd714d777a687ff7c4599b600/docs/checks.md#cii-best-practices"}},{"name":"Signed-Releases","score":0,"reason":"Project has not signed or included provenance with any releases.","details":["Warn: release artifact v0.4.0 not signed: https://api.github.com/repos/rchiofalo/rustgate/releases/294127714","Warn: release artifact v0.3.0 not signed: https://api.github.com/repos/rchiofalo/rustgate/releases/293783173","Warn: release artifact v0.2.0 not signed: https://api.github.com/repos/rchiofalo/rustgate/releases/292311251","Warn: release artifact v0.4.0 does not have provenance: https://api.github.com/repos/rchiofalo/rustgate/releases/294127714","Warn: release artifact v0.3.0 does not have provenance: https://api.github.com/repos/rchiofalo/rustgate/releases/293783173","Warn: release artifact v0.2.0 does not have provenance: https://api.github.com/repos/rchiofalo/rustgate/releases/292311251"],"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/c22063e786c11f9dd714d777a687ff7c4599b600/docs/checks.md#signed-releases"}},{"name":"Fuzzing","score":10,"reason":"project is fuzzed","details":["Info: RustCargoFuzzer integration found: fuzz/fuzz_targets/cot_parse.rs:3","Info: RustCargoFuzzer integration found: fuzz/fuzz_targets/length_prefixed_codec.rs:3","Info: RustCargoFuzzer integration found: fuzz/fuzz_targets/tak_frame_codec.rs:3","Info: RustCargoFuzzer integration found: fuzz/fuzz_targets/v2_federation_convert.rs:3","Info: RustCargoFuzzer integration found: fuzz/fuzz_targets/xml_stream_codec.rs:3"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/c22063e786c11f9dd714d777a687ff7c4599b600/docs/checks.md#fuzzing"}},{"name":"Packaging","score":10,"reason":"packaging workflow detected","details":["Info: Project packages its releases by way of GitHub Actions.: .github/workflows/ci.yml:177"],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/c22063e786c11f9dd714d777a687ff7c4599b600/docs/checks.md#packaging"}},{"name":"Vulnerabilities","score":9,"reason":"1 existing vulnerabilities detected","details":["Warn: Project is vulnerable to: RUSTSEC-2025-0134"],"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/c22063e786c11f9dd714d777a687ff7c4599b600/docs/checks.md#vulnerabilities"}},{"name":"Branch-Protection","score":-1,"reason":"internal error: error during branchesHandler.setup: internal error: some github tokens can't read classic branch protection rules: https://github.com/ossf/scorecard-action/blob/main/docs/authentication/fine-grained-auth-token.md","details":null,"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/c22063e786c11f9dd714d777a687ff7c4599b600/docs/checks.md#branch-protection"}},{"name":"SAST","score":7,"reason":"SAST tool detected but not run on all commits","details":["Info: SAST configuration detected: CodeQL","Warn: 1 commits out of 25 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/c22063e786c11f9dd714d777a687ff7c4599b600/docs/checks.md#sast"}},{"name":"Contributors","score":0,"reason":"project has 0 contributing companies or organizations -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project has a set of contributors from multiple organizations (e.g., companies).","url":"https://github.com/ossf/scorecard/blob/c22063e786c11f9dd714d777a687ff7c4599b600/docs/checks.md#contributors"}},{"name":"CI-Tests","score":10,"reason":"25 out of 25 merged PRs checked by a CI test -- score normalized to 10","details":null,"documentation":{"short":"Determines if the project runs tests before pull requests are merged.","url":"https://github.com/ossf/scorecard/blob/c22063e786c11f9dd714d777a687ff7c4599b600/docs/checks.md#ci-tests"}}]},"last_synced_at":"2026-03-21T07:41:56.188Z","repository_id":345643300,"created_at":"2026-03-21T07:41:56.188Z","updated_at":"2026-03-21T07:41:56.188Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31419549,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-04T20:09:54.854Z","status":"ssl_error","status_checked_at":"2026-04-04T20:09:44.350Z","response_time":60,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["certificate-enrollment","crl","cursor-on-target","federation","fips","helm","kubernetes","message-router","mtls","nats","rust","websocket"],"created_at":"2026-04-05T00:01:15.356Z","updated_at":"2026-04-05T00:02:04.674Z","avatar_url":"https://github.com/rchiofalo.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cp align=\"center\"\u003e\n  \u003cimg src=\"assets/logo.svg\" alt=\"rustgate logo\" width=\"600\"\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://github.com/rchiofalo/rustgate/actions/workflows/ci.yml\"\u003e\u003cimg src=\"https://github.com/rchiofalo/rustgate/actions/workflows/ci.yml/badge.svg\" alt=\"CI\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://github.com/rchiofalo/rustgate/releases/latest\"\u003e\u003cimg src=\"https://img.shields.io/github/v/release/rchiofalo/rustgate?color=green\" alt=\"Release\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://ghcr.io/rchiofalo/rustgate\"\u003e\u003cimg src=\"https://img.shields.io/badge/docker-ghcr.io-blue?logo=docker\" alt=\"Docker\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://securityscorecards.dev/viewer/?uri=github.com/rchiofalo/rustgate\"\u003e\u003cimg src=\"https://api.securityscorecards.dev/projects/github.com/rchiofalo/rustgate/badge\" alt=\"OpenSSF Scorecard\"\u003e\u003c/a\u003e\n  \u003cimg src=\"https://img.shields.io/badge/rust-1.93%2B-orange.svg?logo=rust\" alt=\"Rust 1.93+\"\u003e\n  \u003cimg src=\"https://img.shields.io/badge/license-Proprietary-blue.svg\" alt=\"License\"\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003cem\u003eSecure mTLS message router in Rust — group-based routing, WebSocket, server federation, NATS scaling, certificate enrollment, CRL and FIPS support. Single binary, edge-ready.\u003c/em\u003e\n\u003c/p\u003e\n\n## Table of Contents\n\n- [Why](#why)\n- [Quick Start](#quick-start)\n- [Architecture](#architecture)\n- [Features](#features)\n- [Prerequisites](#prerequisites)\n- [Building](#building)\n- [Running](#running)\n- [Docker](#docker)\n- [Kubernetes](#kubernetes)\n- [Security](#security)\n- [Testing](#testing)\n- [Documentation](#documentation)\n- [Contributing](#contributing)\n- [License](#license)\n\n## Why\n\nExisting messaging servers are Java monoliths requiring 8 GB+ RAM, multiple JVM processes, and complex module stacks. They work in fixed infrastructure but fall apart at the edge where resources are constrained and reliability matters most. Federation-only alternatives exist but don't handle client connections.\n\nrustgate is a lightweight alternative that handles mTLS client connections, routes messages by group membership derived from client certificates, and exposes a pluggable protocol interface. Pure Rust, single binary, minimal footprint.\n\n## Quick Start\n\nGenerate test certificates and run with Docker Compose:\n\n```bash\n# Generate CA\nopenssl req -x509 -newkey rsa:4096 -keyout ca-key.pem -out ca.pem \\\n  -days 365 -nodes -subj \"/CN=rustgate-ca\"\n\n# Generate server cert\nopenssl req -newkey rsa:4096 -keyout server-key.pem -out server.csr \\\n  -nodes -subj \"/CN=rustgate-server\"\nopenssl x509 -req -in server.csr -CA ca.pem -CAkey ca-key.pem \\\n  -CAcreateserial -out server.pem -days 365\n\n# Place certs where Docker Compose expects them\nmkdir -p certs\ncp ca.pem certs/ca.crt \u0026\u0026 cp server.pem certs/server.crt \u0026\u0026 cp server-key.pem certs/server.key\n\n# Start\ndocker compose up -d\n\n# Verify\ncurl http://localhost:9090/healthz\n```\n\nFor production certificate management see [docs/tls-certificates.md](docs/tls-certificates.md).\n\n## Architecture\n\n```\n┌─────────────────────────────────────────────────────────────────────────────────────────┐\n│                                     rustgate-server                                     │\n│                                        (binary)                                         │\n├──────────────┬──────────────┬──────────────┬──────────────┬──────────────┬──────────────┤\n│  rustgate-   │  rustgate-   │  rustgate-   │  rustgate-   │  rustgate-   │  rustgate-   │\n│  transport   │  websocket   │  nats        │  enrollment  │  proto       │  federation  │\n│  TLS·codec   │  wss://mTLS  │  NATS pubsub │  HTTPS·CSR   │  protobuf    │  V1·V2·gRPC  │\n│  router      │  WS sessions │  JetStream   │  Basic Auth  │  XML/proto   │  peer mgmt   │\n├──────────────┴──────────────┴──────────────┼──────────────┴──────────────┴──────────────┤\n│                rustgate-cot                │               rustgate-core                │\n│      CoT XML parsing · MessageBuilder      │    Codec trait · Identity · RoutableMessage│\n└────────────────────────────────────────────┴────────────────────────────────────────────┘\n```\n\n| Crate | Purpose |\n|-------|---------|\n| `rustgate-core` | Codec trait, shared types: Identity, RoutableMessage, Destination, framing strategies |\n| `rustgate-cot` | Cursor on Target XML parsing and message building |\n| `rustgate-transport` | mTLS listener, codec, session management, CRL, FIPS provider, routing engine |\n| `rustgate-websocket` | WebSocket (wss://) listener with mTLS client authentication |\n| `rustgate-nats` | NATS/JetStream bridge for cross-instance message delivery |\n| `rustgate-enrollment` | HTTPS certificate enrollment server (CSR signing, PKCS#12) |\n| `rustgate-proto` | Protobuf message translation (XML ↔ proto) |\n| `rustgate-federation` | Server-to-server federation: V1 (XML), V2 (gRPC), HA, REST API |\n| `rustgate-server` | Binary entry point, CLI, orchestration |\n| `rustgate-test-utils` | Test CA and certificate generation helpers |\n\nFor detailed architecture documentation see [docs/architecture.md](docs/architecture.md).\n\n## Features\n\n### Transport \u0026 Routing\n\n| Feature | Description |\n|---------|-------------|\n| mTLS | Mutual TLS with client certificate authentication |\n| Identity extraction | CN → callsign, OU → groups, SHA-256 → fingerprint |\n| Group routing | Broadcast, group, and direct message delivery |\n| Codecs | Length-prefixed, XML stream, and line-delimited codecs |\n| Position cache | Replay cached positions on client connect |\n| Rate limiting | Per-client message rate and burst controls |\n| Plaintext input | TCP and UDP listeners for trusted-network scenarios |\n\n### Protocols \u0026 Codecs\n\n| Feature | Description |\n|---------|-------------|\n| WebSocket | wss:// listener with mTLS, interoperable with TCP clients |\n| Protobuf | Bidirectional XML ↔ protobuf translation |\n| Protocol negotiation | Automatic upgrade from XML to protobuf framing |\n| CoT archival | Structured JSONL logging of all received events |\n| Data packages | Upload, download, and search via Marti sync API |\n\n### Security\n\n| Feature | Description |\n|---------|-------------|\n| CRL revocation | PEM-encoded CRL loaded via `--crl`, enforced at TLS handshake |\n| FIPS 140-3 | aws-lc-rs crypto provider via `--features fips` ([details](docs/fips.md)) |\n| Subject DN enforcement | Enrollment certs carry the authenticated username — prevents impersonation |\n| No unsafe code | `unsafe_code = \"forbid\"` workspace-wide |\n| Container hardening | Non-root UID, read-only filesystem, STOPSIGNAL SIGTERM |\n\n### Federation \u0026 Scaling\n\n| Feature | Description |\n|---------|-------------|\n| Federation V1 | Length-prefixed XML over mTLS |\n| Federation V2 | gRPC over mTLS with FederatedChannel service |\n| Loop detection | Provenance-based with configurable hop limits |\n| HA mode | NATS KV distributed claims for multi-pod peer ownership |\n| NATS bridge | Publish/subscribe for stateless horizontal scaling with JetStream replay |\n| REST API | Peer CRUD and certificate management endpoints |\n\n### Operations\n\n| Feature | Description |\n|---------|-------------|\n| Prometheus metrics | Connection lifecycle, message routing, NATS, federation ([unauthenticated](docs/deployment.md#ports) — firewall in hostile environments) |\n| OpenTelemetry tracing | Distributed trace export via OTLP (Jaeger, Tempo, etc.) |\n| Health endpoints | `/healthz` (liveness), `/readyz` (readiness) |\n| Graceful shutdown | SIGTERM handling, readiness 503, connection draining |\n| Helm chart | Pod Security Standards, PDB, HPA, probes, NetworkPolicy |\n| Docker Compose | Local development stack with NATS and JetStream |\n| jemalloc | Optional allocator for musl/Alpine production builds |\n\n## Prerequisites\n\n| Dependency | Required | Notes |\n|------------|----------|-------|\n| Rust 1.93+ | Yes | Pinned in `rust-toolchain.toml` (edition 2024) |\n| Rust nightly | Yes | For `cargo +nightly fmt` (CI enforces nightly formatting) |\n| protoc | For `proto` / `federation` features | Protocol Buffers compiler |\n| Go 1.20+, cmake | For `fips` feature | Required by aws-lc-rs build system |\n| nats-server | For NATS integration tests | Install from [nats.io](https://nats.io/download/) |\n\nOptional tooling:\n\n| Tool | Purpose |\n|------|---------|\n| [cargo-nextest](https://nexte.st/) | CI test runner |\n| [cargo-hack](https://github.com/taiki-e/cargo-hack) | Feature powerset checking |\n| [cargo-deny](https://github.com/EmbarkStudios/cargo-deny) | License and advisory auditing |\n| [cargo-machete](https://github.com/bnjbvr/cargo-machete) | Unused dependency detection |\n| Helm | Chart linting |\n\n## Building\n\n```bash\n# Default (core transport + routing)\ncargo build --release\n\n# With individual features\ncargo build --release --features nats           # NATS bridge\ncargo build --release --features enrollment     # Certificate enrollment\ncargo build --release --features proto          # Protobuf translation (needs protoc)\ncargo build --release --features federation     # Server federation (needs protoc)\ncargo build --release --features websocket      # WebSocket listener\ncargo build --release --features metrics        # Prometheus + health endpoints\ncargo build --release --features jemalloc       # jemalloc allocator (musl)\ncargo build --release --features fips           # FIPS 140-3 crypto (needs Go + cmake)\ncargo build --release --features otel           # OpenTelemetry tracing (needs protoc)\n\n# All features\ncargo build --release --all-features\n```\n\n### Feature Flags\n\n| Feature | Purpose | Extra build deps |\n|---------|---------|-----------------|\n| `nats` | NATS/JetStream bridge | — |\n| `enrollment` | PKCS#12 enrollment server | — |\n| `proto` | Protobuf message support | `protoc` |\n| `federation` | Server-to-server federation | `protoc` |\n| `federation-ha` | HA federation with JWT | `protoc` |\n| `websocket` | WebSocket transport | — |\n| `metrics` | Prometheus metrics | — |\n| `full-detail` | Extended CoT parsing | — |\n| `fips` | FIPS 140-3 crypto (aws-lc-rs) | Go 1.20+, cmake |\n| `otel` | OpenTelemetry distributed tracing | `protoc` |\n| `jemalloc` | jemalloc allocator | — |\n\n## Running\n\nMinimal:\n\n```bash\nrustgate --cert server.pem --key server-key.pem --ca ca.pem\n```\n\nFull setup:\n\n```bash\nrustgate \\\n  --cert server.pem --key server-key.pem --ca ca.pem \\\n  --crl revoked.pem --fips-required \\\n  --websocket-bind 0.0.0.0:8443 \\\n  --nats-url nats://localhost:4222 \\\n  --metrics-bind 0.0.0.0:9090 \\\n  --federation-v1-bind 0.0.0.0:9000 \\\n  --federation-v2-bind 0.0.0.0:9001 \\\n  --framing tak-negotiate\n```\n\n\u003cdetails\u003e\n\u003csummary\u003eAll configuration flags\u003c/summary\u003e\n\nAll flags support environment variables (CLI takes precedence):\n\n| Flag | Env Var | Default |\n|------|---------|---------|\n| `--bind` | `RUSTGATE_BIND` | `0.0.0.0:4433` |\n| `--cert` | `RUSTGATE_CERT` | — |\n| `--key` | `RUSTGATE_KEY` | — |\n| `--ca` | `RUSTGATE_CA` | — |\n| `--crl` | `RUSTGATE_CRL` | — |\n| `--crl-warn-stale` | `RUSTGATE_CRL_WARN_STALE` | `true` |\n| `--tls-min-version` | `RUSTGATE_TLS_MIN_VERSION` | `1.2` |\n| `--cert-reload-interval` | `RUSTGATE_CERT_RELOAD_INTERVAL` | `0` (disabled) |\n| `--max-concurrent-handshakes` | `RUSTGATE_MAX_HANDSHAKES` | `100` |\n| `--fips-required` | `RUSTGATE_FIPS_REQUIRED` | `false` |\n| `--framing` | `RUSTGATE_FRAMING` | `xml` |\n| `--encoding` | `RUSTGATE_ENCODING` | `raw` |\n| `--max-connections` | `RUSTGATE_MAX_CONNECTIONS` | `1024` |\n| `--tcp-bind` | `RUSTGATE_TCP_BIND` | — |\n| `--udp-bind` | `RUSTGATE_UDP_BIND` | — |\n| `--plaintext-cn` | `RUSTGATE_PLAINTEXT_CN` | `anonymous` |\n| `--plaintext-group` | `RUSTGATE_PLAINTEXT_GROUP` | `__plaintext__` |\n| `--metrics-bind` | `RUSTGATE_METRICS_BIND` | — |\n| `--nats-url` | `RUSTGATE_NATS_URL` | — |\n| `--nats-credentials` | `RUSTGATE_NATS_CREDENTIALS` | — |\n| `--nats-tls-cert` | `RUSTGATE_NATS_TLS_CERT` | — |\n| `--nats-tls-key` | `RUSTGATE_NATS_TLS_KEY` | — |\n| `--nats-tls-ca` | `RUSTGATE_NATS_TLS_CA` | — |\n| `--nats-tls-required` | `RUSTGATE_NATS_TLS_REQUIRED` | `false` |\n| `--websocket-bind` | `RUSTGATE_WEBSOCKET_BIND` | — |\n| `--enrollment-bind` | `RUSTGATE_ENROLLMENT_BIND` | — |\n| `--ca-key` | `RUSTGATE_CA_KEY` | — |\n| `--enrollment-user` | `RUSTGATE_ENROLLMENT_USER` | — |\n| `--enrollment-password` | `RUSTGATE_ENROLLMENT_PASSWORD` | — |\n| `--ca-organization` | `RUSTGATE_CA_ORG` | `rustgate` |\n| `--data-package-dir` | `RUSTGATE_DATA_PACKAGE_DIR` | — |\n| `--federation-v1-bind` | `RUSTGATE_FEDERATION_V1_BIND` | — |\n| `--federation-v2-bind` | `RUSTGATE_FEDERATION_V2_BIND` | — |\n| `--federation-id` | `RUSTGATE_FEDERATION_ID` | `rustgate-federation-1` |\n| `--federation-peers-file` | `RUSTGATE_FEDERATION_PEERS_FILE` | — |\n| `--federation-skip-hostname-verify` | `RUSTGATE_FEDERATION_SKIP_HOSTNAME_VERIFY` | `false` |\n| `--federation-max-hops` | `RUSTGATE_FEDERATION_MAX_HOPS` | `10` |\n| `--federation-store-path` | `RUSTGATE_FEDERATION_STORE_PATH` | — |\n| `--federation-trust-store-dir` | `RUSTGATE_FEDERATION_TRUST_STORE_DIR` | — |\n| `--federation-circuit-breaker-threshold` | `RUSTGATE_FEDERATION_CIRCUIT_BREAKER_THRESHOLD` | `5` |\n| `--federation-circuit-breaker-timeout` | `RUSTGATE_FEDERATION_CIRCUIT_BREAKER_TIMEOUT` | `60` |\n| `--federation-pod-id` | `RUSTGATE_FEDERATION_POD_ID` | — |\n| `--replay-window` | `RUSTGATE_REPLAY_WINDOW` | `300` |\n| `--client-message-rate` | `RUSTGATE_CLIENT_MSG_RATE` | `0` (disabled) |\n| `--client-burst` | `RUSTGATE_CLIENT_BURST` | `200` |\n| `--archive-dir` | `RUSTGATE_ARCHIVE_DIR` | — |\n| `--package-max-age-hours` | `RUSTGATE_PACKAGE_MAX_AGE_HOURS` | `0` (no expiration) |\n| `--otel-endpoint` | `OTEL_EXPORTER_OTLP_ENDPOINT` | — |\n| `--otel-service-name` | `OTEL_SERVICE_NAME` | `rustgate` |\n\n\u003c/details\u003e\n\n## Docker\n\n```bash\ndocker compose up -d\n```\n\nThis starts NATS with JetStream, a one-shot stream setup container, and rustgate on port 4433 with metrics on 9090.\n\nThe Dockerfile builds all features (including jemalloc) in a multi-stage Alpine build. The final image runs as UID 10001 with a read-only root filesystem. Health is checked via `/healthz` on port 9090.\n\nTo build the image standalone:\n\n```bash\ndocker build -t rustgate .\n```\n\n## Kubernetes\n\nA Helm chart is provided in `helm/`:\n\n```bash\nhelm install rustgate helm/ --set tls.secretName=my-tls-secret\n```\n\nThe chart includes Pod Security Standards (restricted profile), startup/liveness/readiness probes, PodDisruptionBudget, HorizontalPodAutoscaler, graceful shutdown with connection draining, optional federation, and NetworkPolicy.\n\nFor full deployment documentation see [docs/deployment.md](docs/deployment.md).\n\n## Security\n\n- **mTLS everywhere** — all client and federation connections require mutual TLS with certificate verification\n- **CRL revocation** — revoked certificates are rejected at the TLS handshake via `--crl`\n- **FIPS 140-3** — optional aws-lc-rs crypto provider for FIPS-validated TLS ([details](docs/fips.md))\n- **No unsafe code** — `unsafe_code = \"forbid\"` enforced workspace-wide\n- **No panics** — `clippy::panic = \"deny\"` and `clippy::unwrap_used = \"deny\"` in production code\n- **Subject DN enforcement** — enrollment certificates carry the authenticated username to prevent impersonation\n- **Container hardening** — non-root UID (10001), read-only filesystem, STOPSIGNAL SIGTERM\n- **TLS session resumption disabled** — forces full handshake with CRL check on every connection\n\nFor security policy and vulnerability reporting see [SECURITY.md](SECURITY.md).\n\n## Testing\n\n```bash\ncargo nextest run                              # All tests (default features)\ncargo nextest run --features fips              # FIPS-gated tests\ncargo nextest run -p rustgate-nats --test integration  # NATS integration (needs nats-server)\n```\n\n| Crate | Test files | Covers |\n|-------|-----------|--------|\n| `rustgate-transport` | `tls_listener`, `e2e_routing`, `encoder`, `crl`, `fips`, `cert_rotation` | mTLS, routing, codecs, CRL, FIPS, certificate hot-reload |\n| `rustgate-cot` | `parser` | CoT XML parsing |\n| `rustgate-core` | `types` | Core type invariants |\n| `rustgate-enrollment` | `server_integration` | PKCS#12 enrollment, CSR signing |\n| `rustgate-federation` | `v2_integration`, `api_integration`, `ha_integration` | Federation V2 protocol, REST API, HA coordination |\n| `rustgate-nats` | `integration` | NATS bridge, echo prevention, JetStream replay |\n| `rustgate-proto` | `codec_integration` | XML ↔ protobuf conversion |\n| `rustgate-server` | `cli_parsing`, `tls_config`, `feature_gates`, `archive_integration` | CLI validation, TLS setup, feature gating, CoT archival |\n| `rustgate-websocket` | `ws_listener`, `ws_server` | WebSocket mTLS, session routing |\n\nAll tests use ephemeral certificates generated at runtime via `rustgate-test-utils` — no fixture files.\n\n## Documentation\n\n| Document | Description |\n|----------|-------------|\n| [Architecture](docs/architecture.md) | System design and crate responsibilities |\n| [TLS Certificates](docs/tls-certificates.md) | Certificate requirements, generation, and management |\n| [Deployment](docs/deployment.md) | Binary, Docker Compose, and Kubernetes deployment |\n| [FIPS 140-3](docs/fips.md) | FIPS crypto provider setup and known limitations |\n| [Configuration](docs/configuration.md) | All CLI flags, env vars, and runtime options |\n| [Security Posture](docs/security-posture.md) | NIST 800-53 control mapping and compliance overview |\n| [Threat Model](docs/threat-model.md) | STRIDE methodology threats, mitigations, and residual risks |\n| [Graceful Degradation](docs/graceful-degradation.md) | Subsystem failure modes and recovery behavior |\n| [Post-Quantum Roadmap](docs/post-quantum.md) | Path to post-quantum cryptographic protection |\n| [Observability](docs/observability.md) | Structured logging, metrics, and distributed tracing |\n| [Runbooks](docs/runbooks/) | Operational runbooks for federation, memory, NATS |\n| [CONTRIBUTING](CONTRIBUTING.md) | Build prerequisites, code quality, and PR guidelines |\n| [CHANGELOG](CHANGELOG.md) | Release history in Keep a Changelog format |\n| [SECURITY](SECURITY.md) | Security policy and vulnerability reporting |\n\n## Contributing\n\nSee [CONTRIBUTING.md](CONTRIBUTING.md) for prerequisites, building, testing, code quality standards, and pull request guidelines.\n\n## License\n\nProprietary. See [LICENSE](LICENSE) for details.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frchiofalo%2Frustgate","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frchiofalo%2Frustgate","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frchiofalo%2Frustgate/lists"}