Microsoft Authentication Library Extensions
MSAL EX provides a persistence API for saving data on disk, encrypted on Windows, macOS, and Linux, with concurrent data access coordinated by a file lock mechanism. Current version: 1.3.1, released on March 14, 2025. Release cadence: approximately quarterly.
Common errors
-
ModuleNotFoundError: No module named 'distutils'
cause This error occurs in Python 3.12 and later because the `distutils` package, which `msal-extensions` (or its dependency `azure-identity`) historically used for version parsing, was removed from the standard library in Python 3.12.fixUpgrade `msal-extensions` to a version that supports Python 3.12+ (typically 1.0.0 or higher for direct `msal-extensions` usage, or ensure your `azure-identity` dependency is updated to a compatible version like 1.10.0 or newer if `msal-extensions` is a transitive dependency). You might also need to explicitly install a backport of `distutils` if an upgrade is not immediately possible, but updating is the recommended approach. -
ModuleNotFoundError: No module named 'msal-extensions'
cause This error indicates that the `msal-extensions` library has not been installed in your Python environment or is not accessible in the current Python path.fixInstall the library using pip: `pip install msal-extensions`. -
Error: The module '...dpapi.node' was compiled against a different Node.js version using NODE_MODULE_VERSION XX. This version of Node.js requires NODE_MODULE_VERSION YY. Please try re-compiling or re-installing the module....
cause This error typically occurs with `@azure/msal-node-extensions` when the Node.js version used to install the package (which often compiles native binaries like `dpapi.node` via `node-gyp`) differs from the Node.js version used to run the application.fixRecompile or reinstall the module for the current Node.js version. Navigate to your project directory and run `npm rebuild` or `npm install`. -
SyntaxError: Named export 'deletePassword' not found. The requested module 'keytar' is a CommonJS module, which may not support all module.exports as named exports.
cause This issue arises when attempting to import `@azure/msal-node-extensions` into an ES Module (ESM) environment in Node.js, because `msal-node-extensions` internally relies on `keytar`, which is a CommonJS module. Direct named imports from CommonJS modules are not always fully supported in ESM.fixInstead of direct named imports, import the CommonJS module's default export and destructure the required members. For example, change `import { setPassword, getPassword, deletePassword } from 'keytar';` to `import pkg from 'keytar'; const { setPassword, getPassword, deletePassword } = pkg;`. Alternatively, if possible, ensure your Node.js project is configured to run as a CommonJS module.
Warnings
- breaking Ensure that the 'msal' package is installed and up-to-date to avoid compatibility issues.
- gotcha The 'CLIENT_ID' and 'CLIENT_SECRET' environment variables must be set for the script to function correctly.
- breaking The MSAL configuration failed due to 'ValueError: AADSTS90002: Tenant 'your_tenant_id' not found'. This indicates that the tenant ID or tenant name specified in the authority URL is incorrect or does not exist. Double-check your tenant ID or tenant name.
- breaking The tenant ID provided in the authority URL (e.g., 'your_tenant_id') is invalid or a placeholder was used. Ensure the authority URL contains a valid tenant ID or tenant name.
Install
-
pip install msal-extensions
Imports
- FilePersistence
from msal_extensions.persistence import FilePersistence
Quickstart
import os
from msal import ConfidentialClientApplication
from msal_extensions.persistence import FilePersistence
# Set up the persistence layer
cache = FilePersistence('my_cache.bin')
# Initialize the MSAL application
app = ConfidentialClientApplication(
client_id=os.environ.get('CLIENT_ID'),
client_credential=os.environ.get('CLIENT_SECRET'),
authority='https://login.microsoftonline.com/your_tenant_id',
token_cache=cache
)
# Acquire a token
result = app.acquire_token_for_client(scopes=['https://graph.microsoft.com/.default'])
if 'access_token' in result:
print('Access token acquired successfully.')
else:
print('Failed to acquire access token.')