Recording That Passes an Audit: Exemptions, Retention and the Evidence Trail

M
Miuda Team
Building conversational AI tooling

Compliance recording isn’t “turn recording on.” It’s being able to answer, months later, questions like: was this specific call recorded? why not? where is it now? can you produce it, and prove it wasn’t altered?

RustPBX’s recording pipeline is built to make those answers routine. Here’s the operational playbook.

Recording pipeline: capture → segments → retried upload → presigned evidence

Start With the Policy, Not the Switch

The master switch is simple:

[recording]
enabled = true
type = "local"      # local | http | s3 | sipflow
auto_start = true

What matters is where exceptions live:

  • Per-trunk — record only carrier-facing traffic, or exclude a partner whose jurisdiction forbids it
  • Per-app exemptions — list routed applications that must opt out (the “agent pauses recording for card numbers” pattern)
  • Because these are config, they go through Git: the audit answer to “which calls are not recorded, and why” is a commit diff, not tribal knowledge

Segments Are the Unit of Evidence

A call is not one artifact. A consult transfer is two conversations; hold/resume changes context. Recording produces per-segment files, each with its own id and metadata, all linked to the same session_id.

That property is what makes selective production possible: hand the auditor the exact segment where the disputed statement occurred, not a 40-minute call with a timestamp they have to trust.

Storage That Won’t Lose Evidence

  • Upload retry worker — a failed upload retries with backoff. Nothing is silently dropped because an object store hiccuped.
  • Presigned downloads — evidence is produced via time-limited URLs; the console never proxies large media, and access is logged.
  • Lifecycle rules — retention lives in object storage policy (e.g., 180/360 days), where it’s auditable independently of the PBX.
  • Archive addon — long-term retention exports for programs that outlive hot storage.

The Three-Channel Evidence Model

For a thorough program, don’t rely on audio alone:

ChannelProves
Recording (audio)What was said
SipFlow (signaling + RTP)What was signaled, when, to whom — independent of the recorder
CDR (structured)Route, timings, hangup cause, media quality, session id

All three key off session_id, so a single call reconciles into one story. If a recording is disputed, the signaling capture and CDR corroborate it — and vice versa. This triangulation is what turns “we have recordings” into “we can demonstrate the record is complete.”

Retention Without Guesswork

  • Decide retention per channel (audio vs. packets vs. records) — they have different sizes and lifetimes
  • Keep exports (CSV/archives) for the structured record; keep objects for media
  • Document the clock: all nodes on NTP, because timestamps are part of the evidence
  • Test restoration annually — an archive never restored is a hope, not a plan

A Compliance Runbook Skeleton

  1. Define what must be recorded and what must not (per trunk/app), in config under Git
  2. Capture with per-segment recording + SipFlow always-on
  3. Store with retry, presigned access, and object-storage lifecycle
  4. Reconcile any call: CDR → segments → SipFlow ladder
  5. Produce evidence via presigned URLs with access logging
  6. Prove integrity: exports, timestamps, and the config history

Guides: Operations Manual, Basic Setup → Storage, and the SipFlow addon.

Get new posts by email

Deep dives on Rust telephony, contact centers and wholesale voice. No spam.

Thanks — you're on the list.

We use cookies for anonymous analytics to improve the site. Nothing is loaded until you accept. Privacy Policy