|
| 1 | +Metadata-Version: 2.4 |
| 2 | +Name: msal-key-attestation |
| 3 | +Version: 0.1.0 |
| 4 | +Summary: KeyGuard attestation support for MSAL Python MSI v2 (mTLS PoP). Provides AttestationClientLib.dll bindings for Windows Credential Guard key attestation. |
| 5 | +Home-page: https://github.com/AzureAD/microsoft-authentication-library-for-python |
| 6 | +Author: Microsoft Corporation |
| 7 | +Author-email: nugetaad@microsoft.com |
| 8 | +License: MIT |
| 9 | +Classifier: Development Status :: 3 - Alpha |
| 10 | +Classifier: Programming Language :: Python :: 3 :: Only |
| 11 | +Classifier: Programming Language :: Python :: 3 |
| 12 | +Classifier: Programming Language :: Python :: 3.8 |
| 13 | +Classifier: Programming Language :: Python :: 3.9 |
| 14 | +Classifier: Programming Language :: Python :: 3.10 |
| 15 | +Classifier: Programming Language :: Python :: 3.11 |
| 16 | +Classifier: Programming Language :: Python :: 3.12 |
| 17 | +Classifier: Programming Language :: Python :: 3.13 |
| 18 | +Classifier: Programming Language :: Python :: 3.14 |
| 19 | +Classifier: License :: OSI Approved :: MIT License |
| 20 | +Classifier: Operating System :: Microsoft :: Windows |
| 21 | +Requires-Python: >=3.8 |
| 22 | +Description-Content-Type: text/markdown |
| 23 | +Requires-Dist: msal>=1.32.0 |
| 24 | + |
| 25 | +# msal-key-attestation |
| 26 | + |
| 27 | +KeyGuard attestation support for **MSAL Python** MSI v2 (mTLS Proof-of-Possession). |
| 28 | + |
| 29 | +This package provides the `AttestationClientLib.dll` bindings for Windows |
| 30 | +Credential Guard / KeyGuard key attestation via Azure Attestation (MAA). |
| 31 | + |
| 32 | +## Installation |
| 33 | + |
| 34 | +```bash |
| 35 | +pip install msal msal-key-attestation |
| 36 | +``` |
| 37 | + |
| 38 | +## Prerequisites |
| 39 | + |
| 40 | +- **Windows** with Credential Guard / KeyGuard enabled (Azure VM with VBS) |
| 41 | +- **AttestationClientLib.dll** — place it next to your application, or set |
| 42 | + `ATTESTATION_CLIENTLIB_PATH` environment variable to its full path. |
| 43 | + |
| 44 | +## Usage |
| 45 | + |
| 46 | +```python |
| 47 | +import msal, requests |
| 48 | + |
| 49 | +client = msal.ManagedIdentityClient( |
| 50 | + msal.SystemAssignedManagedIdentity(), |
| 51 | + http_client=requests.Session(), |
| 52 | +) |
| 53 | + |
| 54 | +# with_attestation_support=True auto-discovers msal-key-attestation |
| 55 | +result = client.acquire_token_for_client( |
| 56 | + resource="https://graph.microsoft.com", |
| 57 | + mtls_proof_of_possession=True, |
| 58 | + with_attestation_support=True, |
| 59 | +) |
| 60 | + |
| 61 | +if "access_token" in result: |
| 62 | + print(f"Token type: {result['token_type']}") # mtls_pop |
| 63 | + print(f"Cert thumbprint: {result.get('cert_thumbprint_sha256', 'N/A')}") |
| 64 | +else: |
| 65 | + print(f"Error: {result.get('error_description', result)}") |
| 66 | +``` |
| 67 | + |
| 68 | +## How it works |
| 69 | + |
| 70 | +1. MSAL Python's MSI v2 flow creates a KeyGuard-protected RSA key (via NCrypt) |
| 71 | +2. When `with_attestation_support=True`, MSAL auto-imports this package |
| 72 | +3. This package calls `AttestationClientLib.dll` to attest the key with MAA |
| 73 | +4. The attestation JWT is cached in-memory (~90% of its lifetime) |
| 74 | +5. MSAL sends the JWT + CSR to IMDS `/issuecredential` |
| 75 | +6. IMDS returns a short-lived certificate, which MSAL uses for mTLS token |
| 76 | + acquisition |
| 77 | + |
| 78 | +## Architecture |
| 79 | + |
| 80 | +``` |
| 81 | +┌─────────────────────────────────────────┐ |
| 82 | +│ msal (pip install msal) │ |
| 83 | +│ │ |
| 84 | +│ ManagedIdentityClient │ |
| 85 | +│ └─ acquire_token_for_client() │ |
| 86 | +│ mtls_proof_of_possession=True │ |
| 87 | +│ with_attestation_support=True │ |
| 88 | +│ │ |
| 89 | +│ msal.msi_v2 (core flow) │ |
| 90 | +│ - NCrypt KeyGuard key (ctypes) │ |
| 91 | +│ - PKCS#10 CSR builder │ |
| 92 | +│ - IMDS getplatformmetadata │ |
| 93 | +│ - IMDS issuecredential │ |
| 94 | +│ - Crypt32 cert binding │ |
| 95 | +│ - WinHTTP/SChannel mTLS │ |
| 96 | +│ - Certificate cache (in-memory) │ |
| 97 | +└────────────────┬────────────────────────┘ |
| 98 | + │ auto-discovers via import |
| 99 | +┌────────────────▼────────────────────────┐ |
| 100 | +│ msal-key-attestation │ |
| 101 | +│ (pip install msal-key-attestation) │ |
| 102 | +│ │ |
| 103 | +│ create_attestation_provider() │ |
| 104 | +│ - AttestationClientLib.dll bindings │ |
| 105 | +│ - MAA token cache (in-memory) │ |
| 106 | +└─────────────────────────────────────────┘ |
| 107 | +``` |
| 108 | + |
| 109 | +## Environment Variables |
| 110 | + |
| 111 | +| Variable | Description | |
| 112 | +|---|---| |
| 113 | +| `ATTESTATION_CLIENTLIB_PATH` | Full path to `AttestationClientLib.dll` | |
| 114 | +| `MSAL_MSI_V2_ATTESTATION_CACHE` | `"0"` to disable MAA JWT caching | |
| 115 | + |
| 116 | +## License |
| 117 | + |
| 118 | +MIT |
0 commit comments