v0.37.2

thevoiceguy/siphon-aiv0.37.2Jul 20, 2026by github-actions[bot]

Upgrading?

AI Summary

This release fixes outbound TLS connectivity issues by correcting SNI handling for hostname trunks and refines the admin API response structure for `/admin/calls`. It also updates metrics labeling to accurately reflect request outcomes.

Key Highlights

  • Outbound TLS to hostname trunks now completes by using the URI hostname for SNI instead of the resolved IP.
  • The response shape of `GET /admin/calls` changed from an array of strings to an array of objects containing `{call_id, sip_call_id, direction}`.
  • The metric `siphon_ai_admin_requests_total` now correctly labels failed requests based on response status codes rather than auth outcome.

Breaking Changes

  • The response shape of `GET /admin/calls` changed from an array of strings to an array of objects.

New Features

  • Outbound TLS completion for hostname trunks.
  • Refined admin request metrics labeling.

Full Release Notes

### Changed

- **`GET /admin/calls` now returns an object per call, not a bare SIP
  Call-ID string** (issue #311). Each element is
  `{call_id, sip_call_id, direction}`: the **bridge** `call_id` (the id
  `/admin/v1/conferences/*`, `/park`, `/retrieve`, and `/stats` all take,
  and the value on the WS `start` message + CDR), the **SIP** Call-ID
  (what `POST /admin/calls/:id/hangup` takes), and `"inbound"` /
  `"outbound"`. Before this, the only endpoint that enumerated calls
  returned SIP Call-IDs while every conference endpoint required the
  bridge id, and **no admin endpoint exposed the mapping** — operator
  conferencing was undriveable without correlating daemon logs, and the
  resulting `404 "no active call"` (while `GET /admin/calls` listed the
  call) read as a liveness bug. The listing is now sourced from the
  bridge-id-keyed control registry, so it also covers **outbound** calls,
  which the old inbound-only listing omitted. **This is a breaking
  response-shape change** to `GET /admin/calls` (array of strings → array
  of objects); scripts parsing it must be updated. The `404` bodies from
  the conference/park handlers now name the expected id namespace.

### Fixed

- **Outbound TLS to a hostname trunk now completes — SNI is the URI
  hostname, not the resolved IP** (issue #312; siphon-rs #64, pin
  `36c3ac4f3c0c` → `3a4fc312ade3`). On a hostname trunk with no SRV
  records (Twilio Secure Trunking, `*.pstn.twilio.com`), RFC 3263
  resolution replaced the URI host with the resolved A-record IP, and the
  UAC then handed *that IP* to rustls as the TLS `ServerName` — so the
  handshake presented `sni=<ip>` and cert-verified against the IP. Any
  trunk serving a hostname-scoped certificate and keying on SNI rejected
  it, so outbound TLS calls never connected (`result="unreachable"`);
  combined with a secure trunk rejecting UDP (`488`), there was **no
  working outbound transport**. Fixed upstream in siphon-rs `sip-dns` /
  `sip-uac`: a `DnsTarget` now carries the pre-resolution hostname as its
  TLS reference identity (RFC 5922 §4) and TLS uses it for SNI and
  certificate-name verification, while the connection still targets the
  resolved IP — so RFC 3263 address selection is unchanged. This bump is
  the only siphon-ai change; no siphon-ai API, config, protocol, or CDR
  change. IP-literal and SRV-addressed trunks are unaffected.

- **`siphon_ai_admin_requests_total` no longer labels failed admin
  requests `result="ok"`** (issue #310). The counter derived `result`
  from the auth outcome only, so any authorized request whose handler
  then returned a non-2xx status was still counted `ok` — a `404` from
  operating on a stale `call_id`, a `409`, a `503` at a cap. `result` now
  follows the response status: `not_found` for `404` (a normal
  conference/park race), `error` for every other handler failure (400 /
  409 / 429 / 501 / 503), `ok` only for 2xx. The auth layer's
  `unauthenticated` / `forbidden` are unchanged. Alerting on
  `result != "ok"` is now a faithful failure signal. `# HELP` text,
  `docs/DEPLOY.md`, and the audit-stream `result` field updated to match.

---

**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.37.2` (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