ValueError: Key not found when authenticating with Microsoft Entra ID (Single Tenant)

Bug Report

Summary

I’m getting a ValueError: Key not found error when implementing Microsoft Entra ID authentication following the official Streamlit documentation. The error occurs during the OAuth callback when Streamlit tries to validate the JWT token returned by Microsoft.

Environment

  • Streamlit version: 1.51.0

  • Python version: 3.11.13

  • Authlib version: 1.6.5

  • Deployment: AWS (behind ALB)

  • Microsoft Entra ID configuration: Single tenant

Steps to Reproduce

  1. Register a new application in Microsoft Entra ID with:

    • Supported account types: “Accounts in this organizational directory only (Single tenant)”

    • Redirect URI: https://aws-alb-web-mura-prod-1961644625.us-east-1.elb.amazonaws.com/oauth2callback

    • ID tokens enabled under “Implicit grant and hybrid flows”

  2. Configure .streamlit/secrets.toml:

[auth]
redirect_uri = "https://aws-alb-web-mura-prod-1961644625.us-east-1.elb.amazonaws.com/oauth2callback"
cookie_secret = "xxx"
client_id = "xxx"
client_secret = "xxx"
server_metadata_url = "https://login.microsoftonline.com/{tenant-id}/v2.0/.well-known/openid-configuration"
  1. Create a simple app following the documentation:
import streamlit as st

def login_screen():
    st.header("This app is private.")
    st.subheader("Please log in.")
    st.button("Log in with Microsoft", on_click=st.login)

if not st.user.is_logged_in:
    login_screen()
else:
    st.header(f"Welcome, {st.user.name}!")
    st.button("Log out", on_click=st.logout)
```

4. Run the app and attempt to log in with a Microsoft account

### Expected Behavior
User should be authenticated successfully and see the welcome message.

### Actual Behavior
After Microsoft redirects back to the application, the following error occurs:
```
Traceback (most recent call last):
  File "/path/to/authlib/integrations/base_client/sync_openid.py", line 85, in load_key
    return jwk_set.find_by_kid(
ValueError: Key not found

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/path/to/streamlit/web/server/oauth_authlib_routes.py", line 172, in get
    token = client.authorize_access_token(self)
  File "/path/to/streamlit/web/server/oidc_mixin.py", line 95, in authorize_access_token
    userinfo = self.parse_id_token(
  File "/path/to/authlib/integrations/base_client/sync_openid.py", line 67, in parse_id_token
    claims = _jwt.decode(
  File "/path/to/authlib/jose/rfc7519/jwt.py", line 104, in decode
    data = self._jws.deserialize_compact(s, load_key, decode_payload)
  File "/path/to/authlib/jose/rfc7515/jws.py", line 114, in deserialize_compact
    algorithm, key = self._prepare_algorithm_key(jws_header, payload, key)
  File "/path/to/authlib/jose/rfc7515/jws.py", line 271, in _prepare_algorithm_key
    key = key(header, payload)
  File "/path/to/authlib/integrations/base_client/sync_openid.py", line 91, in load_key
    return jwk_set.find_by_kid(
  File "/path/to/authlib/jose/rfc7517/key_set.py", line 37, in find_by_kid
    raise ValueError("Key not found")
ValueError: Key not found

Additional Context

  • The official documentation example uses server_metadata_url = "https://login.microsoftonline.com/consumers/v2.0/.well-known/openid-configuration" for personal Microsoft accounts

  • I’m using a single-tenant configuration with my organization’s tenant ID

  • The OIDC metadata endpoint is accessible and returns valid JSON: https://login.microsoftonline.com/{tenant-id}/v2.0/.well-known/openid-configuration

  • I’ve verified that the redirect URI matches exactly in both Azure and secrets.toml