An Azure service that integrates speech processing into apps and services.
Azure Speech SDK: audio logging works with a subscription key but not with an STS token
Speech recognition succeeds with both subscription-key authentication and STS token authentication. However, audio and transcription logs are available only when I supply the subscription key directly to the SDK.
Is this expected behavior, or is additional configuration required for logging with STS token authentication?
Environment
Region: japaneast
Recognition language: en-US
Python Speech SDK: 1.52.0
Runtime: Google Colab
BYOS: Not enabled
Standard speech-to-text model, without a custom deployment
Input: A 4.3-second WAV file, streamed through PushAudioInputStream
Audio format: 16 kHz, 16-bit PCM, mono
Recognition method: recognize_once_async()
The STS token is obtained by exchanging the same Speech resource key at:
POST https://japaneast.api.cognitive.microsoft.com/sts/v1.0/issueToken
This is not a Microsoft Entra ID token.
Observed results
I used the same resource key, region, language, and audio file for both tests. Log retrieval used subscription-key authentication in both cases.
| Recognition authentication | Recognition | Audio/transcription logs |
| STS token | Successful | No logs appeared during five minutes of polling |
| Subscription key | Successful | Both logs appeared on the first check |
Both tests reported EnableAudioLogging: true, returned ResultReason.RecognizedSpeech, and ended the recognition session normally.
Reproduction
Install the dependencies:
%pip install azure-cognitiveservices-speech==1.52.0 requests
Upload a short WAV file containing English speech, encoded as 16 kHz, 16-bit PCM, mono. Update WAV_PATH below.
Run once with USE_STS_TOKEN = True, then again with USE_STS_TOKEN = False.
import getpass
import time
import wave
import requests
import azure.cognitiveservices.speech as speechsdk
KEY = getpass.getpass("Speech resource key: ")
REGION = "japaneast"
LANGUAGE = "en-US"
WAV_PATH = "/content/test_16k.wav"
USE_STS_TOKEN = True
API_ORIGIN = f"https://{REGION}.api.cognitive.microsoft.com"
LOG_URL = (
f"{API_ORIGIN}/speechtotext/v3.2"
f"/endpoints/base/{LANGUAGE}/files/logs"
)
def list_logs():
entries = []
url = LOG_URL
params = {"sasValidityInSeconds": 3600}
while url:
response = requests.get(
url,
headers={"Ocp-Apim-Subscription-Key": KEY},
params=params,
timeout=30,
)
response.raise_for_status()
body = response.json()
entries.extend(body.get("values", []))
url = body.get("@nextLink")
params = None
return entries
def identity(entry):
return entry.get("self") or entry["name"]
with wave.open(WAV_PATH, "rb") as audio:
assert audio.getframerate() == 16000
assert audio.getsampwidth() == 2
assert audio.getnchannels() == 1
assert audio.getcomptype() == "NONE"
assert 0 < audio.getnframes() / 16000 <= 15
before_ids = {identity(entry) for entry in list_logs()}
if USE_STS_TOKEN:
response = requests.post(
f"{API_ORIGIN}/sts/v1.0/issueToken",
headers={"Ocp-Apim-Subscription-Key": KEY},
timeout=30,
)
response.raise_for_status()
config = speechsdk.SpeechConfig(
auth_token=response.text,
region=REGION,
)
else:
config = speechsdk.SpeechConfig(
subscription=KEY,
region=REGION,
)
config.speech_recognition_language = LANGUAGE
config.enable_audio_logging()
print(
"EnableAudioLogging:",
config.get_property(
speechsdk.PropertyId.SpeechServiceConnection_EnableAudioLogging
),
)
stream = speechsdk.audio.PushAudioInputStream(
stream_format=speechsdk.audio.AudioStreamFormat(
samples_per_second=16000,
bits_per_sample=16,
channels=1,
)
)
recognizer = speechsdk.SpeechRecognizer(
speech_config=config,
audio_config=speechsdk.audio.AudioConfig(stream=stream),
)
recognizer.session_stopped.connect(
lambda _: print("Session stopped")
)
future = recognizer.recognize_once_async()
try:
with wave.open(WAV_PATH, "rb") as audio:
while True:
chunk = audio.readframes(1600)
if not chunk:
break
stream.write(chunk)
time.sleep(0.1)
finally:
stream.close()
result = future.get()
print("Result reason:", result.reason)
print("Recognized text:", result.text)
if result.reason == speechsdk.ResultReason.Canceled:
details = speechsdk.CancellationDetails(result)
print("Cancellation reason:", details.reason)
print("Error details:", details.error_details)
for attempt in range(21):
current = list_logs()
new_logs = [
entry for entry in current
if identity(entry) not in before_ids
]
print(
f"Check {attempt + 1}: "
f"total logs={len(current)}, new logs={len(new_logs)}"
)
for entry in new_logs:
print(entry.get("kind"), entry["name"])
if {"Audio", "Transcription"}.issubset(
{entry.get("kind") for entry in new_logs}
):
break
if attempt < 20:
time.sleep(15)
I could not find an authentication-related restriction in the audio and transcription logging documentation.
Does STS token authentication support this logging feature? If so, does it require an additional scope or configuration, or could this be a service/SDK issue?