Sviluppare soluzioni di piattaforma a grafo personalizzate

Note

Questa funzionalità è attualmente disponibile solo in anteprima. Vedere Condizioni supplementari per l'utilizzo delle anteprime di Microsoft Azure.

Una soluzione con grafo personalizzato di Microsoft Sentinel è una soluzione basata su notebook che definisce nodi e archi a partire dalle tabelle del data lake di Microsoft Sentinel, crea un grafo e consente agli utenti di eseguire query su tale grafo con Graph Query Language (GQL).

Usa questa guida per creare, testare, distribuire, pacchettizzare e pubblicare una soluzione Graph personalizzata come offerta SaaS in Microsoft Partner Center, affinché i clienti possano individuarla in Microsoft Security Store.

Prerequisiti

Per creare soluzioni Graph personalizzate, è necessario essere abilitati al data lake. Per altre informazioni, vedere Come eseguire l'onboarding nel data lake Microsoft Sentinel.

Permissions

Nella tabella seguente sono elencate le autorizzazioni necessarie per ogni operazione o ambito in questa guida.

Operation Ruolo necessario
Introduzione al data lake di Sentinel Microsoft Entra ID - Amministratore della sicurezza o Amministratore globale
Eseguire l'onboarding dell'area di lavoro Sentinel in Defender portal Proprietario della sottoscrizione o Amministratore dell'accesso utente a livello di sottoscrizione e Collaboratore di Microsoft Sentinel a livello di sottoscrizione o di gruppo di risorse
Eseguire l'onboarding dell'area di lavoro Sentinel in Data Lake Proprietario della sottoscrizione o Collaboratore di Microsoft Sentinel a livello di sottoscrizione o gruppo di risorse
Modellare e creare un grafico del notebook Ruolo RBAC unificato personalizzato di Microsoft Defender XDR con autorizzazione data (manage) sulla raccolta dati di Microsoft Sentinel
Rendere persistente (materializzare) un grafico Operatore di sicurezza, amministratore della sicurezza o amministratore globale
Eseguire una query su un grafico persistente Ruolo RBAC unificato personalizzato di Microsoft Defender XDR con security data basics (read) sulla raccolta dati di Microsoft Sentinel
Pubblicazione di una soluzione Graph personalizzata Account di pubblicazione del marketplace su Centro per i partner Microsoft

Tools

Per compilare e pubblicare una soluzione a grafo personalizzata sono necessari gli strumenti seguenti:

Tip

Riutilizza un data lake esistente se il tenant è già abilitato per le query KQL, i notebook o un agente Security Copilot. È disponibile un data lake per ogni tenant. Nel portale di Defender passare aImpostazioni>di sistema>Microsoft Sentinel>Data lake. Se lo stato è Provisioned, saltare l'attività 1.

Creare un flusso di lavoro

Il flusso di lavoro seguente illustra i passaggi per compilare e pubblicare una soluzione a grafo personalizzata.

  1. Inserire dati di esempio nelle tabelle dei modelli a grafo.
  2. Convalidare la connettività con un notebook semplice.
  3. Creare il grafico personalizzato.
  4. Testa il notebook dei grafici.
  5. Pianificare un processo del grafico per materializzare il grafico.
  6. Eseguire query e visualizzare il grafo in Graph Explorer.
  7. Creare un pacchetto e pubblicare la soluzione a grafo personalizzata.

Inserire dati di esempio

Questa attività acquisisce le tabelle delle risorse di Microsoft Entra ID usate dal grafo di esempio in questa guida: EntraUsers, EntraGroups, EntraServicePrincipals e EntraMembers.

  1. Nel portale di Defender passare aImpostazioni>di sistema>Microsoft Sentinel>Connetti dati.
  2. Abilitare il connettore Microsoft Entra ID in modo che le tabelle degli asset Entra vengano inserite nel data lake. Per ulteriori informazioni, vedere Dati sulle risorse nel data lake di Microsoft Sentinel.
  3. Verificare che queste tabelle siano visualizzate in Esplora data lake:
    • EntraUsers
    • EntraGroups
    • EntraServicePrincipals
    • EntraMembers
  4. Queste tabelle vengono inserite nell'area di lavoro Tabelle di sistema .
  5. Facoltativo: inserire altri connettori e sostituire i nomi delle tabelle nei passaggi successivi se lo scenario usa dati diversi.

Note

Se una tabella non viene visualizzata in Esplora data lake, non è possibile usarla per la creazione di gragrafi e l'assistenza per intelligenza artificiale non vi farà riferimento.

Convalidare la connettività con un notebook semplice

Crea ed esegui un notebook minimale per verificare la connettività del data lake prima della creazione dei grafi.

  1. Aprire Visual Studio Code e accedere all'estensione Microsoft Sentinel con lo stesso account che ha accesso al data lake.

  2. In Visual Studio Code, in Extension–Graphs di Sentinel selezionare Crea nuovo notebook. Screenshot che mostra l'opzione Crea nuovo notebook in VS Code.

  3. Salva il notebook, ad esempio hello-world-show-tables.ipynb.

  4. Selezionare Seleziona kernel, selezionare Microsoft Sentinel e selezionare un pool di Spark disponibile. Screenshot che mostra l'opzione select kernel in VS Code.

  5. Aggiungere le celle seguenti nell'ordine.

Cella 1 - Markdown:

# Hello World: Show Tables
A minimal connectivity test for the Microsoft Sentinel data lake.
If every cell below runs without error, your environment is ready
to author custom graphs.
Steps:
1. Connect to the data lake with the Microsoft Sentinel provider
2. Point at your workspace
3. Read a table and show a few rows

Cella 2 - Codice (connettersi e impostare l'area di lavoro):

from sentinel_lake.providers import MicrosoftSentinelProvider
# The provider gives the notebook access to data lake tables.
lake_provider = MicrosoftSentinelProvider(spark=spark)
# >>> ADD YOUR WORKSPACE HERE <<<
# Replace with the Log Analytics workspace that holds your tables.
# Entra asset tables (EntraUsers, EntraGroups, ...) live in "System tables".
LOG_ANALYTICS_WORKSPACE = "System tables"
print(f"Using workspace: {LOG_ANALYTICS_WORKSPACE}")

Cella 3 - Markdown:

## Read a table and show rows
Reading a known table is the fastest way to confirm the extension
can reach the lake with your permissions. Swap EntraGroups for any
table that exists in your workspace.

Cella 4 - Codice (leggere una tabella e visualizzare le righe):

# Read a table from the data lake into a Spark DataFrame.
df_groups = lake_provider.read_table("EntraGroups", LOG_ANALYTICS_WORKSPACE)
# Show a sample. .df exposes the underlying Spark DataFrame.
df_groups.df.select("id", "displayName", "mailEnabled").show(20, truncate=False)

Cella 5: codice (conteggi di integrità facoltativi):

# Confirm the read returned data and inspect the schema.
print("Row count:", df_groups.df.count())
df_groups.df.printSchema()
  1. Eseguire tutte le celle dall'alto verso il basso.
  2. Verificare che ogni cella venga completata senza un traceback rosso, che vengano visualizzati i dati di anteprima della tabella e che il numero di righe sia diverso da zero.

Note

Se le letture non riescono o non restituiscono alcuna riga, verificare che il connettore della sezione Acquisisci dati di esempio abbia completato la prima istantanea, che LOG_ANALYTICS_WORKSPACE corrisponda a un'area di lavoro reale e che l'account disponga dell'accesso in lettura. Controllare il contenuto del sommario con KQL nel portale di Defender per verificare che i dati siano presenti. Per ulteriori informazioni, vedi Eseguire query KQL sul data lake di Microsoft Sentinel.

Creare il grafico personalizzato

Scrivere in uno dei modi seguenti:

  • Creazione di gragrafi assistita dall'intelligenza artificiale.
  • Scrivere a mano.

Creazione di gragrafi assistita dall'intelligenza artificiale

Per creare un grafico con assistenza per intelligenza artificiale, seguire questa procedura:

  1. In Visual Studio Code, apri GitHub Copilot Chat.

  2. Inizia il prompt con l'assistente per la creazione di grafi @sentinel /graph-authoring e descrivi il grafo in linguaggio semplice:

    @sentinel /graph-authoring Create a graph that maps Entra groups to
    their member users, groups, and service principals using EntraGroups,
    EntraUsers, EntraServicePrincipals, and EntraMembers from the
    "System tables" workspace.
    

    Screenshot che mostra la creazione di gragrafi assistita dall'intelligenza artificiale in VS Code.

    Copilot genera le seguenti celle per il ciclo di vita della creazione del grafo:

    Fase del ciclo di vita Output generato
    Configurazione dell'ambiente Verifica i pacchetti necessari e le informazioni di connessione
    Caricamento dei dati Legge le tabelle denominate dal data lake di Sentinel
    Trasformazione dei dati Prepara i dati dei nodi e dei dispositivi perimetrali
    Schema del grafo Definisce nodi e archi
    Convalida dello schema Convalida la definizione del grafo
    Compilazione di grafi Materializza il grafico per la sessione
    Query grafico Esegue una query GQL di esempio e visualizza il risultato
  3. Continuare a perfezionare il notebook con richieste simili alle seguenti:

    Obiettivo Prompt
    Aggiunta di una relazione @sentinel Add an edge from User to IPAddress
    Filtro dei dati @sentinel Filter the data to show only failed sign-ins
    Modificare l'intervallo di tempo @sentinel Change the time range to the last 7 days
    Correzione dell'errore di compilazione @sentinel Fix the error in the graph build step
    Informazioni sul codice @sentinel Explain how edge keys are defined
    Cercare un'API senza modificare What parameters does build_graph_with_data() accept? #Sentinel

Tip

Usare @sentinel /graph-authoring per creare o modificare le celle del notebook. Se hai bisogno di spiegazioni sulle API o di query di esempio, chiedi a Copilot e includi #Sentinel per ottenere risposte specifiche per Sentinel.

Scrivere a mano

Per creare un grafico manualmente, seguire questa procedura:

  1. Connetti e leggi le tabelle delle risorse.

    from pyspark.sql import functions as F
    from sentinel_lake.providers import MicrosoftSentinelProvider
    lake_provider = MicrosoftSentinelProvider(spark=spark)
    # Entra asset tables live in the "System tables" workspace.
    # If your data is elsewhere, update this and ensure the tables exist.
    LOG_ANALYTICS_WORKSPACE = "System tables"
    # Use the latest snapshot of EntraUsers as the point-in-time for all tables.
    snapshot_time = (
        lake_provider.read_table("EntraUsers", LOG_ANALYTICS_WORKSPACE)
        .df.agg(F.max("_SnapshotTime").alias("max_snapshot"))
        .collect()[0]["max_snapshot"]
        .strftime("%Y-%m-%dT%H:%M:%SZ")
    )
    print(f"Using snapshot_time: {snapshot_time}")
    snapshot_filter = (F.col("_SnapshotTime") == F.lit(snapshot_time).cast("timestamp"))
    # Edges: group contains user / group / servicePrincipal
    df_members = (
        lake_provider.read_table("EntraMembers", LOG_ANALYTICS_WORKSPACE)
        .filter(
            snapshot_filter
            & (F.col("sourceType") == "group")
            & (F.col("targetType").isin("user", "group", "servicePrincipal"))
        )
    )
    # Nodes
    df_groups = (
        lake_provider.read_table("EntraGroups", LOG_ANALYTICS_WORKSPACE)
        .filter(snapshot_filter)
        .select("id", "displayName", "mailEnabled")
    )
    df_users = (
        lake_provider.read_table("EntraUsers", LOG_ANALYTICS_WORKSPACE)
        .filter(snapshot_filter)
        .select("id", "accountEnabled", "displayName", "department",
                "userPrincipalName", "usageLocation")
    )
    
  2. Preparare i DataFrame dei nodi e degli archi.

    # NODES
    user_nodes = df_users.df.select(
        "id", "displayName", "accountEnabled", "department",
        "userPrincipalName", "usageLocation")
    group_nodes = df_groups.df.select("id", "displayName", "mailEnabled")
    # EDGES
    edge_group_contains_user = (
        df_members.df.filter(F.col("targetType") == "user")
        .select(F.col("sourceId").alias("SourceGroupId"),
                F.col("targetId").alias("TargetUserId"))
        .distinct()
        .withColumn("EdgeKey", F.concat_ws("_", F.col("SourceGroupId"), F.col("TargetUserId")))
    )
    edge_group_contains_group = (
        df_members.df.filter(F.col("targetType") == "group")
        .select(F.col("sourceId").alias("SourceGroupId"),
                F.col("targetId").alias("TargetGroupId"))
        .distinct()
        .withColumn("EdgeKey", F.concat_ws("_", F.col("SourceGroupId"), F.col("TargetGroupId")))
    )
    
  3. Definisci lo schema del grafo e associa i DataFrame.

    from sentinel_graph import GraphSpecBuilder, Graph
    entra_group_graph_spec = (
        GraphSpecBuilder.start()
        # === NODES ===
        .add_node("EntraUser").from_dataframe(user_nodes)
        .with_columns("id", "displayName", "accountEnabled", "department",
                      "userPrincipalName", "usageLocation",
                      key="id", display="displayName")
        .add_node("EntraGroup").from_dataframe(group_nodes)
        .with_columns("id", "displayName", "mailEnabled",
                      key="id", display="displayName")
        # === EDGES ===
        .add_edge("ContainsUser").from_dataframe(edge_group_contains_user)
        .source(id_column="SourceGroupId", node_type="EntraGroup")
        .target(id_column="TargetUserId", node_type="EntraUser")
        .with_columns("SourceGroupId", "TargetUserId", "EdgeKey",
                      key="EdgeKey", display="EdgeKey")
        .add_edge("ContainsGroup").from_dataframe(edge_group_contains_group)
        .source(id_column="SourceGroupId", node_type="EntraGroup")
        .target(id_column="TargetGroupId", node_type="EntraGroup")
        .with_columns("SourceGroupId", "TargetGroupId", "EdgeKey",
                      key="EdgeKey", display="EdgeKey")
    ).done()
    # Validate the schema before building.
    entra_group_graph_spec.show_schema()
    
  4. Compilare il grafico.

    # Build = prepare data + publish for the session.
    entra_group_graph = Graph.build(entra_group_graph_spec)
    print(entra_group_graph.build_status.status)   # "published" or "prepared"
    

    Note

    Graph.build() prepara i dati e pubblica in una sola chiamata. Per esaminare nodi e archi preparati prima della pubblicazione, chiamare Graph.prepare(spec), rivedere graph.nodes e graph.edges, quindi chiamare graph.publish().

  5. Eseguire una query GQL.

    # Find nested group relationships up to 8 levels deep. 
    # Update the Entra Group name that you want to traverse from 
    
    query_nested_groups = """ 
    MATCH p=(g1:EntraGroup)-[cg]->{1,8}(g2) 
    WHERE g1.displayName = 'tmplevel3' 
    RETURN * 
    """ 
    entra_group_graph.query(query_nested_groups).show()
    

Testa il notebook per i grafici

Verificare il notebook per assicurarsi che produca il grafico previsto:

  1. Riavviare il kernel ed eseguire tutte le celle in alto in basso. Screenshot che mostra il pulsante riavvia kernel.

  2. Verificare che ogni cella sia completata correttamente.

  3. Se le celle di trasformazione richiedono più di 5 minuti su un pool di piccole dimensioni, restringere i filtri delle snapshot e la selezione delle colonne prima di aumentare le dimensioni.

  4. Verificare che show_schema() restituisce i nodi e gli archi previsti.

  5. Eseguire una query GQL di esempio e verificare la visualizzazione e l'output in formato tabellare.

  6. Convalidare i casi limite:

    • Campo vuoto.
    • Spostamento schema.
    • Accesso alla tabella non disponibile.

Tip

Aggiungere celle Markdown sopra ogni sezione di codice per documentarne lo scopo, gli input, gli output e i nodi o gli archi prodotti.

Pianificare un processo del grafico per materializzare il grafico

I grafici creati in una sessione interattiva sono temporanei. Pianificare un processo del grafico per rendere persistente e aggiornare il grafico. Per altre informazioni, vedi Pianificare e gestire i processi grafici di Microsoft Sentinel.

  1. Nel notebook di grafi, seleziona Crea attività pianificata>Crea un processo per grafici. Screenshot che mostra il pulsante per creare un processo del grafico.

  2. Immettere il nome e la descrizione del grafico e verificare il percorso del notebook.

  3. Selezionare una pianificazione:

    • Su richiesta: crea una sola volta, con una conservazione predefinita di 30 giorni.
    • Pianificato: selezionare frequenza di ripetizione e ora di inizio/fine.
  4. Selezionare Invia.

  5. Apri il grafico nell'estensione Sentinel e monitora Job Details.

  6. Usare Run Now per eseguire una pianificazione esterna in base alle esigenze.

  7. Confermare l'avanzamento dello stato da Queued a In Progress .Ready

Importante

I processi inviati sono indipendenti dal notebook locale. La modifica del local .ipynb non aggiorna il job pianificato. Per aggiornare un notebook del job, scaricalo dal pannello Grafici, modificalo, quindi usa Modifica job>Invia.

Eseguire query e visualizzarle in Graph Explorer

Dopo che lo stato del processo del grafico è Ready, è possibile eseguire query e visualizzarne i dati nel portale Defender, nei notebook e nelle API REST.

  1. Nel portale Defender, in Microsoft Sentinel, apri l'esperienza Open Graph e seleziona il tuo grafico materializzato.
  2. Esegui query GQL, ispeziona lo schema, passa dalla visualizzazione grafica a quella tabellare e passa all'hop successivo.
  3. Usa questa guida rapida di GQL:
Modello o clausola Example
Nodo con etichetta (g:EntraGroup)
Arco orientato tipizzato -[c:ContainsUser]->
Percorso a lunghezza variabile (da 1 a 8 hop) (a)-[e]->{1,8}(b)
Filter WHERE g.displayName = 'Finance Admins'
Proietta, ordina, limita RETURN g.displayName ORDER BY g.displayName LIMIT 10
Espressioni di etichetta (:EntraUser \| EntraServicePrincipal)

Note

Ogni query GQL inizia con MATCH. Il motore funziona in formato UTC. Usare ZONED_DATETIME(...) per i valori letterali di data e ora. INSERT e CREATE non sono supportati. I grafici sono di sola lettura.

  1. Eseguire una query da un notebook.

    from sentinel_graph import Graph
    # Attach to an already-materialized graph by name.
    graph = Graph.get("entra_group_membership")
    graph.query("MATCH (g:EntraGroup)-[c:ContainsUser]->(u:EntraUser) RETURN g, c, u").show()
    # Purpose-built security algorithms are available too:
    graph.blast_radius(source_property_value="Finance Admins", min_hop_count=1).show()
    
  2. Eseguire una query usando le API REST di Graph.

    GET https://api.securityplatform.microsoft.com/graphs/graph-instances?graphTypes=Custom
    Authorization: Bearer <access_token>
    
    POST https://api.securityplatform.microsoft.com/graphs/graph-instances/{graphName}/query
    Authorization: Bearer <access_token>
    Content-Type: application/json
    {
      "query": "MATCH (g:EntraGroup)-[c:ContainsUser]->(u) RETURN g, c, u LIMIT 100",
      "responseFormats": ["Table", "Graph"],
      "queryLanguage": "GQL"
    }
    

responseFormats determina la forma dell'uscita. "Table" restituisce righe, "Graph" restituisce nodi e archi e ["Table", "Graph"] restituisce entrambi.

Per altre informazioni, vedere API REST Graph per grafici personalizzati.

Creare un pacchetto e pubblicare la soluzione Graph

Dopo aver testato e materializzato il grafico, crearne il pacchetto per la distribuzione ai clienti. Per istruzioni dettagliate sulla creazione e pubblicazione dei pacchetti, vedere Creazione e pubblicazione delle soluzioni Microsoft Sentinel per grafici e notebook.

Troubleshooting

Usare le tabelle seguenti per diagnosticare i problemi comuni in base al sintomo.

Creazione di grafi

Sintomo Probabile causa e correzione
MicrosoftSentinelProvider o sentinel_graph non trovato Accedere di nuovo all'estensione e verificare che sia selezionato un kernel Microsoft Sentinel.
La cella si blocca ad "Avvio della sessione Spark" La prima avvio può richiedere da 3 a 5 minuti. Se supera i 6 minuti, controllare la capacità del pool e riprovare.
show_schema() è vuoto o Graph.build() ha esito negativo Verificare che le colonne chiave e di visualizzazione esistano e siano non Null e i valori di origine e di destinazione node_type corrispondano agli alias del nodo.
La query GQL non restituisce righe Verificare che i valori del filtro esistano nello snapshot selezionato e verificare il filtro dello snapshot.
publish() non riesce: autorizzazione negata Verificare di avere il ruolo Operatore di sicurezza, Amministratore della sicurezza o Amministratore globale.

Creazione assistita dall'intelligenza artificiale

Sintomo Probabile causa e correzione
@sentinel /graph-authoring non fa nulla Verificare che le estensioni di GitHub Copilot e Jupyter siano installate e attive e che sia disponibile un piano Copilot Business o Enterprise.
Il codice generato fa riferimento a una tabella mancante Verificare la configurazione del connettore e verificare che la tabella venga visualizzata in Esplora data lake.

Programmazione dei processi

Sintomo Probabile causa e correzione
Le modifiche al notebook locale non vengono riflesse nel processo Scaricare il notebook del processo dal pannello Grafici, modificalo, quindi usare Modifica processo>Invia.
Grafico materializzato scomparso I grafici su richiesta hanno una conservazione di 30 giorni. Pianificare un processo ricorrente o eseguire una nuova compilazione.