Trunk Profiles
A trunk profile bundles the behavior shared by a class of trunks: which translation contexts calls enter and leave through, how much of the peer’s asserted caller ID is trusted, STIR/SHAKEN handling, dial timers, URI selection, and codec policy. Define one profile per kind of interconnect — carrier ingress, carrier egress, customer PBX — and point each trunk at the right one.
trunk-profiles: customer-pbx-profile: inbound-translation-context: from-customers outbound-translation-context: to-customers caller-id-mode: provided attestation-mode: A resign-policy: resign uri-selection: sequential ring-for: 30 codecs: [ulaw, g722]Field reference
Section titled “Field reference”| Field | Required | Meaning |
|---|---|---|
inbound-translation-context |
yes | Translation context for calls arriving on these trunks (DID delivery). |
outbound-translation-context |
yes | Translation context for calls being sent out these trunks. |
caller-id-mode |
yes | Ingress caller-ID trust: fixed, provided, or modify (below). |
inbound-caller-id-context |
with mode modify |
Caller-ID context run at ingress. Only valid alongside modify. |
outbound-caller-id-context |
no | Caller-ID context applied when dialing out these trunks. Independent of mode. |
special-number-profile |
no | Which special-number profile intercepts emergency numbers arriving on these trunks. Empty = default. |
attestation-mode |
when the namespace signs | Ingress: the STIR/SHAKEN attestation level (A, B, C) your namespace asserts when it signs a call that arrived on these trunks (below). Ignored without a stirshaken policy block. |
resign-policy |
no | Ingress: what happens to the STIR/SHAKEN signature received with a call arriving on these trunks — passthrough, passthrough-block, resign, or keep-sign (default). |
transmit-passport |
no | Egress: which STIR/SHAKEN headers are emitted on calls dialed out these trunks — transmit-full (default), transmit-verstat, or strip. |
uri-selection |
no | Order the trunk’s URIs are tried: sequential (default) or random. |
ring-for |
no | Per-URI ring duration in seconds. Default 90. |
codecs |
no | Ordered codec policy (below). Empty = no restriction. |
max-concurrent |
no | Template per-trunk concurrent-call cap. A trunk’s own value overrides it; capacity is never pooled across trunks. |
Caller-ID policy is directional
Section titled “Caller-ID policy is directional”The mode and the two contexts split cleanly by direction:
Ingress (caller-id-mode, inbound-caller-id-context, and the trunk’s
allowed-caller-ids) governs what a peer may assert when sending you a
call:
| Mode | Behavior |
|---|---|
fixed |
Discard the asserted value; use the trunk’s primary-caller-id. The allowlist is skipped — the value is yours. Every trunk on a fixed profile must set a valid primary-caller-id. |
provided |
Accept the asserted value, subject to allowed-caller-ids. |
modify |
Rewrite the asserted value through inbound-caller-id-context, then screen the result against allowed-caller-ids. |
Setting inbound-caller-id-context with a mode other than modify is a
validation error — it would be silently inert.
Egress (outbound-caller-id-context only) rewrites the caller ID a call
is carrying just before it leaves — format conversion for a carrier,
scrubbing, branding. Mode and allowlist do not run on egress: the caller ID
on an outbound call arrived with the call (a line’s enforced number, a
PSTN caller’s number on a forwarded call) and was already policed where it
entered.
STIR/SHAKEN: ingress fixes the policy, egress emits it
Section titled “STIR/SHAKEN: ingress fixes the policy, egress emits it”The signing knobs are ingress properties: they are read from the trunk a call arrives on, travel with the call, and are realized when the call leaves — the egress trunk’s own signing knobs are never consulted. This is deliberate anti-laundering: a call cannot pick up a better attestation by leaving through a differently-configured trunk, because the level and signature disposition were fixed where the call (and its trust) entered.
attestation-mode — the attestation level your namespace asserts when
it signs a fresh PASSporT for a call that arrived on these trunks. Required
on every profile when your stirshaken policy has outbound signing
enabled; ignored entirely when the namespace has no stirshaken block.
| Level | Assert it when |
|---|---|
A |
You know the customer and their right to the number — e.g. a trunk pinned by allowed-caller-ids to its assigned DIDs |
B |
Known customer, unverified number |
C |
Gateway / transit traffic |
Choosing honestly is a compliance obligation, not a technical one.
Line-originated calls need no profile: they are signed at A — the switch
enforces line caller ID — unless the line profile sets
allow-unrestricted-caller-id, which drops them to B.
resign-policy — what happens to the signature received with a call
arriving on these trunks:
| Value | Behavior |
|---|---|
keep-sign (default) |
Keep a received signature; sign the call yourself if it arrived unsigned |
resign |
Always sign fresh, discarding whatever was received |
passthrough |
Relay exactly what was received — including nothing; never sign |
passthrough-block |
Relay a received signature, but reject a call that arrives unsigned |
passthrough-block is the strict-interconnect stance: signed traffic
passes untouched, unsigned traffic is refused at ingest.
transmit-passport — the one egress knob, controlling which
STIR/SHAKEN headers actually appear on calls dialed out these trunks:
| Value | Emits |
|---|---|
transmit-full (default) |
The Identity header (the PASSporT), plus verstat / P-Asserted-Identity |
transmit-verstat |
verstat + P-Asserted-Identity only — no Identity header, for far ends that mishandle it |
strip |
No STIR/SHAKEN headers at all |
Unlike the signing knobs, transmit-passport needs no stirshaken block
or credential — it is pure header control. The verstat / PAI conveyance
additionally requires your namespace’s inbound policy to set
convey-verstat.
The signature always covers the final caller ID — after
outbound-caller-id-context has run. The namespace-level policy block,
signing credential provisioning, and inbound verification are covered in
the STIR/SHAKEN guide.
Timers, URI order, codecs
Section titled “Timers, URI order, codecs”ring-for— how long each URI of a trunk is given before the dial moves on (next URI, next route destination, or failure). The 90-second default suits carrier egress; customer-PBX delivery profiles usually want something shorter so DID callers aren’t left ringing into a dead PBX.uri-selection—sequentialtreats a trunk’s URI list as primary/backup;randomspreads calls across gateways.codecs— same semantics as line-profile codecs: inbound offers from these trunks are stripped to the set at the edge (no common codec → SIP 488 before anything rings); outbound dials offer the set in preference order. Empty = passthrough. Match this to what the peer actually supports — a mismatch surfaces as 488s in the peer’s logs.
Worked profiles
Section titled “Worked profiles”trunk-profiles: # Carrier origination: the whole PSTN calls in; trust presented CID and # relay the carrier's signatures untouched — never re-vouch PSTN transit. carrier-ingress: inbound-translation-context: from-carrier outbound-translation-context: to-carrier # required; used if ever dialed caller-id-mode: provided attestation-mode: C # if we ever sign a call from here: gateway level resign-policy: passthrough codecs: [ulaw, g722]
# Carrier termination: normalize egress CID to E.164; emit full S/S headers. carrier-egress: inbound-translation-context: from-carrier outbound-translation-context: to-carrier caller-id-mode: provided outbound-caller-id-context: egress-e164 attestation-mode: C # ingress knob; required whenever the ns signs transmit-passport: transmit-full # the default, shown for clarity uri-selection: random codecs: [ulaw]
# Customer PBX: normalize what they assert, screen it, vouch it fresh at A. customer-pbx-profile: inbound-translation-context: from-customers outbound-translation-context: to-customers caller-id-mode: modify inbound-caller-id-context: normalize-cid outbound-caller-id-context: delivery-format attestation-mode: A # allowed-caller-ids pins them to their DIDs resign-policy: resign # discard whatever the PBX attached; we vouch ring-for: 30 codecs: [ulaw, g722]