clearview/docs/plan-mailbox-scanning.md
Ivo Oskamp 70992bca22 Add mailbox permission scanning proposal
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-28 10:16:50 +02:00

7.2 KiB

Plan — Mailbox Permission Scanning

Voorstel voor het uitbreiden van Clearview met mailbox-rechten scanning naast de bestaande SharePoint-scan. Status: voorstel, nog niet geïmplementeerd.

1. Scope & aanpak

In Exchange Online zijn dit de relevante permissie-categorieën:

Permissie Bron Waarop
Full Access / Read Get-MailboxPermission hele mailbox
Send As Get-RecipientPermission identiteit
Send on Behalf mailbox-property GrantSendOnBehalfTo identiteit
Folder delegaties (Calendar, Inbox) Get-MailboxFolderPermission per folder

Microsoft Graph dekt dit slechts gedeeltelijk (vooral folder-permissies). De volledige set vereist Exchange Online PowerShell met certificaat-auth (Connect-ExchangeOnline -CertificateThumbprint ... -AppId ... -Organization ...). Dat sluit goed aan op het bestaande cert-model van Clearview — dezelfde Azure-app kan zowel Sites.FullControl.All (SharePoint) als Exchange.ManageAsApp (Exchange) krijgen.

Voorgestelde aanpak: EXO PowerShell aanroepen vanuit Python via pwsh subprocess, JSON-output retour. Alternatief is pure Graph, maar dan mist Send As / Send on Behalf grotendeels.

Deviation-baseline voor mailboxen: anders dan SharePoint heeft een mailbox geen "root vs. child" hiërarchie waar een baseline uit volgt. Voorstel: rapporteer alle non-default permissies (filter standaard-entries als NT AUTHORITY\SELF, S-1-5-10, default folder-permissies "Default"/"Anonymous=None") als deviation. Dus géén delta-vergelijk, maar wel dezelfde dedup-logica per (principal, role).

2. Layout-wijzigingen frontend

Huidige website is volledig op SharePoint gemodelleerd (één scanflow, één resultaattabel). Voorstel:

a. Scan-type keuze in "Start New Scan"

  • Tabs of segmented control bovenaan: SharePoint Sites / Mailboxes
  • Bij Mailboxes verandert het invoerveld: één UPN/email per regel (geen "skip default sites")
  • CSV-import: extra accept-formaat (kolom UserPrincipalName / Email / Mailbox)

b. Jobs-tabel

  • Nieuwe kolom Type (SharePoint / Mailbox)
  • Tenant-filter blijft, extra filter op type

c. Job Details panel

  • Sectie heading wordt dynamisch: "Targets" blijft, maar URL-kolom wordt "Mailbox" voor mailbox-jobs
  • Permission Deviations tabel krijgt voor mailbox-jobs andere kolommen:
    • Mailbox · Folder (leeg voor mailbox-level) · Permission Type (FullAccess/SendAs/SendOnBehalf/Folder) · Principal · Access Rights
  • SharingLinks-blok wordt verborgen voor mailbox-jobs
  • Site-filter wordt mailbox-filter

d. Tenants-panel

  • In de onboarding-instructies een extra stap erbij: API permission Office 365 Exchange Online → Exchange.ManageAsApp + role Exchange Administrator toekennen aan de service principal. Voor de geautomatiseerde flow betekent dit een extra Graph-call (rol-toekenning kan niet altijd, dus mogelijk handmatige stap).
  • Statuskolom Auth toont al cert/secret; voorstel: extra capability-badge per tenant (SP, EXO) zodat zichtbaar is welke scans mogelijk zijn.

3. Backend-optimalisatie / herstructurering

scanner.py is nu één bestand met SharePoint-specifieke logica én generieke helpers (auth, HTTP, dedup, role-name normalization). Voorstel:

src/clearview_app/scanners/
    __init__.py            # dispatcher: scan(target_type, ...)
    common.py              # AuthConfig, DeviationRecord, ScanResult, ProbeResult,
                           # MSAL token cache, _request_json, _iter_paged,
                           # _deduplicate_hierarchical, role-name normalization
    sharepoint.py          # huidige scan_site_for_deviations + probe_site + resolve_sharing_link_members
    mailbox.py             # nieuw: scan_mailbox_for_deviations + probe_mailbox
                           # roept pwsh aan met EXO-script en parseert JSON
    exo_scripts/
        get-permissions.ps1  # connect + get mailbox/recipient/folder permissions, output JSON
        probe.ps1            # lichtgewicht: Get-EXOMailbox -Identity x | select Identity

Voordelen:

  • scanner.py was richting 540 regels en mengt concerns; opsplitsen maakt testen makkelijker
  • worker.py krijgt één dispatcher-call: scan(target_type, target, auth, progress) ipv. directe import van SharePoint-specifieke functies
  • Toekomstige scan-types (OneDrive, Teams) passen in hetzelfde patroon

Worker.py moet leren: per target weten welke scanner aan te roepen op basis van scan_targets.target_type (of scan_jobs.scan_type).

4. Datamodel

Minimale, niet-brekende wijzigingen — toegepast via bestaand _ensure_schema_columns():

Tabel Nieuwe kolom Default
scan_jobs scan_type VARCHAR(32) 'sharepoint'
scan_targets (geen — site_url blijft, bevat UPN voor mailbox-jobs; of hernoem naar target met DB-view voor compat)
permission_deviations permission_type VARCHAR(32) NULL NULL (voor SP-rows)
permission_deviations object_type krijgt nieuwe waarden: Mailbox, MailboxFolder

Vraag: liever site_url houden als generieke "target identifier" (compacter, geen migratie), of nu hernoemen? Eerste optie is mijn voorstel.

5. API-endpoints

Bestaand blijft werken. Toevoegingen:

POST   /api/scan-jobs            payload krijgt optioneel "scan_type": "sharepoint"|"mailbox"
                                 en "mailboxes": [...] naast/ipv "site_urls"
POST   /api/scan-jobs/import-csv extra "scan_type" form-field
GET    /api/scan-jobs?scan_type=mailbox    filter

Nieuwe response-velden in ScanJobDetail: scan_type, en deviations krijgen permission_type.

6. Onboarding & runtime-vereisten

  • Container: PowerShell 7 (pwsh) en de ExchangeOnlineManagement PS-module installeren in de Docker image. Dit voegt ~150MB toe. Acceptabel?
  • Azure-app: extra permission Office 365 Exchange Online → Exchange.ManageAsApp + Entra-rol "Exchange Administrator" voor de service principal. In Mode A (automated) kan het permission-deel via Graph, het rol-deel meestal niet — handmatige bevestigingsstap nodig.
  • Probe: voor mailboxen één kleine call (Get-EXOMailbox -Identity <upn> -Properties Identity via een korter PS-script) om vroeg te falen op auth/rol.

7. Implementatiestappen (volgorde)

  1. Backend refactor: scanner-module opsplitsen, geen functionele wijziging (groen test)
  2. Datamodel: scan_type + permission_type toevoegen, default 'sharepoint'
  3. Mailbox-scanner: PS-scripts + Python-wrapper + dispatcher; alleen via API testbaar
  4. API: scan-job creatie uitbreiden met scan_type/mailboxes
  5. Frontend: scan-type segment in formulier + dynamische kolommen in details
  6. Onboarding-tekst en build (Dockerfile voor pwsh)
  7. Documentatie: TECHNICAL.md + changelog-develop.md

Open vragen

  1. PowerShell-route akkoord, of liever Graph-only (incompleter, maar pure Python)?
  2. Eén scan-type per job (voorstel), of mengbare jobs (SharePoint + mailboxen door elkaar)?
  3. Baseline voor mailbox: alle non-default rechten als deviation rapporteren (voorstel), of moet er een "expected baseline" per mailbox/tenant configureerbaar worden?
  4. Image-grootte: is +150 MB voor pwsh + EXO-module aanvaardbaar?
  5. site_url kolom hergebruiken als generieke target-identifier, of nu hernoemen naar target?