ADR-0173 : Plateforme de téléphonie Navin : Asterisk, Kamailio, LiveKit SIP, SeaweedFS, multi-tenant et HA
- Statut : accepté
- Date : 2026-11-03
- Portée : catalogue du Navin Manager (
navin-manager/catalog/services/asterisk.yaml,kamailio.yaml,rtpengine.yaml,livekit*.yaml), domaine téléphonie du Control Plane (services/control-plane/src/eai/domains/telephony), migrationssql/postgres/V202__telephony*.sqlet suivantes, section « Téléphonie » du portail (portal/src) - Documents liés : ADR-0101 (politique de licences), ADR-0166 (haute disponibilité déclarée par service), ADR-0171
(installation durcie),
docs/architecture/ADRs/ADR-0173-*(ce document), guides téléphonie (docs/fr/guides/telephony)
Contexte
Le client demande une téléphonie d'entreprise commercialisable : PBX, proxy SIP, passerelle SIP vers LiveKit, agents
vocaux IA, multi-tenant, haute disponibilité, interfaces Web, sans démonstration. Deux plateformes existent et gardent
leur rôle : le Navin Manager et ses agents installent et exploitent l'infrastructure ; Navin Enterprise AI Platform
configure et administre les usages. LiveKit Server est déjà au catalogue (méthodes binary et podman, mode
distributed sur Redis) et le Control Plane signe des jetons de salle LiveKit pour la voix temps réel ; LiveKit SIP,
LiveKit Egress, les workers d'agents, Asterisk, Kamailio et RTPengine n'existent pas.
Décision
1. Deux plans, des interfaces explicites
| Qui | Par quoi | Fait quoi |
|---|---|---|
| Navin Manager | agents Navin sur les hôtes | installation, versions, configuration système, ports, certificats, clusters, HA, sauvegardes, contrôles de santé, rollback |
| Navin Enterprise | AMI et ARI d'Asterisk, JSONRPC de Kamailio, API Twirp de LiveKit, S3 de SeaweedFS | tenants, extensions, trunks, numéros, routage, IVR, files, agents, enregistrements, CDR, quotas |
| Navin Enterprise | API du Manager (domaine platform_manager existant) | lecture de l'inventaire et de l'état des services ; toute opération d'infrastructure est demandée au Manager |
Le Control Plane n'exécute aucune commande système. Le Manager ne gère ni extension, ni IVR, ni file, ni règle métier.
2. Services du catalogue du Manager
| Service | Composants | Méthodes | Rôle |
|---|---|---|---|
asterisk | asterisk (pool) | package | PBX : PJSIP, dialplan, files, messagerie vocale, ConfBridge, MixMonitor, ARI, AMI, CDR et CEL |
kamailio | kamailio (2 au moins en HA) | package | bord SIP : TLS, WSS, NAT, anti-flood, anti-bruteforce, dispatcher vers Asterisk et LiveKit SIP |
rtpengine | rtpengine | package | optionnel : ancrage RTP, NAT difficile, interconnexion média ; jamais installé par défaut |
livekit | livekit-server | binary, podman | existant, complété sans changer un déploiement qui fonctionne |
livekit-sip | livekit-sip | podman | passerelle SIP vers les salles LiveKit |
livekit-egress | livekit-egress | podman | enregistrements LiveKit vers SeaweedFS |
livekit-ingress | livekit-ingress | podman | optionnel, inutile à la téléphonie (RTMP, WHIP) |
livekit-agents | livekit-agents (workers) | python | exécution des agents vocaux IA de Navin |
Valeurs par défaut des ports (le planificateur refuse un conflit sur un même hôte) :
| Service | Port | Exposition |
|---|---|---|
| Kamailio | 5060 UDP et TCP, 5061 TLS (SIP) ; 7443 WSS (softphones) | public (opérateurs, téléphones) |
| Kamailio | 5071 HTTP (JSONRPC et /metrics) | réseau d'administration |
| Asterisk | 5070 UDP et TCP (SIP depuis Kamailio uniquement) | réseau de signalisation interne |
| Asterisk | 8088 HTTP, 8089 HTTPS (ARI, /metrics) ; 5038 AMI, 5039 AMI TLS | réseau d'administration |
| Asterisk | 10000 à 19999 UDP (RTP, SRTP, DTLS-SRTP) | réseau média |
| LiveKit SIP | 5090 UDP et TCP (SIP) ; 20000 à 29999 UDP (RTP) | interne et média |
| RTPengine | 2223 UDP (protocole ng) ; 30000 à 39999 UDP | administration et média |
| LiveKit Server | 7880 (signalisation), 50000 à 50100 UDP (existant) | existant |
AMI, ARI, JSONRPC et les ports de métriques ne sont jamais publics : ils écoutent sur l'adresse d'administration de l'hôte et le pare-feu du Manager ne les ouvre qu'aux sources déclarées.
3. Livraison de la configuration fonctionnelle
- Asterisk. Le Manager installe les fichiers système (
asterisk.conf,modules.conf,pjsip.confavec les transports,extensions.conf,queues.conf,voicemail.conf,confbridge.conf,manager.conf,ari.conf,http.conf,rtp.conf,prometheus.conf,cdr.conf,cel.conf) ; chacun inclut un fichier géré (#tryinclude pjsip_navin.conf,extensions_navin.conf,queues_navin.conf,voicemail_navin.conf,confbridge_navin.conf). Navin Enterprise compile ces fichiers gérés par pool PBX à partir des tenants, extensions, trunks, numéros, règles, IVR et files ; il les valide, les versionne (texte, empreinte SHA-256, auteur), les livre à chaque nœud du pool par AMI (CreateConfig,UpdateConfig), les active par AMI (pjsip reload,dialplan reload,queue reload all,voicemail reload,module reload app_confbridge.so), relit le résultat (GetConfig) et peut revenir à la version précédente. ARI sert au contrôle des appels (canaux, ponts, enregistrements, transferts) ; AMI sert aussi aux événements (CDR parcdr_manager, CEL parcel_manager, états des contacts et des files). - Nommage. Identifiant court du tenant
tid=tsuivi des 12 premiers caractères hexadécimaux de son UUID. Points de terminaison{tid}-{extension}, contextes{tid}-internal,{tid}-inbound,{tid}-outbound,{tid}-ivr-{flux}, files{tid}-{file},accountcode= UUID du tenant, variableNAVIN_TENANTsur chaque canal. Aucun contexte d'un tenant ne référence un objet d'un autre tenant ; le compilateur le vérifie. - Kamailio. Le Manager écrit la liste du dispatcher à partir de la topologie (jeu 1 : pool Asterisk partagé, jeu
2 : LiveKit SIP, jeux 100 et suivants : pools dédiés). Navin Enterprise pousse le routage des tenants par JSONRPC
dans les tables de hachage
tenant_domains(domaine SIP vers tenant et jeu) etdid_routes(numéro E.164 vers tenant, jeu et branchepbxouai), réconcilie à intervalle régulier et après chaque redémarrage de Kamailio (core.uptime), et pilote le drain des destinations (dispatcher.set_state). Les instances Kamailio répliquent ces tables par DMQ. - LiveKit SIP. Navin Enterprise crée par l'API LiveKit les trunks entrants et sortants et les règles de dispatch
de chaque tenant (noms préfixés par
tid, métadonnéestenant_id), lance les appels sortants des agents (CreateSIPParticipant) et les transferts vers une extension (TransferSIPParticipant, SIP REFER). - Deux branches distinctes. Branche PBX : Kamailio vers Asterisk. Branche IA directe : Kamailio vers LiveKit SIP
(numéro routé
ai). Branche IA par le PBX : Asterisk composePJSIP/{agent}@livekit-sipdepuis un IVR ou une file. Le transfert IA vers humain passe par un REFER vers Kamailio, qui route l'extension vers son Asterisk. - Corrélation. Asterisk pose l'en-tête
X-Navin-Call-Id(UUID) ; LiveKit SIP le recopie en attribut de participant ; la session d'appel de Navin relieX-Navin-Call-Id,uniqueidetlinkedidd'Asterisk, leCall-IDSIP, la salle et le participant LiveKit.
4. Données de Navin Enterprise
Tables du schéma eai, toutes avec tenant_id, isolées par les mécanismes de tenancy existants du Control Plane :
telephony_tenants (modèle shared ou dedicated, domaine SIP, pool, quotas, conservation), pbx_instances
(pool partagé ou dédié, service du Manager, références de secrets AMI et ARI), sip_trunks, phone_numbers,
extensions, routing_rules, ivr_flows et leurs versions, call_queues, queue_members, telephony_agents
(humains), voice_agents (IA), telephony_config_versions (publications), call_sessions, call_events,
call_recordings, voicemail_messages, telephony_quotas. Le journal d'audit existant du Control Plane est
réutilisé, pas dupliqué. Mots de passe SIP, secrets de trunks, identifiants AMI et ARI : dans le coffre existant,
jamais renvoyés par l'API (champs en écriture seule, has_secret).
5. Stockage SeaweedFS
Un compartiment navin-telephony, clés opaques tenants/{tenant_uuid}/{catégorie}/{aaaa}/{mm}/{uuid}, catégories
call-recordings, voicemail, ivr-prompts, conference-recordings, ai-voice-recordings, audio-exports.
Les objets sont chiffrés par Navin Enterprise avant l'envoi. Lecture et téléchargement uniquement par Navin
Enterprise : URL signées de quelques minutes, contrôle des droits, audit ; les identifiants S3 ne quittent jamais le
serveur. Enregistrements Asterisk : MixMonitor écrit dans recording/navin/{tid}/ ; Navin Enterprise les récupère
par ARI (GET /recordings/stored/{nom}/file), les chiffre, les dépose, puis les supprime par ARI. LiveKit Egress
écrit dans le compartiment navin-livekit-egress avec des identifiants limités à ce compartiment ; à la fin d'un
enregistrement (webhook signé), Navin Enterprise le range dans l'organisation des tenants.
6. Softphone WebRTC
Le softphone du portail utilise JsSIP (MIT) en SIP sur WebSocket sécurisé vers Kamailio (WSS, path), qui relaie
vers l'Asterisk du tenant ; média DTLS-SRTP avec ICE entre le navigateur et Asterisk (webrtc=yes). Le navigateur ne
reçoit jamais le mot de passe SIP de l'extension : Navin Enterprise délivre des identifiants éphémères (module
auth_ephemeral de Kamailio, HMAC avec un secret partagé gardé dans le coffre, une heure au plus) ; les points de
terminaison WebRTC d'Asterisk n'acceptent que les adresses de Kamailio. Une salle LiveKit n'est pas une extension.
7. Multi-tenant
Modèle shared : pool Asterisk partagé, isolation par contextes, domaines SIP, préfixes LiveKit, préfixes de
stockage et autorisations. Modèle dedicated : pool Asterisk (et, au besoin, LiveKit SIP) dédié au tenant, jeu de
dispatcher propre. Quotas par tenant : appels simultanés, appels par seconde (CPS, appliqués par Kamailio),
destinations et pays autorisés, durée maximale, conservation des enregistrements.
8. Haute disponibilité : garanties par scénario
| Panne | Nouveaux appels | Appels en cours |
|---|---|---|
| Une instance Kamailio | reprises par l'autre instance (DNS SRV, adresses multiples chez l'opérateur, ou répartiteur réseau) | les dialogues routés par l'instance perdue échouent sur la requête suivante |
| Un nœud Asterisk du pool | routés vers les autres nœuds dès que la sonde OPTIONS du dispatcher le déclare hors service | perdus : il n'y a pas d'état d'appel partagé entre nœuds Asterisk |
| Un nœud LiveKit SIP ou LiveKit Server | routés vers les autres nœuds | perdus pour les participants SIP de ce nœud |
| Un worker d'agent IA | pris par un autre worker | la session de l'agent s'arrête ; la règle de secours route vers une file humaine |
| PostgreSQL, Redis, SeaweedFS | modes HA existants du catalogue (Patroni, Sentinel, réplication) | selon le service |
Une adresse IP virtuelle n'est pas une solution universelle ; aucune capacité ni survie d'appel n'est annoncée sans test.
9. Observabilité
Métriques : res_prometheus d'Asterisk, xhttp_prom de Kamailio, ports Prometheus de LiveKit, LiveKit SIP et
Egress, collectés par le Prometheus du catalogue ; journaux par Alloy ; alertes par Alertmanager ; indicateurs métier
(appels, CPS, qualité, files, consommation) calculés par Navin Enterprise à partir des CDR, CEL et événements.
10. Licences
Asterisk (GPL-2.0), Kamailio (GPL-2.0-or-later), RTPengine (GPL-3.0) et JsSIP (MIT) restent des composants séparés, utilisés par leurs interfaces réseau documentées ; aucun code GPL n'entre dans le code propriétaire de Navin. La redistribution des binaires GPL dans le bundle hors ligne s'accompagne des notices et des sources correspondantes.
Conséquences
- Le Manager gagne cinq services et des modèles de configuration ; Navin Enterprise gagne un domaine téléphonie, ses migrations, ses compilateurs et une section du portail.
- Le Control Plane dépend de l'AMI, de l'ARI, du JSONRPC de Kamailio et de l'API LiveKit, joints par les liaisons du
service
navin-enterprisedu catalogue. - Les tests de charge et les tests de panne multi-hôtes se font sur un environnement dédié avec SIPp ; aucun test n'est lancé vers un opérateur sans son accord.