DID Routing Environments¶
Every DID in did_numbers has a routing_environment flag that decides where inbound calls for that number land: prod, staging, or OSS. This lets one Tata trunk serve all three environments with a clean separation.
The three environments¶
| Value | Where inbound lands | Managed by |
|---|---|---|
prod (default) | Prod cloud, local org_*_incoming context | Prod dispatcher auto-generated from DB |
staging | Staging cloud via WireGuard (cloud-endpoint-stage) | Prod dispatcher auto-generated from DB |
oss | OSS VPS (185.252.235.208) via public SIP from NUC | NUC oss-did-route — manual config |
How the flag drives dispatch¶
The dispatcher generator lives in api/src/services/asterisk/configDeploymentService.js → deployGatewayRouting(). It regenerates /etc/asterisk/ext_tata_gateway.conf on each config deploy. Pseudocode:
for each assigned DID:
if didEnv === myEnv:
Goto(org_<prefix>__incoming, <did>, 1) // local routing
elif myEnv === 'prod' && didEnv === 'staging':
Dial(PJSIP/<did>@cloud-endpoint-stage, 120) // forward over WG
else:
fallback: log + local Goto
myEnv is derived from process.env.ASTRADIAL_ENV at runtime — "staging" on staging, default "prod" on prod.
Format aliases¶
Indian DIDs are stored as either 08065978002 (local) or 918065978002 (international). The dispatcher generator emits both aliases for every Indian DID so customers calling either format reach the same org:
exten => 08065978002,1,Goto(org_mnd5khym__incoming,08065978002,1)
exten => 918065978002,1,Goto(org_mnd5khym__incoming,918065978002,1)
Generator helper: indianAliases(num) — prepends 91 to 11-digit leading-0 numbers and vice versa.
Managing the flag¶
Via admin UI (primary path)¶
- Log into editor as admin → Admin → DID Management
- Click the Environment dropdown on the DID row
- Pick
Prod/Staging/OSS - Backend flow: PUT
/api/v1/did-pool/admin/<id>+ POST/api/v1/admin/regenerate-gateway - Dispatcher regenerates + Asterisk reloads in place (no call drops)
Via SQL (emergency / bulk)¶
-- Single DID
UPDATE did_numbers SET routing_environment='staging' WHERE number='+918065978001';
-- Range allocation
UPDATE did_numbers SET routing_environment='staging' WHERE number IN ('918065978021','918065978022','918065978023','918065978024');
UPDATE did_numbers SET routing_environment='oss' WHERE number LIKE '91806597802_';
Then: curl -X POST -H "X-Internal-Key: $INTERNAL_API_KEY" http://localhost:8000/api/v1/admin/regenerate-gateway
Allocation convention¶
Astradial owns 30 DIDs (91806597 8000 – 8029). The current split:
| Range | Environment | Count | Notes |
|---|---|---|---|
| 78000 – 78020 | prod | 21 | Customer DIDs + reserved |
| 78021 – 78024 | staging | 4 | Testing pool |
| 78025 – 78029 | oss | 5 | OSS demo pool |
Convention — not enforced. Any DID can move between environments via the UI.
How prod forwards staging traffic (WireGuard)¶
Tata PSTN → NUC (10.10.10.2) → Prod Cloud (10.10.10.1)
│
│ if routing_environment='staging':
│ Dial(PJSIP/<did>@cloud-endpoint-stage,120)
▼
cloud-endpoint-stage endpoint on prod
│ (PJSIP contact: sip:10.10.10.3:5060)
▼
WireGuard tunnel prod ↔ staging
│
▼
Staging Cloud (10.10.10.3)
tata_gateway endpoint
identify match: 10.10.10.1, 10.10.10.2
│
▼
tata-inbound → tata-did-route → org_*_incoming
Required setup for staging forwarding to work¶
- Prod has
cloud-endpoint-stagePJSIP endpoint +cloud-aor-stageAOR (sip:10.10.10.3:5060) - WireGuard tunnel prod (
10.10.10.1) ↔ staging (10.10.10.3) —wg show wg0must show recent handshake - Staging's
tata_gateway_identifymust includematch=10.10.10.1(added during Apr 17 cutover) - ASTRADIAL_ENV=staging in staging's api
.env→ generator produces local Goto for staging-env DIDs
OSS routing — kept on NUC deliberately¶
OSS is NOT dispatched from prod for security reasons:
- If OSS VPS is compromised (credentials leak, exploit), attacker must not reach prod SIP
- If OSS VPS is unreachable (downtime, DDoS, misconfig), prod must continue working for real customers
Current OSS flow:
Tata → NUC (192.168.0.13) → NUC's oss-did-route context
│ exten => 918065978015,1,
│ Dial(PJSIP/${TATA_DID}@185.252.235.208:5060,30)
▼
Public internet (SIP auth)
│ username nuc_oss_gateway
▼
OSS VPS (185.252.235.208)
- NUC's
oss-did-routeis manually maintained (oneexten =>line per OSS DID) - Prod has no knowledge of OSS routing
routing_environment='oss'flag on prod DIDs is purely informational- When adding a new OSS DID, admin must SSH NUC and add the routing entry
When OSS grows to real customers, revisit this with a WireGuard tunnel prod ↔ OSS — defence in depth via SIP auth + WG private key + IP whitelist. Until then, NUC-only isolation is the right call.
Troubleshooting¶
"I changed routing_environment but dispatcher didn't update"¶
- Confirm PUT hit the API:
pm2 logs astrapbx --lines 30 --nostream | grep PUT - Known-bug fix landed in fix/did-admin-put-allow-routing-env (Apr 17) — verify
routing_environmentis in theallowedarray atapi/src/routes/didPool.jsPUT handler - Manually trigger regen:
curl -X POST -H "X-Internal-Key: $KEY" http://localhost:8000/api/v1/admin/regenerate-gateway - Then
grep <did> /etc/asterisk/ext_tata_gateway.confto confirm
"Staging-flagged DID not reaching staging"¶
- Prod dispatcher emits
Dial(PJSIP/.../cloud-endpoint-stage)— check file asterisk -rx 'pjsip show endpoint cloud-endpoint-stage'→ Status: Availwg show wg0 | grep -A 3 '10.10.10.3'→ recent handshake- On staging:
asterisk -rx 'pjsip show identifies'→ must include10.10.10.1 - Check staging's asterisk log for 'from-tata' / 'tata-inbound' entries
"OSS DID reaching prod (shouldn't happen)"¶
- Means NUC failed to intercept it before forwarding. Check NUC's
extensions.conffor anoss-did-routeentry matching the DID.