Skip to content

[Bug] Init of ClientApplication fails on read only filesystems when msal-extensions is installed since 1.32.0 #800

Description

@nluedema

Describe the bug
After upgrading to 1.32.0, initializing ClientApplication fails with the following error when also msal-extensions is installed:

Traceback (most recent call last):
  File "//confidential_client_sample.py", line 42, in <module>
    global_app = msal.ConfidentialClientApplication(
                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/site-packages/msal/application.py", line 664, in __init__
    _msal_extension_check()
  File "/usr/local/lib/python3.12/site-packages/msal/application.py", line 201, in _msal_extension_check
    from msal_extensions import __version__ as v
  File "/usr/local/lib/python3.12/site-packages/msal_extensions/__init__.py", line 11, in <module>
    from .cache_lock import CrossPlatLock
  File "/usr/local/lib/python3.12/site-packages/msal_extensions/cache_lock.py", line 8, in <module>
    import portalocker
  File "/usr/local/lib/python3.12/site-packages/portalocker/__init__.py", line 2, in <module>
    from .utils import (
  File "/usr/local/lib/python3.12/site-packages/portalocker/utils.py", line 418, in <module>
    class BoundedSemaphore(LockBase):
  File "/usr/local/lib/python3.12/site-packages/portalocker/utils.py", line 441, in BoundedSemaphore
    directory: str = tempfile.gettempdir(),
                     ^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/tempfile.py", line 315, in gettempdir
    return _os.fsdecode(_gettempdir())
                        ^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/tempfile.py", line 308, in _gettempdir
    tempdir = _get_default_tempdir()
              ^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/tempfile.py", line 223, in _get_default_tempdir
    raise FileNotFoundError(_errno.ENOENT,
FileNotFoundError: [Errno 2] No usable temporary directory found in ['/tmp', '/var/tmp', '/usr/tmp', '/']

We noticed this problem after our get_token calls started to fail for a azure.identity.ClientSecretCredential in fresh Docker builds for containers with a read-only filesystem. We traced the problem back to an update of msal from version 1.31.1 to 1.32.0. As you can see from the stack trace, the call to _msal_extension_check leads to portalocker being imported, which calls tempfile.gettempdir(). Calls to tempfile.gettempdir() fail on read-only filesystems.

To Reproduce
I was able to reproduce the error with Docker and your confidential_client_sample.py sample.
Here the Dockerfile:

FROM python:3.12.9-slim-bookworm

RUN pip install msal python-dotenv msal-extensions

COPY confidential_client_sample.py confidential_client_sample.py
COPY .env .env

CMD ["python","confidential_client_sample.py"]

Then run the following:

docker build . -t test
docker run --read-only test:latest

Which will result in the traceback shown above.

Expected behavior
Successfully acquiring a token.

What you see instead

Traceback (most recent call last):
  File "//confidential_client_sample.py", line 42, in <module>
    global_app = msal.ConfidentialClientApplication(
                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/site-packages/msal/application.py", line 664, in __init__
    _msal_extension_check()
  File "/usr/local/lib/python3.12/site-packages/msal/application.py", line 201, in _msal_extension_check
    from msal_extensions import __version__ as v
  File "/usr/local/lib/python3.12/site-packages/msal_extensions/__init__.py", line 11, in <module>
    from .cache_lock import CrossPlatLock
  File "/usr/local/lib/python3.12/site-packages/msal_extensions/cache_lock.py", line 8, in <module>
    import portalocker
  File "/usr/local/lib/python3.12/site-packages/portalocker/__init__.py", line 2, in <module>
    from .utils import (
  File "/usr/local/lib/python3.12/site-packages/portalocker/utils.py", line 418, in <module>
    class BoundedSemaphore(LockBase):
  File "/usr/local/lib/python3.12/site-packages/portalocker/utils.py", line 441, in BoundedSemaphore
    directory: str = tempfile.gettempdir(),
                     ^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/tempfile.py", line 315, in gettempdir
    return _os.fsdecode(_gettempdir())
                        ^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/tempfile.py", line 308, in _gettempdir
    tempdir = _get_default_tempdir()
              ^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/tempfile.py", line 223, in _get_default_tempdir
    raise FileNotFoundError(_errno.ENOENT,
FileNotFoundError: [Errno 2] No usable temporary directory found in ['/tmp', '/var/tmp', '/usr/tmp', '/']

The MSAL Python version you are using
1.32.0

Additional context
I assume that this will also affect quite a few others, since running containers with a read-only filesystem is a security best practice.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions