Skip to main content

Inter-tenant calling

Tenants are isolated by default: extension 100 in acme cannot reach extension 100 in globex, and a call between them would have to go out to the carrier and back in over a DID.

Direct dialling is possible, and it is deliberately off unless two switches agree.

Enabling it

configs/lyno.yaml
allow_inter_tenant: true
configs/tenants/acme/tenant.yaml
inter_tenant: [globex]
  • The global flag is the ceiling. With it off, a tenant's inter_tenant list has no effect at all.
  • The per-tenant list is an allowlist of tenants this tenant may dial.

The list is one-directional. acme naming globex lets acme call globex; for the reverse, globex must name acme in its own file. That asymmetry is usually what you want — a support desk that may reach a customer's extensions without the customer being able to dial back in.

Dialling

Once enabled, a dialplan target may be written tenant:<name>/<extension>:

configs/tenants/acme/extensions/300.yaml
extension: "300"
name: Escalate to Globex support
steps:
- id: escalate
type: dial
timeout: 30s
target:
kind: endpoint
endpoint: "tenant:globex/900"

The same form works inside ring group and follow-me targets:

target:
kind: followme
stages:
- targets: ["101"]
timeout: 15s
- targets: ["100", "tenant:globex/900", "external:0612345678"]
timeout: 25s

What crosses the boundary and what does not

CrossesStays behind
The call itself, bridged as any otherCredentials — each tenant keeps its own realm
Caller identity, as an internal callDialplans — the target tenant's plan runs
Music on hold — resolved in the tenant that owns the step
Time conditions — evaluated in the calling tenant's timezone

The destination extension runs its own tenant's dialplan, so an escalation lands in whatever greeting, follow-me and out-of-hours handling that tenant has configured.

Validation

A tenant: target is checked at startup:

  • the global allow_inter_tenant must be on;
  • the calling tenant must list the target tenant in inter_tenant;
  • the target tenant and extension must exist.

Any of these failing is a configuration error, not a runtime surprise.