Microsoft Office + Microsoft 365 — Python Family (parent)
Parent skill for the ms-office-python-* family. Covers Python's Office and Microsoft 365 surface end-to-end: file formats (Excel / Word / PowerPoint), Microsoft Graph APIs (Outlook / Teams / SharePoint / OneDrive), enterprise SSO (MSAL / WAM broker / SAML / Kerberos), and a consolidated security checklist with a runnable validator.
For specialized areas, see companion skills: ms-office-excel-python, ms-office-word-python, ms-office-powerpoint-python, ms-office-graph-python, ms-office-enterprise-sso-python, ms-office-security-python.
This family is complementary, not a replacement, for:
python-auth-security— server-side OAuth/OIDC/SAML/JWT patterns for Python web apps (generic).windows-sso— PowerShell-based AD FS / Entra ID infrastructure administration (no Python).
The family covers what those two don't: Python client code consuming enterprise SSO from desktop / CLI / server contexts and Python automation against Microsoft Office artifacts and Graph endpoints.
1. Overview
The family answers four overlapping questions a Python developer faces in any Microsoft-tenant environment:
- File-format code — read, write, transform Excel / Word / PowerPoint files without needing Office installed.
- Graph code — call Microsoft 365 APIs for mail, calendar, Teams, SharePoint, OneDrive, users, groups.
- Auth code — get a token, with or without a UI, on or off a managed device, with or without a broker.
- Hardening — make sure none of the above leaks secrets, bypasses Conditional Access, or pulls in deprecated libraries.
Each child skill covers one area. The parent covers the cross-cutting concerns: preflight, OS bootstrap, library philosophy, glossary, anti-patterns.
2. Preflight checklist (BEFORE choosing libraries)
Answer these five questions before reading the child skills. The answers determine which child applies and which libraries are appropriate.
| Question | Why it matters |
|---|---|
| Target tenant: Exchange Online (M365) / Exchange Server on-prem / both? | EWS path lives in exchangelib; Graph path lives in msgraph-sdk. Mixed environments need both with explicit dispatching. |
| National cloud: Commercial / GCC / GCC-H / DoD / China (21Vianet) / Germany / Other? | Different authority URLs, different Graph endpoints, different consent / app-registration story. See §12 of ms-office-enterprise-sso-python. |
| Auth context: Domain-joined Windows / Linux desktop / headless server / container in Azure / container elsewhere / CI? | Determines which of the four auth branches (Win broker / Linux broker / headless daemon / Kerberos) you need. See ms-office-enterprise-sso-python §2. |
| Office installed locally: yes / no? | Determines whether xlwings, docx2pdf, and pywin32 COM automation are viable. None of those work on headless Linux. |
| License tier: E3 / E5 / F1-F3 / EDU? | Affects Graph feature availability (E5 unlocks advanced eDiscovery, Defender, etc.; F-line restricts kiosk access). Don't assume tenant-wide Graph access without confirming the license. |
National-cloud preflight banner (D7). If the answer to "national cloud" is anything other than Commercial:
- Authority URL changes (
login.microsoftonline.us,login.microsoftonline.de,login.partner.microsoftonline.cn). - Graph endpoint changes (
graph.microsoft.us,graph.microsoft.de,microsoftgraph.chinacloudapi.cn). - Some Graph endpoints and library features ship later (or never) in sovereign clouds — verify per resource.
- Service Principal app registration ALSO happens in the sovereign portal (different URL).
The child skills assume Commercial unless explicitly noted. Sovereign clouds are flagged at the points where they materially affect code.
3. When to use which child (decision tree)
Start
|
+-- Working with .xlsx / .xls / .xlsb files? -------------------> ms-office-excel-python
|
+-- Working with .docx / .doc / .docm files? ------------------> ms-office-word-python
|
+-- Working with .pptx / .ppt / .potx files? ------------------> ms-office-powerpoint-python
|
+-- Calling Microsoft Graph (mail, calendar, Teams,
| SharePoint, OneDrive, users, groups, admin)? -------------> ms-office-graph-python
|
+-- Authenticating to Entra ID / AD FS from a Python client? -> ms-office-enterprise-sso-python
|
+-- Hardening any of the above (checklist / validator) -------> ms-office-security-python
|
+-- Server-side web-app OAuth/OIDC/SAML/JWT (generic) --------> python-auth-security
|
+-- PowerShell AD FS / Entra ID infrastructure admin --------> windows-sso
A typical "silent SSO from a domain-joined Windows laptop into Outlook via Graph" task pulls in three children: ms-office-enterprise-sso-python (acquire the token), ms-office-graph-python (call the endpoint), ms-office-security-python (verify the result).
4. Family-wide library philosophy
Two opinionated defaults the family enforces unless you have a reason to deviate:
4.1 Cloud-first over file-first for tenant-owned data.
If the data lives in an M365 tenant — mail, calendar, OneDrive files, SharePoint documents, Teams messages — read it via Graph, not via files. Reasons:
- Graph inherits tenant policy (Conditional Access, DLP, audit log).
- File-based code (download .msg via Outlook export, parse with extract-msg) leaves no audit trail on the tenant side.
- Forensic / archival / migration use cases are the exception, not the rule — and they are first-class in
ms-office-graph-python(§10 offline mail parsing).
4.2 Microsoft-blessed library over community wrapper when the gap is small.
msgraph-sdk (Microsoft, Kiota-generated) is preferred over O365 (community wrapper) for new code, even though O365 has a friendlier sync API. Reasons:
- Auto-generated from the OData metadata — keeps up with new endpoints automatically.
- Async-first — matches modern Python.
- Microsoft support story (issues / docs) is direct.
O365 remains a legitimate choice when the friendlier API outweighs the freshness cost (small scripts, prototypes, education).
msal (Microsoft) is preferred over authlib / requests-oauthlib for Microsoft IdPs. authlib is the right call when the IdP is not Microsoft (Okta, Auth0, Keycloak — covered by python-auth-security).
5. Common OS prerequisites (per-OS bootstrap)
System dependencies the family needs across all children. Per-skill install commands are in each child's SKILL.md.
RHEL 9 / AlmaLinux 9 / Rocky 9
sudo dnf install -y python3.12 python3-pip python3-devel \
gcc-c++ krb5-devel libxml2-devel libxslt-devel libffi-devel openssl-devel \
libsecret-devel cyrus-sasl-gssapi
# Optional, per-skill:
# - libpff-devel (for ms-office-graph-python .pst parsing — may need EPEL)
# - libreoffice (for ms-office-word-python / ms-office-powerpoint-python rendering)
# - libxmlsec1-devel (for ms-office-enterprise-sso-python SAML)
Debian 12 / Ubuntu 24.04
sudo apt update
sudo apt install -y python3.12 python3-pip python3-venv python3-dev \
build-essential libkrb5-dev libxml2-dev libxslt1-dev libffi-dev libssl-dev \
libsecret-1-dev libsasl2-modules-gssapi-mit
# Optional, per-skill:
# - libpff-dev (Debian 12 only; Ubuntu may need to build from source)
# - libreoffice
# - libxmlsec1-dev
# - microsoft-identity-broker (for Linux broker — Intune-managed, install from MS repo)
Windows 11
# Python 3.12 from python.org or winget
winget install --id Python.Python.3.12 -e --silent
# Optional, per-skill:
# winget install --id LibreOffice.LibreOffice -e --silent
# winget install --id Microsoft.VCRedist.2015+.x64 -e --silent # required by some COM extensions
# pymsalruntime ships its own DLLs; verify with:
# python -c "import pymsalruntime; print(pymsalruntime.__file__)"
macOS 14+ (Sonoma / Sequoia / Tahoe)
xcode-select --install # REQUIRED to build appscript (xlwings on macOS)
brew install python@3.12
# Optional, per-skill:
# brew install --cask libreoffice # headless conversion — the portable route
# brew install pandoc # pypandoc backend
On macOS, driving installed Office goes through Apple Events, not COM — xlwings and
docx2pdf use the AppleScript bridge (appscript), and the first call raises a TCC consent dialog
that cannot be answered headlessly. That makes macOS live-automation unavailable on CI runners
and launchd jobs for the same practical reason COM is unavailable on Linux.
Read references/macos-automation.md before writing any macOS automation path — it covers the
Apple Events grant, Office's App Sandbox containers, the Apple-silicon Homebrew prefix, and the
cross-platform routes (Graph, Office Scripts, LibreOffice headless) that avoid the problem entirely.
Office installation is NOT a family-wide prerequisite. Only xlwings, docx2pdf, and explicit COM-automation patterns require local Office. The defaults (openpyxl, python-docx, python-pptx, msgraph-sdk) do not. Each child skill flags Office-dependent libraries in its Library Selection table.
6. Common cross-cutting libraries
Libraries every child references. Single source of truth for status + version recommendations is the master family library status table in references/library-status.md.
| Library | Used by | Status | Notes |
|---|---|---|---|
msal |
SSO, Graph | Active (preferred for M365 auth) | Direct Microsoft auth library |
msal-extensions |
SSO, Security | Active | Encrypted token cache (DPAPI / Keychain / libsecret) |
msal[broker] / pymsalruntime |
SSO | Active | WAM broker bindings (Windows); required for CA compliance |
azure-identity |
SSO, Graph | Active | High-level credential abstractions; primarily for Azure SDK |
azure-identity-broker |
SSO | Active (separate package!) | InteractiveBrowserBrokerCredential for Windows AND Linux broker |
msgraph-sdk |
Graph | Active (preferred) | Microsoft-blessed; Kiota-generated; async-first |
cryptography |
All | Active | Foundation; CVE-watch |
defusedxml |
Excel, Word, PowerPoint, Security | Active | XXE defence for stdlib XML parsing |
keyring |
SSO, Security | Active | Cross-platform OS-keyring access |
The full ~40-row table lives in each child's Library Selection section. The status column reflects 2026-05 ecosystem state.
7. Glossary (renames + deprecations developers stumble over)
| Old name | New name | First use |
|---|---|---|
| Azure AD | Entra ID | 2023 — Azure AD renamed to Microsoft Entra ID; Python code still imports as azure.identity |
ADAL (adal library) |
MSAL (msal library) |
ADAL deprecated and end-of-life since June 2023 |
| Office 365 Connectors API | Power Automate Workflows / Graph chatMessage |
Connectors retired 2024-2025; legacy pymsteams targets the old API |
| EWS (Exchange Web Services) | Microsoft Graph | EWS retiring for Exchange Online per Microsoft's announced schedule (disabled-by-default 2026-10-01, permanent shutdown 2027-04-01); verify on Microsoft Learn before locking dates |
xlrd for .xlsx |
openpyxl |
xlrd >= 2.0 only reads .xls, not .xlsx |
requests-kerberos |
requests-gssapi / requests-negotiate-sspi / pyspnego |
Legacy as of 2026-05 |
| Azure DevOps Server credential helpers | azure-identity Managed Identity |
The new path on Azure-hosted CI |
8. In-scope / out-of-scope
In scope:
- Excel (.xlsx, .xls, .xlsb), Word (.docx, .doc, .docm), PowerPoint (.pptx, .ppt, .potx).
- Microsoft Graph: mail / calendar / contacts / Teams chat & channels & meetings / SharePoint / OneDrive / users / groups.
- Auth: MSAL (Win + Linux broker, daemon, device code, certificate), SAML 2.0 SPs, JWT validation, Kerberos / SPNEGO, hardware keys (FIDO2 / smartcard).
- Hardening: per-skill HARD-RULEs + the consolidated checklist + the runnable Python validator.
Out of scope (v1):
- Microsoft Access / Visio / Project / OneNote — single-sentence namecheck in
See Alsoonly; full coverage deferred. - Microsoft Copilot APIs (Copilot Studio / M365 Copilot) — surface still evolving as of 2026-05; deferred to v1.1.
- SharePoint deep collaboration workflows (lists, Power Platform integration) — preflight + recipe in
ms-office-graph-python, but workflow / list / Power Automate coverage deferred to v1.1. - Test corpus + golden-output regression — useful but heavy lift; v1 ships library recommendations verified by approach agents only.
- Air-gapped enterprise scenarios (private PyPI, wheelhouse, offline validator) — Gotchas-level coverage in
ms-office-security-python; full air-gap pattern deferred.
9. Selection cheatsheet
| Need | First-line skill | Library |
|---|---|---|
| "Read this .xlsx file" | ms-office-excel-python |
openpyxl |
| "Write a Word doc and PDF" | ms-office-word-python |
python-docx + docx2pdf (Windows/macOS) OR pypandoc |
| "Send an email through M365 from a service" | ms-office-graph-python |
msgraph-sdk + client-credentials |
| "Get a token silently on a domain-joined laptop" | ms-office-enterprise-sso-python |
msal[broker] + PublicClientApplication(enable_broker_on_windows=True) |
| "Authenticate a Linux service to Graph in CI" | ms-office-enterprise-sso-python |
azure-identity + Workload Identity Federation |
| "Parse an offline .pst archive" | ms-office-graph-python |
libpff-python |
| "Check this codebase for hardcoded secrets / disabled JWT verification / EWS imports" | ms-office-security-python |
python3 -m ms_office_security_check . |
10. Anti-patterns
| Don't | Why |
|---|---|
Use exchangelib to talk to Exchange Online in 2026+ |
EWS retiring for Exchange Online (per Microsoft's announced schedule, verify before relying); use msgraph-sdk |
Use adal for any new code |
EOL since June 2023; use msal |
Use pymsteams for new Teams integrations |
Targets the retired O365 Connectors API; use Workflows OR Graph chatMessage POST |
Use requests-kerberos for new Kerberos code |
Legacy; use requests-gssapi (Linux/macOS) + requests-negotiate-sspi (Windows) + pyspnego |
Mix openpyxl with xlrd for .xlsx |
xlrd >= 2.0 cannot read .xlsx; pick openpyxl |
| Skip the preflight checklist (§2) | Library choice depends on tenant, cloud, auth context, Office presence, license — guessing wastes a sprint |
| Treat MSAL and azure-identity as interchangeable | MSAL is for direct M365 / Graph auth; azure-identity is primarily for Azure SDK and abstracts over many credential sources; see SSO skill §4 for the boundary |
| Hardcode a Graph access token in source | A001/A006-grade finding; ms-office-security-python flags it; use msal + msal-extensions cache |
| Use device-code flow on a managed Windows laptop when a broker is available | Bypasses WAM → token lacks device-compliance claim → Conditional Access blocks or silently downgrades |
| Assume Graph endpoints / features are identical across sovereign clouds | They aren't — preflight per §2 question 2 |
11. Related skills
| Skill | When to use it instead of / alongside this family |
|---|---|
python-auth-security |
Server-side Python web-app OAuth/OIDC/SAML/JWT against non-Microsoft IdPs (Okta, Auth0, Keycloak, Cognito). This family link-and-defers to it for generic JWT validation patterns. |
windows-sso |
PowerShell AD FS / Entra ID infrastructure administration. No Python code. Use when the question is "how do I configure the IdP / WAP / Conditional Access policy", not "how does my Python client talk to it." |
python-flask-developer / python-data-engineer |
When the Python code involves Flask / SQLAlchemy more than it involves Office or Graph. The Office family covers the Office surface; the Flask/data skills cover the surrounding app. |
dep-currency-check |
Run BEFORE writing code — surfaces stale versions / CVEs in the libraries this family recommends. ms-office-security-python validator does NOT duplicate dep-currency-check; they are layered. |
linux-centrify |
When the on-prem authentication path is Centrify-managed (not native Kerberos). The SSO skill covers Kerberos / pyspnego; Centrify-specific configuration lives in linux-centrify. |
Update Triggers (per Codex M-1 — alf will scan these)
The following events should force a review of this skill and its children:
- Microsoft deprecation announcements affecting: EWS, Office 365 Connectors API, ADAL, basic auth for SMTP / IMAP / POP, any msgraph-sdk major version, any
azure-identitymajor version, broker DLL distribution model. - Major version bumps of:
msal(currently 1.x),msgraph-sdk(currently 1.x),azure-identity(currently 1.x),cryptography(CVE-watch),defusedxml. - National-cloud changes — new sovereign endpoints, authority URL changes, GCC-H / DoD onboarding model changes.
- Annual review anniversary: 2027-05-22 (one year after creation). Sweep the family for
pymsteamsremoval eligibility, EWS post-shutdown rule updates, library status table refresh.
See Also
| Resource | Where |
|---|---|
| Microsoft Graph reference | https://learn.microsoft.com/graph/api/overview |
| MSAL Python docs | https://learn.microsoft.com/entra/msal/python/ |
| Azure Identity for Python | https://learn.microsoft.com/python/api/overview/azure/identity-readme |
| EWS retirement timeline (verify before locking dates) | https://learn.microsoft.com/exchange/clients-and-mobile-in-exchange-online/ews-retirement |
| openpyxl docs | https://openpyxl.readthedocs.io |
| python-docx docs | https://python-docx.readthedocs.io |
| python-pptx docs | https://python-pptx.readthedocs.io |
| Microsoft Authentication Library architecture | https://github.com/AzureAD/microsoft-authentication-library-for-python |
| Validator package layout precedent | ~/.claude/skills/dep-currency-check/ |