-
Notifications
You must be signed in to change notification settings - Fork 219
Support ISO8601-ish formats for expires_on in Managed Identity#900
Support ISO8601-ish formats for expires_on in Managed Identity #900Copilot wants to merge 2 commits into
expires_on in Managed Identity #900Conversation
Agent-Logs-Url: https://github.com/AzureAD/microsoft-authentication-library-for-python/sessions/988c4f0a-9dee-4865-9c61-1dccdfd9ea49 Co-authored-by: gladjohn <90415114+gladjohn@users.noreply.github.com>
expires_on in Managed Identity (追記ここまで)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
This PR improves Managed Identity token handling by making expires_on parsing resilient to non-epoch formats returned by some MI endpoints (e.g., App Service, Azure ML), preventing failures when int(expires_on) would previously raise.
Changes:
- Added
_parse_expires_on(raw: str) -> intwith a cascading parsing strategy (epoch → ISO8601-ish → Azure SDK-style strptime formats). - Updated App Service and Azure ML MI flows to compute
expires_inusing_parse_expires_on(...). - Added unit tests covering the supported
expires_onformats.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 5 comments.
| File | Description |
|---|---|
msal/managed_identity.py |
Adds _parse_expires_on() and switches App Service/Azure ML to use it when normalizing expires_in. |
tests/test_mi.py |
Adds coverage for multiple expires_on string formats and expected epoch conversions. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Copilot
AI
Apr 11, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
socket is imported but not used anywhere in this module (only referenced in a comment). Please remove the unused import to avoid lint/maintenance noise.
Copilot
AI
Apr 11, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The loop variable name format shadows Python’s built-in format() function. Consider renaming it (e.g., fmt) to avoid shadowing and improve readability.
Copilot
AI
Apr 11, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
calendar.timegm(time.strptime(...)) ignores the parsed %z offset (time tuples don’t apply the timezone offset when converted this way). If expires_on ever includes a non-+00:00 offset, this will compute the wrong epoch and thus wrong expires_in. Prefer parsing into a timezone-aware datetime (e.g., datetime.datetime.strptime(...).timestamp()) so offsets are honored.
Copilot
AI
Apr 11, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The variable name input shadows Python’s built-in input() function. Rename it (e.g., raw/expires_on) to avoid shadowing and make the test intent clearer.
Copilot
AI
Apr 11, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
raw is mutated during ISO preprocessing, and the final exception reports the possibly-normalized value rather than the original input. Preserve the original string (e.g., original_raw = raw) and include that in the ManagedIdentityError message to make troubleshooting easier.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The Z → +00:00 normalization should run before the regex, not after — otherwise an input like 2024年10月18日T19:51:37.0000000Z slips through (regex requires [+-]HH:MM, so it doesn't strip the 7-digit microseconds), then fromisoformat rejects it on Py<3.11 and we end up raising ManagedIdentityError for what should be a supported shape.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No happy path test for failure
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
On line 645 the comment right there even says "Azure SDK team's test obtained a string." Route this through _parse_expires_on(payload["expires_on"]) like App Service and Machine Learning do.
@4gust
4gust
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Approved with couple of changes
Uh oh!
There was an error while loading. Please reload this page.
Managed Identity endpoints (particularly App Service and Machine Learning) can return
expires_onin non-epoch formats (e.g.,2024年10月18日T19:51:37.0000000+00:00as seen in the dotnet MSAL issue tracker), causingint()parsing to fail. This recreates PR #804 (original author left the team, CLA blocked merge).Changes
msal/managed_identity.py: Adds_parse_expires_on(raw: str) -> intwith a cascading parse strategy:datetime.fromisoformat(), with regex pre-processing to strip 7-digit microseconds on Python < 3.11 and normalizeZsuffix%m/%d/%Y %H:%M:%S %zand%m/%d/%Y %I:%M:%S %p %zManagedIdentityErrorif all attempts failReplaces bare
int(payload["expires_on"])calls in_obtain_token_on_app_service()and_obtain_token_on_machine_learning()with_parse_expires_on().tests/test_mi.py: AddsExpiresOnTestCasecovering all supported formats:Original prompt
This pull request was created from Copilot chat.