I have a new Single-Tenant Azure Bot whose incoming messages are all getting 401 Unauthorized from the OpenClaw gateway.
An existing bot (Marcel) with identical config works perfectly. I've spent an entire day debugging and need help.
Environment:
OpenClaw version: 2026.4.26 (be8c246)
OS: Ubuntu 24, Node 22.22.1
Two bots running on same server: Marcel (working) and Diana (broken)
What works (Marcel):
App Type: Single Tenant
Same tenantId, same dmPolicy: allowlist, same allowFrom list
Receives and responds to Teams messages normally
Token structure: iss: https://api.botframework.com, aud: <marcelAppId>
What fails (Diana โ new bot):
App Type: Single Tenant
Identical openclaw.json structure, different appId/appPassword
Azure Bot Web Chat errors show HTTP status code Unauthorized
Token captured via proxy: valid kid in JWKS, correct aud, non-expired exp
OpenClaw logs nothing when rejecting โ no auth error, no debug line
tcpdump confirms Azure IS reaching port 3980 with a valid POST
curl with fresh token to localhost:3980/api/messages returns {"error":"Unauthorized"}
What I've tried:
Verified token with kid: cV98EhAA6kdD9FrJgEGTsfV5jpQ โ present in JWKS
Confirmed https://login.botframework.com/v1/.well-known/openidconfiguration accessible
Confirmed https://graph.microsoft.com/v1.0/ returns 200
Set authType: "secret" explicitly
Ran openclaw configure interactively โ no change
Ran openclaw channels add --channel msteams --use-env โ no change
Compared openclaw.json diff between Marcel and Diana โ structurally identical
Questions:
Is there a known issue with newly created Single-Tenant bots vs older ones in OpenClaw?
Is there a debug/verbose flag to see exactly which JWT validation check is failing?
Could there be an internal registration step (like a first-time handshake) that Marcel completed but Diana hasn't?
Any difference in how OpenClaw handles token validation for new vs existing App Registrations?
Thank you very much