Skip to content

Latest commit

 

History

14 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

MS Change Intelligence

MS Change Intelligence è una dashboard web leggera per raccogliere, normalizzare, consultare e filtrare gli aggiornamenti ufficiali di Microsoft 365 Roadmap e Azure Updates.

Il progetto privilegia un'architettura static-first, un footprint operativo ridotto e la continuità di servizio: il browser consulta un dataset JSON pre-generato, mentre un collector Python aggiorna i dati in modo atomico e conserva l'ultima versione valida se una fonte upstream non è disponibile o restituisce dati incompleti.

Applicazione pubblicata

La versione attualmente distribuita su Azure App Service è raggiungibile all'indirizzo:

Obiettivi

Il progetto nasce per offrire una vista operativa unica sugli aggiornamenti Microsoft senza introdurre un database, un framework frontend o dipendenze client di terze parti.

Gli obiettivi principali sono:

  • aggregare fonti Microsoft ufficiali;
  • mantenere una finestra mobile di tre anni basata sul campo Last modified;
  • offrire una vista predefinita sugli ultimi 30 giorni;
  • evidenziare rilasci, ritiri, modifiche e aggiornamenti che richiedono un'azione;
  • consentire ricerca e filtraggio interamente nel browser;
  • non inviare query, indirizzi IP o dati di navigazione a servizi di analisi esterni;
  • continuare a servire l'ultimo dataset valido durante errori o rallentamenti upstream;
  • funzionare come applicazione WSGI gestita su Azure App Service.

Funzionalità

Raccolta dati

  • Microsoft 365 Roadmap tramite RSS ufficiale.
  • Azure Updates tramite endpoint OData v4 ufficiale.
  • Paginazione completa dell'endpoint Azure con controllo di @odata.count.
  • Convalida restrittiva degli URL di continuazione OData.
  • Limite alle dimensioni delle risposte upstream.
  • Deduplicazione per identificatore della fonte.
  • Normalizzazione di entità HTML, markup, spaziatura e date.
  • Riduzione controllata delle descrizioni troppo lunghe.
  • Finestra mobile di conservazione di tre anni.
  • Pubblicazione atomica di data.json e data.json.gz.
  • Protezione dell'ultimo dataset valido in caso di raccolta parziale o fallita.

Microsoft CVEs & KBs

  • MSRC CVRF v3.0 come fonte ufficiale. Le keyword Azure, Dynamics, GitHub, Fabric, Microsoft, M365, Office, PowerShell, Remote Desktop, Surface, System Center, Teams, Visual Studio e Windows sono applicate come filtro case-insensitive *keyword* durante il parsing; i tag prodotto originali CVRF vengono mantenuti nel dataset.
  • Azure Linux è escluso esplicitamente dal filtro Azure.
  • Finestra mobile di 12 mesi basata su InitialReleaseDate, individuata tramite il filtro dell'indice /updates.
  • Un documento CVRF mensile scaricato per ogni mese della finestra.
  • Deduplicazione per CVE e normalizzazione di severity, KB, CWE, exploit e disclosure; i nomi prodotto non vengono rinominati.
  • La vista CVE applica di default il filtro temporale degli ultimi 30 giorni; la retention backend resta di 12 mesi.
  • Pubblicazione atomica separata di cve-data.json e cve-data.json.gz.
  • Limite di download CVRF separato dal limite RSS/OData, necessario per i documenti mensili più grandi.
  • Ultimo dataset valido mantenuto in caso di errore upstream.

Dashboard

  • Ricerca per titolo, descrizione, prodotto e feature ID.
  • Filtri per fonte, prodotto, stato, azione e periodo.
  • Vista predefinita sugli ultimi 30 giorni.
  • Ordinamento per data o prodotto.
  • Filtri serializzati nella query string, quindi condivisibili tramite URL.
  • Caricamento progressivo delle schede, 60 elementi alla volta.
  • Conteggi riepilogativi per elementi visibili, ritiri, azioni richieste e aggiornamenti recenti.
  • Interfaccia responsive, accessibile da tastiera e compatibile con tema chiaro/scuro.
  • Scorciatoia / per portare il focus sul campo di ricerca.
  • Rendering sicuro mediante textContent; il markup proveniente dalle fonti non viene inserito nel DOM.

Aggiornamento stale-only

Nella distribuzione WSGI il client controlla l'età del dataset. Se generatedAt ha almeno 24 ore:

  1. il browser invia POST /api/refresh-if-stale;
  2. il server acquisisce un lock non bloccante;
  3. un solo processo esegue il collector;
  4. gli altri client ricevono 202 running e attendono;
  5. il dataset viene ricaricato solo dopo la pubblicazione di una generazione più recente.

Dopo un errore upstream viene applicato un backoff persistente di 15 minuti, 1 ora e infine 6 ore. Durante tutto il processo il dataset precedente rimane disponibile.

La vista CVE usa lo stesso protocollo e la stessa soglia di 24 ore, ma con endpoint, lock e stato indipendenti:

  • vista principale: POST /api/refresh-if-stalecollector.pydata.json;
  • vista CVE: POST /api/refresh-cves-if-stalecve_collector.pycve-data.json.

Architettura

Microsoft 365 Roadmap RSS ─┐
                           ├─> collector.py ─> data.json + data.json.gz ─┐
Azure Updates OData v4 ────┘                                             │
MSRC CVRF /updates ────────> cve_collector.py ─> cve-data.json + .gz ────┤
                                                                         v
Browser <─ HTML/CSS/JavaScript <─ server.py / Gunicorn
   ├──── POST refresh-if-stale ───────┘
   └──── POST refresh-cves-if-stale ──┘

Il repository non richiede un database e non contiene un processo di raccolta residente. Il collector è un comando one-shot avviato dall'applicazione durante una procedura di aggiornamento controllata.

Struttura del repository

.
├── collector.py                         Collector RSS/OData e pubblicazione atomica
├── server.py                            Applicazione WSGI e refresh stale-only
├── startup.sh                           Avvio Gunicorn per Azure App Service
├── requirements.txt                     Dipendenza runtime Gunicorn
├── index.html                           Dashboard principale
├── styles.css                           Stili responsive
├── app.js                               Filtri, ricerca, ordinamento e rendering
├── app-utils.js                         Utility frontend condivise e testabili
├── refresh-client.js                    Protocollo client di aggiornamento
├── demo.html / demo.js                  Demo deterministica degli stati di refresh
├── cve_collector.py                     Collector MSRC CVRF separato
├── cves.html / cves.css / cves.js       Vista isolata CVEs & KBs
├── mschangeintelligence.png             Logo dell'applicazione
├── favicon-16x16.png / favicon-32x32.png
├── favicon-96x96.png / apple-touch-icon.png Icone favicon dell'applicazione
├── data.json / data.json.gz             Dataset last-known-good principale
├── cve-data.json / cve-data.json.gz     Dataset last-known-good CVE, 12 mesi
├── samples/                             Fixture RSS per test e sviluppo offline
├── test_collector.py                    Test del collector principale
├── test_cve_collector.py                Test del parser CVRF
├── test_server.py                       Test del server WSGI
├── test_app.js                          Test del frontend principale
├── test_cves.js                          Test del contratto frontend CVE
├── test_refresh_client.js               Test del protocollo di refresh
└── test_demo.js                         Test della demo

Le directory build/, __pycache__/, gli ambienti virtuali e gli stati runtime non fanno parte della codebase versionata.

Requisiti

Runtime

  • Linux o un ambiente compatibile con fcntl;
  • Python 3.11 o successivo;
  • accesso HTTPS alle fonti Microsoft;
  • Gunicorn 23.0.0 per l'esecuzione WSGI.

Sviluppo e test frontend

  • Node.js recente;
  • nessun pacchetto npm richiesto.

Il collector utilizza esclusivamente la libreria standard Python. Gunicorn è l'unica dipendenza Python esterna del runtime web.

Configurazione

Variabile Predefinito Descrizione
PORT 8000 Porta utilizzata da startup.sh.
DASHBOARD_ROOT directory di server.py Directory degli asset applicativi.
DASHBOARD_DATA_DIR DASHBOARD_ROOT in server.py; /home/data/microsoft-release-dashboard in startup.sh Directory persistente e scrivibile per dataset, lock e stato di backoff.
DASHBOARD_ORIGIN origine derivata dalla richiesta Origine autorizzata per il POST same-origin di refresh su Azure App Service.

Non sono richieste chiavi API per le fonti Microsoft attualmente utilizzate.

Dataset

Il documento generato contiene quattro sezioni principali:

{
  "schemaVersion": 1,
  "generatedAt": "2026-07-30T16:12:45Z",
  "sources": {},
  "summary": {},
  "retention": {},
  "items": []
}

Ogni elemento normalizzato contiene, tra gli altri:

  • id: identificatore globale composto da fonte e ID upstream;
  • source e sourceKey;
  • featureId;
  • title e description normalizzati;
  • url limitato a host Microsoft approvati;
  • updated in UTC ISO 8601;
  • status, phase, action e updateType;
  • product, products e categories.

La classificazione action per Microsoft 365 è euristica e basata su categorie e parole chiave. Non sostituisce la valutazione del testo ufficiale collegato nella scheda.

Test

La suite non richiede pytest né dipendenze npm.

python3 -m unittest -q test_server.py test_collector.py test_cve_collector.py
node test_app.js
node test_cves.js
node test_refresh_client.js
node test_demo.js

Controlli sintattici aggiuntivi:

python3 -m py_compile collector.py cve_collector.py server.py test_collector.py test_server.py test_cve_collector.py
node --check app.js
node --check cves.js
node --check app-utils.js
node --check refresh-client.js
node --check demo.js

I test coprono, tra l'altro:

  • parsing e normalizzazione RSS/OData;
  • cutoff mobile e gestione del 29 febbraio;
  • paginazione, loop e host OData autorizzati;
  • conteggi completi e deduplicazione;
  • scrittura atomica e coerenza gzip;
  • routing WSGI, cache validation ed header di sicurezza;
  • soglia esatta delle 24 ore;
  • lock concorrente, backoff persistente e recovery;
  • protocollo client fresh, running, updated, backoff e failed;
  • filtri iniziali e isolamento della vista CVE;
  • parsing CVRF, deduplicazione CVE e coerenza gzip del dataset CVE;
  • endpoint CVE stale-only con lock e stato indipendenti.

Distribuzione su Azure App Service

startup.sh è predisposto per un App Service Linux con runtime Python:

/home/site/wwwroot/startup.sh

La configurazione usa:

  • un worker Gunicorn;
  • worker class gthread con due thread;
  • timeout di 210 secondi;
  • DASHBOARD_DATA_DIR=/home/data/microsoft-release-dashboard come storage persistente;
  • porta fornita da Azure tramite PORT.

L'applicazione è pubblicata sotto /microsoft/. Gli endpoint di refresh sono /api/refresh-if-stale per la dashboard principale e /api/refresh-cves-if-stale per la vista CVE.

Impostazioni raccomandate per App Service:

  • HTTPS obbligatorio;
  • TLS minimo 1.2 o superiore;
  • FTPS disabilitato se non necessario;
  • HTTP/2 abilitato;
  • health probe sulla dashboard;
  • persistenza della directory /home/data.

Pipeline GitHub Actions con Azure OIDC

Il workflow .github/workflows/deploy-azure.yml esegue test, controlli sintattici, validazione del dataset, creazione di un pacchetto runtime pulito, autenticazione passwordless tramite GitHub OIDC, deploy e verifica HTTP dell'applicazione.

Le GitHub Actions di terze parti sono referenziate tramite commit SHA immutabili. Il pacchetto contiene esclusivamente i file runtime approvati e un deployment-metadata.json generato durante la build con repository, commit e identificativo della run.

Il repository usa le seguenti GitHub Actions variables, senza publish profile o client secret:

  • AZURE_CLIENT_ID;
  • AZURE_TENANT_ID;
  • AZURE_SUBSCRIPTION_ID;
  • AZURE_RESOURCE_GROUP;
  • AZURE_WEBAPP_NAME;
  • AZURE_DEPLOY_ENABLED.

Il job di test viene eseguito a ogni push su main. Il job di produzione è attivo e viene eseguito dopo il completamento positivo dei controlli. L'identità Entra federata usa il ruolo minimo Website Contributor, limitato alla singola Web App, e la federazione è vincolata al GitHub environment production.

Ogni aggiornamento di main avvia automaticamente il deploy su Azure App Service e la successiva verifica HTTP dell'applicazione pubblicata.

Sicurezza e affidabilità

Fonti e contenuti

  • sono accettate soltanto fonti HTTPS definite nel collector;
  • gli URL OData di continuazione sono limitati a host e path Microsoft previsti;
  • i link mostrati agli utenti sono limitati a host Microsoft approvati;
  • il markup upstream viene rimosso e non è renderizzato con innerHTML;
  • le descrizioni sono limitate a 2.000 caratteri.

HTTP

Il server applica:

  • Content Security Policy restrittiva;
  • X-Frame-Options: DENY;
  • X-Content-Type-Options: nosniff;
  • Referrer-Policy: no-referrer;
  • richiesta same-origin per il refresh;
  • limite di 1 KiB al corpo della richiesta;
  • assenza di CORS permissivo;
  • ETag, Last-Modified e supporto 304;
  • Vary: Accept-Encoding per il dataset.

Continuità del dato

  • una raccolta incompleta non sostituisce il dataset valido;
  • JSON e gzip vengono generati prima della sostituzione atomica;
  • il refresh usa un lock Linux non bloccante;
  • errori upstream attivano un backoff persistente;
  • il browser continua a visualizzare i dati precedenti.

Privacy

La dashboard non integra analytics, tracker, CDN JavaScript, font remoti o chiamate client verso terze parti. Le richieste alle fonti Microsoft vengono effettuate dal collector sul server, non dal browser del visitatore.

I file data.json, cve-data.json e samples/ contengono esclusivamente contenuti pubblicati dalle fonti Microsoft ufficiali; non devono essere usati per memorizzare dati di tenant o informazioni personali interne.

Limitazioni note

  • Microsoft 365 e Azure possono modificare endpoint o schema senza preavviso.
  • Il feed RSS Microsoft 365 può rappresentare una finestra upstream anziché l'intero storico; il collector espone il conteggio upstream osservato.
  • La classificazione delle azioni è euristica.
  • Il refresh su navigazione dipende dall'arrivo di una richiesta dopo la soglia di 24 ore.
  • Il server usa fcntl e quindi è destinato a Linux/Unix, non a Windows nativo.
  • Una singola istanza con filesystem condiviso è il modello operativo previsto per lock e stato persistente.

Risoluzione dei problemi

Il dataset non viene aggiornato

Controllare i log dell'App Service, la disponibilità dello storage persistente /home/data e la raggiungibilità delle fonti Microsoft. Se la raccolta fallisce, il dataset esistente non viene sostituito.

Il refresh restituisce 403

Verificare che DASHBOARD_ORIGIN corrisponda esattamente all'origine pubblica Azure.

Il refresh restituisce 202

Un altro worker o client sta già aggiornando il dataset. Il client riprova rispettando Retry-After.

Il refresh restituisce 503 backoff

Un tentativo precedente è fallito. Il server conserva il dataset corrente e restituisce l'orario del prossimo tentativo in nextAllowedAt.

Il browser non carica gli asset

La dashboard usa intenzionalmente il prefisso /microsoft/. Verificare che la configurazione Azure e il server applicativo conservino tale percorso.

Contributi

Per modifiche funzionali:

  1. creare un branch dedicato;
  2. aggiungere o aggiornare prima i test del comportamento interessato;
  3. eseguire tutte le suite Python e JavaScript;
  4. verificare che data.json.gz e cve-data.json.gz siano le decompressioni esatte dei rispettivi JSON quando i dataset vengono rigenerati;
  5. evitare nuove dipendenze salvo reale necessità;
  6. non aggiungere segreti, file .env, cache o dati di tenant al repository.

Autore

Creato da Alessandro Fabiani.

Il logo mschangeintelligence.png è un asset fornito dal titolare del progetto ed è incluso nel repository privato per l'uso con MS Change Intelligence. Non viene concessa separatamente una licenza di riutilizzo del marchio o dell'immagine.

Licenza

Nessuna licenza open source è attualmente dichiarata. Il repository è privato e tutti i diritti restano riservati al titolare del progetto.

About

Static-first Microsoft 365 Roadmap and Azure Updates intelligence dashboard

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages