chore: mandate telnyx signature verification

This commit is contained in:
Sabiha Khan 2026-05-19 16:48:49 +05:30
parent 5b1e3980b1
commit ce3ac98bd8
5 changed files with 9 additions and 56 deletions

View file

@ -142,12 +142,3 @@ FORCE_TURN_RELAY = os.getenv("FORCE_TURN_RELAY", "false").lower() == "true"
# OSS Email/Password Auth
OSS_JWT_SECRET = os.getenv("OSS_JWT_SECRET", "change-me-in-production")
OSS_JWT_EXPIRY_HOURS = int(os.getenv("OSS_JWT_EXPIRY_HOURS", "720")) # 30 days
# REMOVE-AFTER 2026-05-15: transitional flag. When True, Telnyx webhook
# signature verification is skipped for configs that have no
# webhook_public_key set (existing configs predating the field). Set in prod
# through 2026-05-15 to give users time to add their key; once removed,
# configs without a key will fail signature verification.
TELNYX_WEBHOOK_VERIFICATION_OPTIONAL = (
os.getenv("TELNYX_WEBHOOK_VERIFICATION_OPTIONAL", "false").lower() == "true"
)

View file

@ -25,7 +25,6 @@ TELNYX_TIMESTAMP_TOLERANCE_SECONDS = 300
TELNYX_PUBLIC_KEY_BYTES = 32
TELNYX_SIGNATURE_BYTES = 64
from api.constants import TELNYX_WEBHOOK_VERIFICATION_OPTIONAL
from api.enums import WorkflowRunMode
from api.services.telephony.base import (
CallInitiationResult,
@ -211,12 +210,6 @@ class TelnyxProvider(TelephonyProvider):
return False
if not self.webhook_public_key:
# REMOVE-AFTER 2026-05-15: transition window. Allow webhooks
# through for configs that haven't added the key yet. Remove this
# branch along with TELNYX_WEBHOOK_VERIFICATION_OPTIONAL after
# the cutoff.
if TELNYX_WEBHOOK_VERIFICATION_OPTIONAL:
return True
logger.error("Missing Telnyx webhook_public_key configuration")
return False

View file

@ -153,45 +153,16 @@ async def test_verify_inbound_signature_rejects_missing_config_public_key():
_, headers = _signed_headers(body)
provider = _provider()
# REMOVE-AFTER 2026-05-15: drop the patch wrapper once
# TELNYX_WEBHOOK_VERIFICATION_OPTIONAL is removed; the bare call below
# will then assert the only path.
with patch(
"api.services.telephony.providers.telnyx.provider.TELNYX_WEBHOOK_VERIFICATION_OPTIONAL",
False,
):
result = await provider.verify_inbound_signature(
"https://example.test/api/v1/telephony/inbound/run",
json.loads(body),
headers,
body,
)
result = await provider.verify_inbound_signature(
"https://example.test/api/v1/telephony/inbound/run",
json.loads(body),
headers,
body,
)
assert result is False
# REMOVE-AFTER 2026-05-15: delete this whole test along with the
# TELNYX_WEBHOOK_VERIFICATION_OPTIONAL flag.
@pytest.mark.asyncio
async def test_verify_inbound_signature_allows_missing_key_when_optional_flag_set():
body = _body()
_, headers = _signed_headers(body)
provider = _provider()
with patch(
"api.services.telephony.providers.telnyx.provider.TELNYX_WEBHOOK_VERIFICATION_OPTIONAL",
True,
):
result = await provider.verify_inbound_signature(
"https://example.test/api/v1/telephony/inbound/run",
json.loads(body),
headers,
body,
)
assert result is True
@pytest.mark.asyncio
async def test_verify_inbound_signature_reads_headers_case_insensitively():
body = _body()