Microsoft 365 connector for Piilot — Outlook, OneDrive, SharePoint, Teams via Microsoft Graph
Project description
piilot-pack-microsoft-365
Plugin Piilot pour Microsoft 365 — accès Outlook, OneDrive, SharePoint et Teams via l'API Microsoft Graph, avec gating granulaire côté admin company et HITL systématique sur toutes les écritures.
Statut : v0.1 — release initiale (Outlook + OneDrive + SharePoint + Teams).
Surface v0.1
| Service | Lecture | Écriture (HITL) | Admin consent Microsoft ? |
|---|---|---|---|
| Outlook | search / read / list | send_mail | Non (user delegated) |
| OneDrive | search / list / download | upload_file | Non |
| SharePoint | list_sites / files / download | upload_file | Oui (Sites.*.All) |
| Teams | list_chats / channels / read | send_message | Oui (ChannelMessage.Read.All) |
Soit 14 tools agents, dont 4 en HITL (pattern PLT-28). Excel + Teams Bot (= chantier C14 distinct) reportés en v0.2.
Architecture
piilot-pack-microsoft-365/
├── piilot_pack_microsoft_365/
│ ├── __init__.py # Plugin entry point — register_* + register_module
│ ├── _db.py # connections + scope_grants helpers (encrypted)
│ ├── oauth.py # OAuth2 flow, state token, exchange/refresh
│ ├── client.py # GraphAPIClient (httpx wrapper)
│ ├── connector.py # SCOPE_GROUPS + admin_consent_required
│ ├── routes/
│ │ ├── oauth.py # /authorize-url /callback /admin-consent-url /status /disconnect
│ │ └── scopes.py # GET / + PUT / (8 toggles)
│ └── tools/
│ ├── _auth.py # resolve_access_token + ensure_permission (fail-closed)
│ ├── outlook.py # 4 tools — search, read, list, send_mail (HITL)
│ ├── onedrive.py # 4 tools — search, list, download, upload_file (HITL)
│ ├── sharepoint.py # 4 tools — list_sites, list_files, download, upload (HITL)
│ └── teams.py # 4 tools — list_chats, list_channels, read, send (HITL)
├── frontend/ # piilot-pack-microsoft-365-ui (npm package)
│ ├── package.json
│ └── src/
│ ├── index.ts # register(core) entry
│ ├── MicrosoftSettingsView.tsx # Settings page orchestrator
│ ├── components/ # ConnectionPanel, AdminConsentPanel, ScopeTogglesPanel
│ ├── hooks/ # useMicrosoftStatus, useScopeGrants
│ ├── locales/{fr,en}.json # ~25 keys under "microsoft365" namespace
│ └── services/microsoftService.ts
└── tests/
├── conftest.py # autouse stubs for piilot.sdk.{db,crypto}
├── test_oauth.py # 20 tests — pure OAuth helpers (no DB)
├── test_db.py # 19 tests — _db.py with mocked cursor()
├── test_auth.py # 12 tests — resolve_access_token + ensure_permission
└── test_{outlook,onedrive,sharepoint,teams,client,connector,whoami}.py
194/194 tests sur la suite plugin (sans la stack du core).
Gating côté Piilot (admin company)
8 toggles indépendants dans Settings → Microsoft 365, fail-closed par défaut :
☐ Outlook — Lire les emails
☐ Outlook — Envoyer des emails (HITL)
☐ OneDrive — Lire les fichiers
☐ OneDrive — Uploader des fichiers (HITL)
☐ SharePoint — Lire les sites/fichiers
☐ SharePoint — Uploader des fichiers (HITL)
☐ Teams — Lire les messages
☐ Teams — Envoyer des messages (HITL)
Chaque toggle débloque les tools agents correspondants. Si un toggle
est OFF, le tool refuse l'appel avec M365_PERMISSION_DISABLED. Si
le toggle est ON mais que la connexion Microsoft est absente ou
expirée, le tool refuse avec M365_NOT_CONNECTED — l'agent est
formé pour relayer ces deux codes à l'utilisateur.
Gating côté Microsoft (admin tenant)
Les scopes .All (Sites.Read.All, ChannelMessage.Read.All, …)
exigent un admin consent Microsoft Entra avant que les utilisateurs
puissent consentir individuellement.
Le plugin détecte si le tenant a validé l'app et, sinon, propose le lien d'admin consent à l'admin Piilot pour qu'il le transmette à l'admin tenant Microsoft. Le banner jaune dans Settings → Microsoft 365 guide la démarche.
Variables d'environnement
MICROSOFT_CLIENT_ID=<azure_app_id> # partagé avec SSO PLT-37
MICROSOFT_CLIENT_SECRET=<secret_value> # à créer dans Azure App Registration
MICROSOFT_TENANT_ID=common # ou un GUID tenant pour single-tenant
FRONTEND_URL=https://app.piilot.ai # base de la redirection après callback OAuth
L'Azure App Registration est la même que pour l'auth SSO (PLT-37) —
pas d'app Microsoft séparée à créer. Il faut juste y générer un
Client Secret (l'auth SSO utilise PKCE, donc l'app n'avait pas
besoin de secret) et y ajouter les scopes Graph délégués listés
dans connector.SCOPE_GROUPS.
Données stockées
Migration 110_microsoft_365_integrations.sql (versionnée dans le
repo core AICockpit, même convention que Pennylane mig 056) :
integrations_microsoft_365.connections— 1 row par company, tokens chiffrés Fernet viapiilot.sdk.crypto,expires_at,scopes_granted,admin_consent_granted. RLS FORCEd, admin-only.integrations_microsoft_365.scope_grants— jusqu'à 8 rows par company (CHECK contraint surpermission_id). RLS FORCEd, admin-only.
Les access tokens sont rafraîchis proactivement à T-120 secondes via
oauth.refresh_tokens ; un échec de refresh fail-closed (l'agent
renvoie M365_NOT_CONNECTED).
Tests
pip install -e .[dev]
pytest -v
194 tests, ~1.5 s d'exécution. Les tests utilisent un conftest.py
autouse qui rebind piilot.sdk.db.run_in_thread + piilot.sdk.crypto.{encrypt,decrypt}
en stubs déterministes — aucun PG / aucune Fernet réelle.
Release
Backend + frontend publiés ensemble sur un tag unique v<version> via
.github/workflows/release.yml :
| Package | Registry |
|---|---|
piilot-pack-microsoft-365 (backend) |
PyPI / TestPyPI |
piilot-pack-microsoft-365-ui (frontend) |
npm (tag latest ou rc) |
PyPI auth = OIDC Trusted Publisher (sans token stocké). npm auth =
secret NPM_TOKEN dans l'environnement GitHub npm. Le pipeline
refuse le tag si pyproject.toml et frontend/package.json divergent
sur la version — bump les deux ensemble.
Convention :
v0.1.0→ PyPI + npmlatestv0.1.0-rc1→ TestPyPI + npm dist-tagrc(dry run)
Côté core (AICockpit) :
backend/api/requirements.txt → piilot-pack-microsoft-365==<version>
frontend/package.json → "piilot-pack-microsoft-365-ui": "<version>"
Migration 110_microsoft_365_integrations.sql reste dans backend/migrations/
côté core (convention usine).
License
Apache-2.0.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file piilot_pack_microsoft_365-0.1.4.tar.gz.
File metadata
- Download URL: piilot_pack_microsoft_365-0.1.4.tar.gz
- Upload date:
- Size: 67.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
fea33ef4b81dcefd7635f3c455e3f82b42f0f33e11589fe16e100299d3d7f6b0
|
|
| MD5 |
fbbf3501dfb763a44e395fa2f079e310
|
|
| BLAKE2b-256 |
849921a768cb09034f25a848db6a494d067993ee9e1272dc4bffd2c4b3b6e78b
|
Provenance
The following attestation bundles were made for piilot_pack_microsoft_365-0.1.4.tar.gz:
Publisher:
release.yml on Kinetics-Consulting-V2/piilot-pack-microsoft-365
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
piilot_pack_microsoft_365-0.1.4.tar.gz -
Subject digest:
fea33ef4b81dcefd7635f3c455e3f82b42f0f33e11589fe16e100299d3d7f6b0 - Sigstore transparency entry: 1439968111
- Sigstore integration time:
-
Permalink:
Kinetics-Consulting-V2/piilot-pack-microsoft-365@226f9dd04d579ccf10a3e1b26e3a14b812ca2cf8 -
Branch / Tag:
refs/tags/v0.1.4 - Owner: https://github.com/Kinetics-Consulting-V2
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@226f9dd04d579ccf10a3e1b26e3a14b812ca2cf8 -
Trigger Event:
push
-
Statement type:
File details
Details for the file piilot_pack_microsoft_365-0.1.4-py3-none-any.whl.
File metadata
- Download URL: piilot_pack_microsoft_365-0.1.4-py3-none-any.whl
- Upload date:
- Size: 59.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
398b12d9fffd5354606ec656f40e51b401d8b4248fb1fd405e35d18ec9e7e1eb
|
|
| MD5 |
506476e29700ccd865ca74db9d41b006
|
|
| BLAKE2b-256 |
e08ce557ed2e333159eb07ace493956448257dd1d7f0643546e5897f70956339
|
Provenance
The following attestation bundles were made for piilot_pack_microsoft_365-0.1.4-py3-none-any.whl:
Publisher:
release.yml on Kinetics-Consulting-V2/piilot-pack-microsoft-365
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
piilot_pack_microsoft_365-0.1.4-py3-none-any.whl -
Subject digest:
398b12d9fffd5354606ec656f40e51b401d8b4248fb1fd405e35d18ec9e7e1eb - Sigstore transparency entry: 1439968125
- Sigstore integration time:
-
Permalink:
Kinetics-Consulting-V2/piilot-pack-microsoft-365@226f9dd04d579ccf10a3e1b26e3a14b812ca2cf8 -
Branch / Tag:
refs/tags/v0.1.4 - Owner: https://github.com/Kinetics-Consulting-V2
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@226f9dd04d579ccf10a3e1b26e3a14b812ca2cf8 -
Trigger Event:
push
-
Statement type: