v0.19.0

thevoiceguy/siphon-aiv0.19.0Jun 27, 2026by github-actions[bot]

Upgrading?

AI Summary

This release focuses on security and abuse hardening by introducing inbound admission control via token-bucket rate limiting and mandatory digest authentication for SIP INVITEs.

Key Highlights

  • Inbound INVITE admission control to prevent DoS
  • Per-source token bucket limiter (rate limit + burst)
  • Optional global concurrent call cap
  • Inbound digest authentication (RFC 3261 §22)

New Features

  • SIP admission control configuration
  • Digest authentication configuration
  • Source-based rate limiting metrics

Full Release Notes

### Added

- **Inbound INVITE admission control — `[sip.admission]`** (P1 "Security &
  abuse hardening"; second chunk of v0.19.0). A DoS posture beyond the
  `[[trunk]]` allowlist: shed abusive inbound INVITEs **before** any
  trunk / auth / route work. A **per-source token bucket** keyed on the
  source IP (`max_per_sec` + `burst`) answers an over-rate source `503` +
  `Retry-After`, and after `drop_after` consecutive rejects **silently
  drops** further INVITEs from it (an obvious flood doesn't earn a
  response). An optional **global `max_concurrent`** cap (read from the
  live call registry) answers `503` once the node is at capacity. Source
  buckets live in a size-capped table (`max_sources`) with idle/oldest
  eviction, so the limiter can't leak memory under a spoofed-source
  flood. New metrics
  `siphon_ai_invite_admission_total{result=accepted|rate_limited|dropped}`
  + `siphon_ai_invite_admission_sources` gauge. Off by default;
  restart-required on `SIGHUP` (part of `[sip]`). See `docs/CONFIG.md` →
  `[sip.admission]`.

- **Inbound digest authentication — `[sip.auth]`** (P1 "Security & abuse
  hardening"; first chunk of v0.19.0). Challenge inbound INVITEs with RFC 3261
  §22 / RFC 7616 digest auth, so trust no longer rests on a spoofable network
  identity (source IP / `From:` host). A new out-of-dialog INVITE that needs
  auth and arrives without a valid `Authorization` is answered `401
  Unauthorized` + `WWW-Authenticate` (nonce/realm/qop); the peer re-sends with
  a digest `response` verified against the configured credentials. Replay is
  bounded by a server nonce TTL (an expired nonce gets a `stale=true`
  re-challenge). Configured by `[sip.auth]` (`enabled`, `realm`, `algorithm` =
  MD5/SHA-256/SHA-512, `qop`, and `[[sip.auth.user]]` credentials) — passwords
  resolve via `${file:…}`/`${cred:…}` (v0.18.0). Digest is an **AND-gate with
  the `[[trunk]]` allowlist**, opt-in per trunk via `auth_required = true`, so
  a static-IP carrier that doesn't send credentials stays allowlist-only and
  isn't broken by enabling auth; with no trunks (legacy mode) every INVITE is
  challenged. New metric `siphon_ai_sip_auth_total{result=ok|challenged|failed|stale}`.
  Uses the upstream `sip-auth` server-side verifier (no siphon-rs change).
  Off by default; no protocol/CDR/schema break. See `docs/CONFIG.md` →
  `[sip.auth]`.

---

**Artifacts**

- Static musl binaries for `x86_64` and `aarch64` (`.tar.gz`).
- Debian packages (`.deb`) for `amd64` and `arm64` — `apt install ./siphon-ai_*_amd64.deb`.
- `SHA256SUMS` — verify with `sha256sum -c SHA256SUMS`.
- `*-sbom.cdx.json` — CycloneDX SBOM.
- `SHA256SUMS.cosign.bundle` — cosign keyless signature over the checksums.
- Container: `ghcr.io/thevoiceguy/siphon-ai:v0.19.0` (multi-arch, cosign-signed).

Verify the checksums signature:
```
cosign verify-blob --bundle SHA256SUMS.cosign.bundle \
  --certificate-oidc-issuer https://token.actions.githubusercontent.com \
  --certificate-identity-regexp 'release.yml@' SHA256SUMS
```

Related Repositories