Skip to content

Security: HueCodes/Aulon

Security

docs/SECURITY.md

Security

Aulon v0.1 is a single-node NATS-core-compatible broker without TLS, authentication, or authorisation. Deploy it behind a trusted boundary (loopback, a private network, or a fronting gateway). This document records the threat model, the explicit non-mitigations, and the supported reporting channel.

Threat model

In-scope threats are the ones a v0.1 operator running Aulon behind a trusted boundary would still have to defend against:

Threat Mitigation
DoS via malformed frames. A peer sends bytes that exhaust the parser. parse_frame is allocation-free over a borrowed slice; the read accumulator caps at 2 × max_payload_bytes. Fuzzed (fuzz/parse_frame, fuzz/parse_pub) and proptested.
DoS via oversize payload. A peer sends a PUB with a header claiming gigabytes. max_payload_bytes (default 1 MiB) caps the payload; the read accumulator caps the entire frame at 2 × max_payload_bytes.
DoS via slow read. A peer subscribes then stops reading, growing the server's per-connection write buffer. Per-connection outbound buffer is a fixed outbound_capacity_bytes (default 2 MiB). On overflow the connection is evicted with -ERR slow consumer and the socket is closed. Tracked by aulon_slow_consumer_evictions_total.
DoS via subscription flooding. A single connection subscribes to millions of subjects. max_subscriptions_per_connection (default 1,024) caps live SUBs. MAX_SUBJECT_TOKENS (32) bounds trie depth per subscription.
DoS via connection exhaustion. Many concurrent connections from one peer. max_connections_per_shard (default 16,384) per-shard cap; on hit the next accept is dropped and aulon_connections_refused_total increments. The server refuses to start if RLIMIT_NOFILE soft is below MIN_NOFILE_FLOOR (33,280) so the cap fits comfortably under the kernel limit.
DoS via accept overload. Accept queue grows unbounded. listen(2) backlog is 1024 per shard; new accepts beyond that are kernel-refused. The accept loop checks the per-shard connection cap after each accept and drops over the cap.

Known non-mitigations

Aulon v0.1 does not implement:

  • TLS. The wire protocol is plain text. A passive observer on the network path can read every frame. Front Aulon with a TLS-terminating reverse proxy if you need transport encryption.
  • Authentication. Any TCP peer who can connect(2) is a client and can publish or subscribe. There is no token, NKey, JWT, or user/pass scheme.
  • Authorization. Every connected client has full PUB / SUB access to every subject. No ACLs, no per-subject scoping.
  • Per-IP / per-peer rate limiting. A misbehaving peer is bounded by the cap suite above but is not throttled.
  • Audit logging. Tracing logs connection lifecycle events but is not an audit trail in the compliance sense.

JetStream, clustering, gateways, leafnodes, and WebSocket transport are also out of v0.1 scope (see SCOPE.md).

Supply chain

  • License + dep policy enforced in CI by cargo deny (see deny.toml).
  • Advisory checks run in CI under two configurations: cargo deny's [advisories] section (version = 2, yanked = "deny") and an independent cargo audit job against the RustSec database.
  • The public API surface of aulon-core is snapshotted at crates/aulon-core/PUBLIC_API.txt. CI fails on drift so every public-API change is a deliberate commit.

Unsafe code

#![forbid(unsafe_code)] at every crate root except two modules in aulon-core that wrap libc syscalls:

  • eventfd.rs: eventfd(2), dup(2), write(2) on owned fds, and File/OwnedFd constructors from raw fds. Each unsafe block carries a Safety: comment citing the invariant.
  • rlimit.rs: getrlimit(2) read-only and one MaybeUninit::assume_init after a successful return.

The third module is shard_inbox.rs — a hand-rolled MPSC ring. unsafe impl Send/Sync, UnsafeCell slot writes/reads, all gated on the seq counter transitions and verified by loom (tests/loom_inbox.rs).

The unsafe surface is intentionally narrow. Every unsafe block has a Safety: comment naming the invariant it relies on.

Reporting a vulnerability

Use GitHub private vulnerability reporting for the repository. Please do not open a public GitHub issue. Expect a reply within five business days.

For non-security bugs, the GitHub issue tracker is the right place.

There aren't any published security advisories