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

configVersion: lyno/v1
kind: System
spec:
allowInterTenant: true
kind: Tenant
metadata: { name: acme }
spec:
domains: [acme.pbx.example.com]
interTenant: [globex]
  • The global flag is the ceiling. With it off, a tenant's interTenant 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 on its own document. 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>:

configVersion: lyno/v1
kind: Extension
metadata:
name: "300"
tenant: acme
spec:
description: 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 allowInterTenant must be on;
  • the calling tenant must list the target tenant in interTenant;
  • the target tenant and extension must exist.

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