Utveckla anpassade grafplattformslösningar

Note

Den här funktionen är för närvarande i förhandsversion. Se Kompletterande användningsvillkor för Förhandsversioner av Microsoft Azure.

En Microsoft Sentinel anpassad graflösning är en notebook-baserad lösning som definierar noder och kanter från Microsoft Sentinel datasjötabeller, skapar ett diagram och låter användare köra frågor mot diagrammet med Graph Query Language (GQL).

Använd den här guiden för att skapa, testa, materialisera, paketera och publicera en anpassad graflösning som ett SaaS-erbjudande i Microsoft Partner Center så att kunderna kan identifiera den i Microsoft Security Store.

Förutsättningar

Du måste vara registrerad på datasjön för att kunna skapa Custom Graph-lösningar. Mer information finns i Så här ansluter du till Microsoft Sentinel-datasjön.

Permissions

I följande tabell visas de behörigheter som krävs för varje åtgärd eller omfattning i den här guiden.

Operation Obligatorisk roll
Registrering till Sentinel-datasjön Microsoft Entra ID – säkerhetsadministratör eller global administratör
Anslut Sentinel-arbetsytan till Defender-portalen Ägare av prenumeration eller administratör för användaråtkomst på prenumerationsnivå och Microsoft Sentinel-deltagare på prenumerations- eller resursgruppsnivå
Anslut Sentinel-arbetsyta till en datasjö Prenumerationsägare eller Microsoft Sentinel-deltagare på prenumerations- eller resursgruppsnivå
Modellera och bygg en anteckningsboksgraf Anpassad enhetlig RBAC-roll för Microsoft Defender XDR med data (manage) behörighet för Microsoft Sentinel-datainsamling
Spara (materialisera) ett diagram Säkerhetsoperatör, säkerhetsadministratör eller global administratör
Förfråga en bestående graf Anpassad enhetlig RBAC-roll i Microsoft Defender XDR med security data basics (read) för Microsoft Sentinel-datainsamling
Publicera Custom Graph-lösning Marketplace-Publisher konto på Microsoft Partner Center

Tools

Följande verktyg krävs för att skapa och publicera en anpassad graflösning:

Tip

Återanvänd en befintlig datasjö om din klientorganisation redan är konfigurerad för KQL-frågor, anteckningsböcker eller en Security Copilot-agent. Det finns en datasjö per klientorganisation. I Defender-portalen går du tillSysteminställningar>>Microsoft Sentinel>Data lake. Om statusen är Etablerad hoppar du över uppgift 1.

Skapa arbetsflöde

Följande arbetsflöde beskriver stegen för att skapa och publicera en anpassad graflösning.

  1. Importera exempeldata till tabellerna som dina grafmodeller använder.
  2. Verifiera anslutningen med en enkel notebook.
  3. Skapa den anpassade grafen.
  4. Testa grafanteckningsboken.
  5. Schemalägg ett diagramjobb för att materialisera grafen.
  6. Fråga och visualisera diagrammet från Graph Explorer.
  7. Paketera och publicera den anpassade graflösningen.

Mata in exempeldata

Den här uppgiften läser in Microsoft Entra ID-resurstabeller som används av exempelgrafen i den här guiden: EntraUsers, EntraGroups, EntraServicePrincipals, och EntraMembers.

  1. I Defender-portalen går du tillSysteminställningar>>Microsoft Sentinel>Data-anslutningsappar.
  2. Aktivera Microsoft Entra ID-anslutningsappen så att Entra-tillgångstabeller matas in i datasjön. Mer information finns i Resursdata i Microsoft Sentinel data lake.
  3. Bekräfta att dessa tabeller visas i Data Lake Explorer:
    • EntraUsers
    • EntraGroups
    • EntraServicePrincipals
    • EntraMembers
  4. Dessa tabeller hamnar i arbetsytan Systemtabeller .
  5. Valfritt: importera andra anslutningar och ersätt tabellnamn i senare steg om ditt scenario använder andra data.

Note

Om en tabell inte visas i Data Lake Explorer kan du inte använda den för grafredigering och AI-hjälp refererar inte till den.

Verifiera anslutningen med en enkel notebook

Skapa och kör en minimal notebook för att verifiera anslutningen till datasjön innan du skapar grafer.

  1. Öppna Visual Studio Code och logga in på Microsoft Sentinel-tillägget med samma konto som har åtkomst till datasjön.

  2. I Visual Studio Code går du till Sentinel Extension–Graphs och väljer Skapa ny notebook-fil. En skärmbild som visar alternativet skapa ny anteckningsbok i VS Code.

  3. Spara anteckningsboken, till exempel hello-world-show-tables.ipynb.

  4. Välj Select kernel, välj Microsoft Sentinel och välj en tillgänglig Spark-pool. En skärmbild som visar alternativet välj kernel i VS Code.

  5. Lägg till följande celler i ordning.

Cell 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

Cell 2 – Kod (anslut och ange din arbetsyta):

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}")

Cell 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.

Cell 4 – Kod (läs en tabell och visa rader):

# 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)

Cell 5 - Kod (valfria rimlighetskontroller):

# Confirm the read returned data and inspect the schema.
print("Row count:", df_groups.df.count())
df_groups.df.printSchema()
  1. Kör alla celler uppifrån och ned.
  2. Bekräfta att varje cell har slutförts utan röd spårning, tabellförhandsgranskningsdata visas och radantalet är inte noll.

Note

Om läsningar misslyckas eller inte returnerar några rader, kontrollera att anslutningen från avsnittet Importera exempeldata har slutfört sin första snapshot, att LOG_ANALYTICS_WORKSPACE motsvarar en verklig arbetsyta och att ditt konto har läsåtkomst. Kontrollera innehållet i tabellen med KQL i Defender-portalen för att bekräfta att data finns. Mer information finns i Köra KQL-frågor i Microsoft Sentinels datasjö.

Skapa det anpassade diagrammet

Författa på ett av följande sätt:

  • AI-assisterad grafredigering.
  • Skapa manuellt.

AI-assisterad grafredigering

Följ dessa steg om du vill skapa ett diagram med AI-hjälp:

  1. Öppna GitHub Copilot Chat i Visual Studio Code.

  2. Starta prompten med hjälpverktyget för grafredigering @sentinel /graph-authoring och beskriv grafen på vanligt språk:

    @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.
    

    En skärmbild som visar AI-assisterad diagramredigering i VS Code.

    Copilot genererar följande celler för diagramredigeringslivscykeln:

    Livscykelns stadium Genererade utdata
    Miljöinställningar Verifierar nödvändiga paket och anslutningsinformation
    Datainläsning Läser namngivna tabeller från Sentinel Data Lake
    Dataomvandling Förbereder nod- och gränsdata
    Diagramschema Definierar noder och kanter
    Schemavalidering Validerar grafdefinitionen
    Grafkompilering Materialiserar diagrammet för sessionen
    Graph-fråga Kör en GQL-exempelfråga och visualiserar resultatet
  3. Fortsätt förfina anteckningsboken med uppmaningar som dessa:

    Mål Prompt
    Lägga till en relation @sentinel Add an edge from User to IPAddress
    Filtrera data @sentinel Filter the data to show only failed sign-ins
    Ändra tidsintervall @sentinel Change the time range to the last 7 days
    Åtgärda byggfel @sentinel Fix the error in the graph build step
    Förstå kod @sentinel Explain how edge keys are defined
    Slå upp ett API utan redigering What parameters does build_graph_with_data() accept? #Sentinel

Tip

Använd @sentinel /graph-authoring för att skapa eller ändra notebook-celler. Om du behöver API-förklaringar eller exempelfrågor kan du fråga Copilot och ta med #Sentinel för Sentinel-specifika svar.

Författare för hand

Följ dessa steg om du vill skapa ett diagram manuellt:

  1. Anslut till och läs resurstabeller.

    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. Förbereda nod- och gränsdataramar.

    # 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. Definiera grafschema och binda DataFrames.

    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. Skapa diagrammet.

    # 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() förbereder data och publicerar med ett enda anrop. Om du vill inspektera förberedda noder och kanter före publicering anropar du Graph.prepare(spec), granskar graph.nodes och graph.edges och anropar sedan graph.publish().

  5. Kör en GQL-fråga.

    # 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 grafanteckningsboken

Testa anteckningsboken för att säkerställa att den ger de förväntade diagrammen:

  1. Starta om kerneln och kör alla celler uppifrån och ned. En skärmbild som visar knappen starta om kernel.

  2. Kontrollera att varje cell slutförs utan fel.

  3. Om transformeringsceller körs längre än 5 minuter i en liten pool drar du åt filter för ögonblicksbilder och kolumnprojektion innan du skalar upp.

  4. Bekräfta show_schema() returnerar förväntade noder och kanter.

  5. Kör en GQL-exempelfråga och verifiera visualisering och tabellutdata.

  6. Validera gränsfall:

    • Ingen indata.
    • Schemaavvikelse.
    • Tabellåtkomst saknas.

Tip

Lägg till markdown-celler ovanför varje kodavsnitt för att dokumentera syfte, indata, utdata och de noder eller kanter som skapas.

Schemalägga ett diagramjobb för att materialisera grafen

Diagram som skapas i en interaktiv session är tillfälliga. Schemalägg ett diagramjobb för att spara och uppdatera diagrammet. Mer information finns i Schemalägga och hantera Microsoft Sentinel diagramjobb.

  1. I din diagramanteckningsbok väljer du Skapa schemalagt jobb>Skapa ett diagramjobb. En skärmbild som visar knappen skapa diagramjobb.

  2. Ange diagramnamn och beskrivning och verifiera sökvägen till notebook-filen.

  3. Välj ett schema:

    • På begäran: byggs en gång med standardvarhållning på 30 dagar.
    • Schemalagd: välj upprepad takt och start-/sluttider.
  4. Välj Skicka.

  5. Öppna diagrammet i Sentinel-tillägget och övervaka jobbinformation.

  6. Använd Kör nu för att köra utanför schemat efter behov.

  7. Bekräfta statusförlopp från Queued till In ProgressReady .

Important

Inskickade jobb är frikopplade från din lokala notebook. Redigering av det lokala .ipynb uppdaterar inte det schemalagda jobbet. Om du vill uppdatera en jobbanteckningsbok laddar du ned den från panelen Graphs, redigerar den och använder sedan Redigera jobb>– Skicka.

Fråga och visualisera från Graph Explorer

När grafjobbets status är Ready kan du köra frågor och visualisera i Defender-portalen, notebooks och REST-API:er.

  1. Öppna grafupplevelsen i Defender-portalen under Microsoft Sentinel och välj din materialiserade graf.
  2. Kör GQL-frågor, inspektera schemat, växla visuella och tabellbaserade utdata och gå vidare till nästa hopp.
  3. Använd den här GQL-snabbreferensen:
Mönster eller sats Example
Nod med etikett (g:EntraGroup)
Typad, riktad kant -[c:ContainsUser]->
Sökväg med variabel längd (1–8 hopp) (a)-[e]->{1,8}(b)
Filter WHERE g.displayName = 'Finance Admins'
Projicera, sortera, begränsa RETURN g.displayName ORDER BY g.displayName LIMIT 10
Etikettuttryck (:EntraUser \| EntraServicePrincipal)

Note

Varje GQL-fråga börjar med MATCH. Motorn körs i UTC. Använd ZONED_DATETIME(...) för datetime-litteraler. INSERT och CREATE stöds inte. Diagram är skrivskyddade.

  1. Fråga från en notebook-fil.

    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. Fråga med graph REST-API:er.

    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 styr utdataformen. "Table" returnerar rader, "Graph" returnerar noder och kanter och ["Table", "Graph"] returnerar båda.

Mer information finns i Graph REST API:er för anpassade grafer.

Paketera och publicera din graflösning

När grafen har testats och materialiserats paketeras den för distribution till kunder. Detaljerade paketeringsinstruktioner finns i Paketera och publicera Microsoft Sentinel graf- och notebook-lösningar.

Troubleshooting

Använd följande tabeller för att diagnostisera vanliga problem efter symptom.

Diagramredigering

Symptom Sannolik orsak och korrigering
MicrosoftSentinelProvider eller sentinel_graph hittades inte Logga in igen på tillägget och bekräfta att en Microsoft Sentinel kernel har valts.
Cellen låser sig vid "Starta Spark-session" Första starten kan ta 3 till 5 minuter. Om den överskrider 6 minuter kontrollerar du poolkapaciteten och försöker igen.
show_schema() är tom eller Graph.build() misslyckas Kontrollera att nyckel- och visningskolumner finns och inte är null samt att käll- och målvärdena för node_type matchar nodalias.
GQL-frågan returnerar inga rader Bekräfta att filtervärdena finns i den valda ögonblicksbilden och verifiera filtrering av ögonblicksbilder.
publish() misslyckas med nekad behörighet Bekräfta att du har rollen säkerhetsoperatör, säkerhetsadministratör eller global administratör.

AI-assisterad redigering

Symptom Sannolik orsak och korrigering
@sentinel /graph-authoring gör ingenting Bekräfta GitHub Copilot- och Jupyter-tilläggen är installerade och aktiva och att du har en Copilot Business- eller Enterprise-plan.
Genererad kod refererar till en tabell som saknas Bekräfta konfigurationen av anslutningsappen och kontrollera att tabellen visas i Data Lake Explorer.

Finplanering

Symptom Sannolik orsak och korrigering
Redigeringar av lokala notebook-filer återspeglas inte i jobbet Ladda ned jobbanteckningsboken från panelen Graphs, redigera den och använd sedan Redigera jobb>skicka.
Materialiserad graf försvann Grafer på begäran har kvarhållning på 30 dagar. Schemalägg ett återkommande jobb eller kör ett nytt bygge.