AZURE_CLI_DISABLE_CONNECTION_VERIFICATION does not pass verify=False to MSAL, breaking az login behind TLS proxies
- Dominant language
- Python
- Stars
- 4.6k
- Forks
- 3.5k
- Avg merge
- 3d 2h
- Merged PRs (30d)
- 60
Description
## Summary
`AZURE_CLI_DISABLE_CONNECTION_VERIFICATION=1` does not work for `az login` because the `verify=False` parameter is never passed to MSAL's `PublicClientApplication`. The env var only affects post-auth API requests (via `_debug.py`), not the initial OIDC discovery request that MSAL makes during login.
## Reproduction
```bash
export AZURE_CLI_DISABLE_CONNECTION_VERIFICATION=1
az login --use-device-code
# ERROR: HTTPSConnectionPool(host='login.microsoftonline.com', port=443):
# Max retries exceeded ... SSLCertVerificationError
```
## Environment
- azure-cli 2.82.0
- Python 3.13.11
- Behind Zscaler TLS inspection proxy
## Root cause
In `azure/cli/core/auth/identity.py`, `_msal_app_kwargs` does not include `verify`:
```python
@property
def _msal_app_kwargs(self):
return {
"authority": self._msal_authority,
"token_cache": Identity._msal_token_cache,
"http_cache": Identity._msal_http_cache,
"instance_discovery": self._instance_discovery,
"client_capabilities": None if "AZURE_IDENTITY_DISABLE_CP1" in os.environ else ["CP1"]
# ← no "verify" parameter
}
```
MSAL's `PublicClientApplication.__init__` accepts a `verify` parameter (defaults to `True`) and passes it to `requests.Session().verify`. Since `_msal_app_kwargs` never sets it, the initial OIDC discovery request to `login.microsoftonline.com` always uses `verify=True`.
Meanwhile, `_debug.py:change_ssl_cert_verification()` only patches the post-auth client session — it never runs during `az login`.
## Suggested fix
```python
@property
def _msal_app_kwargs(self):
from ..util import should_disable_connection_verify
kwargs = {
"authority": self._msal_authority,
"token_cache": Identity._msal_token_cache,
"http_cache": Identity._msal_http_cache,
"instance_discovery": self._instance_discovery,
"client_capabilities": None if "AZURE_IDENTITY_DISABLE_CP1" in os.environ else ["CP1"]
}
if should_disable_connection_verify():
kwargs["verify"] = False
return kwargs
```
## Note
Even with this fix, there is a second blocker: urllib3 2.6.0 unconditionally sets `VERIFY_X509_STRICT` on Python 3.13, which makes `verify=False` ineffective at the OpenSSL level. See: urllib3/urllib3#5110.
Both fixes are needed for `az login` to work behind TLS inspection proxies on Python 3.13.
Contributor guide
Assessment
This issue has not been assessed yet.