Entwickeln von benutzerdefinierten Graph-Plattformlösungen

Note

Diese Funktion steht derzeit als Vorschau zur Verfügung. Siehe Ergänzende Nutzungsbedingungen für Microsoft Azure-Vorschauversionen.

Eine benutzerdefinierte Microsoft Sentinel-Graphlösung ist eine notebookbasierte Lösung, die Knoten und Kanten aus den Microsoft Sentinel Data Lake-Tabellen definiert, einen Graphen erstellt und Benutzern die Abfrage dieses Graphen mit der Graph Query Language (GQL) ermöglicht.

Verwenden Sie dieses Handbuch zum Erstellen, Testen, Materialisieren, Verpacken und Veröffentlichen einer benutzerdefinierten Graph-Lösung als SaaS-Angebot in Microsoft Partner Center, damit Kunden sie im Microsoft Security Store entdecken können.

Voraussetzungen

Sie müssen in den Data Lake integriert sein, um benutzerdefinierte Graph-Lösungen zu erstellen. Weitere Informationen finden Sie unter So führen Sie das Onboarding für den Microsoft Sentinel Data Lake durch.

Erlaubnisse

In der folgenden Tabelle sind die erforderlichen Berechtigungen für jeden Vorgang oder Bereich in diesem Handbuch aufgeführt.

Operation Erforderliche Rolle
Einführung in den Sentinel Data Lake Microsoft Entra ID – Sicherheitsadministrator oder globaler Administrator
Sentinel-Arbeitsbereich im Defender-Portal integrieren Abonnementbesitzer oder Benutzerzugriffsadministrator im Abonnementbereich und Microsoft Sentinel-Mitwirkender auf Abonnement- oder Ressourcengruppenebene
Sentinel-Arbeitsbereich an den Data Lake anbinden Abonnementbesitzer oder Microsoft Sentinel-Mitwirkender auf Abonnement- oder Ressourcengruppenebene
Ein Notizbuchdiagramm modellieren und erstellen Benutzerdefinierte einheitliche RBAC-Rolle für Microsoft Defender XDR mit data (manage)Berechtigung für die Microsoft Sentinel-Datensammlung
Einen Graphen beibehalten (materialisieren) Sicherheitsoperator, Sicherheitsadministrator oder globaler Administrator
Einen persistenten Graphen abfragen Benutzerdefinierte einheitliche RBAC-Rolle für Microsoft Defender XDR mit der Berechtigung security data basics (read) für die Microsoft Sentinel-Datensammlung
Veröffentlichen einer benutzerdefinierten Graph-Lösung Marketplace Publisher Konto auf Microsoft Partner Center

Tools

Zum Erstellen und Veröffentlichen einer benutzerdefinierten Diagrammlösung sind die folgenden Tools erforderlich:

Tip

Verwenden Sie einen vorhandenen Data Lake wieder, wenn Ihr Mandant bereits für KQL-Abfragen, Notebooks oder einen Security Copilot-Agent integriert ist. Es gibt einen Data Lake pro Mandant. Wechseln Sie im Defender-Portal zuSystemeinstellungen>>Microsoft Sentinel>Datensee. Wenn der Status "Bereitgestellt" ist, überspringen Sie die Aufgabe 1.

Workflow erstellen

Der folgende Workflow beschreibt die Schritte zum Erstellen und Veröffentlichen einer benutzerdefinierten Diagrammlösung.

  1. Importieren Sie Beispieldaten in die Tabellen, die Ihre Graphmodelle abbilden.
  2. Überprüfen sie die Konnektivität mit einem einfachen Notizbuch.
  3. Erstellen Sie das benutzerdefinierte Diagramm.
  4. Testen Sie das Graph-Notizbuch.
  5. Planen Sie einen Diagrammauftrag, um das Diagramm zu materialisieren.
  6. Abfragen und Visualisieren des Diagramms aus dem Graph-Explorer.
  7. Packen und Veröffentlichen der benutzerdefinierten Diagrammlösung.

Importieren von Beispieldaten

Diese Aufgabe erfasst Microsoft Entra ID-Ressourcentabellen, die vom Beispielgraphen in diesem Leitfaden verwendet werden: EntraUsers, EntraGroups, EntraServicePrincipals und EntraMembers.

  1. Wechseln Sie im Defender-Portal zuSystemeinstellungen>>Microsoft Sentinel>Datenconnectors.
  2. Aktivieren Sie den Microsoft Entra ID-Konnektor, damit Entra-Assettabellen in den Data Lake ingestiert werden. Weitere Informationen finden Sie unter Asset-Daten im Microsoft Sentinel Data Lake.
  3. Vergewissern Sie sich, dass diese Tabellen im Datensee-Explorer angezeigt werden:
    • EntraUsers
    • EntraGroups
    • EntraServicePrincipals
    • EntraMembers
  4. Diese Tabellen werden im Arbeitsbereich "Systemtabellen" angezeigt .
  5. Optional: Binden Sie andere Konnektoren ein und ersetzen Sie in späteren Schritten die Tabellennamen, falls Ihr Szenario andere Daten verwendet.

Note

Wenn eine Tabelle nicht im Datensee-Explorer angezeigt wird, können Sie sie nicht für die Diagrammerstellung verwenden, und die KI-Unterstützung verweist nicht darauf.

Überprüfen der Konnektivität mit einem einfachen Notizbuch

Erstellen und ausführen Sie ein minimales Notizbuch, um die Konnektivität von Data Lake vor der Diagrammerstellung zu überprüfen.

  1. Öffnen Sie Visual Studio Code, und melden Sie sich bei der Microsoft Sentinel-Erweiterung mit demselben Konto an, das Zugriff auf den Datensee hat.

  2. Wählen Sie in Visual Studio Code unter Sentinel Extension-Graphs "Neues Notizbuch erstellen" aus. Screenshot der Option

  3. Speichern Sie das Notizbuch, z. B hello-world-show-tables.ipynb. .

  4. Wählen Sie Kernel auswählen, dann Microsoft Sentinel und schließlich einen verfügbaren Spark-Pool aus. Screenshot der Option

  5. Fügen Sie die folgenden Zellen in der angegebenen Reihenfolge hinzu.

Zelle 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

Zelle 2 – Code (Verbinden und Festlegen des Arbeitsbereichs):

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

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

Zelle 4 – Code (Lesen einer Tabelle und Anzeigen von Zeilen):

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

Zelle 5 - Code (optionale Plausibilitätszählung):

# Confirm the read returned data and inspect the schema.
print("Row count:", df_groups.df.count())
df_groups.df.printSchema()
  1. Führen Sie alle Zellen von oben nach unten aus.
  2. Vergewissern Sie sich, dass jede Zelle ohne roten Traceback vollständig ausgeführt wird, dass die Vorschaudaten der Tabelle angezeigt werden und dass die Zeilenanzahl nicht null ist.

Note

Wenn Lesevorgänge fehlschlagen oder keine Zeilen zurückgeben, bestätigen Sie, dass der Konnektor aus dem Abschnitt Beispieldaten erfassen seinen ersten Snapshot abgeschlossen hat, LOG_ANALYTICS_WORKSPACE einem tatsächlichen Arbeitsbereich entspricht und Ihr Konto über Leseberechtigungen verfügt. Überprüfen Sie den Tabelleninhalt mit KQL im Defender-Portal, um zu bestätigen, dass Daten vorhanden sind. Weitere Informationen finden Sie unter Ausführen von KQL-Abfragen auf dem Microsoft Sentinel Data Lake.

Erstellen des benutzerdefinierten Diagramms

Verfassen Sie auf eine der folgenden Arten:

  • KI-unterstützte Diagrammerstellung.
  • Manuell erstellen.

KI-unterstützte Diagrammerstellung

Führen Sie die folgenden Schritte aus, um ein Diagramm mit KI-Unterstützung zu erstellen:

  1. Öffnen Sie in Visual Studio Code GitHub-Copilot Chat.

  2. Starten Sie Ihre Eingabeaufforderung mit dem Hilfsprogramm @sentinel /graph-authoring zum Erstellen von Grafiken, und beschreiben Sie Ihr Diagramm in einfacher Sprache:

    @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 der KI-unterstützten Diagrammerstellung in VS Code.

    Copilot generiert die folgenden Zellen für den Lebenszyklus der Diagrammerstellung:

    Lebenszyklusphase Generierte Ausgabe
    Umgebungskonfiguration Überprüft erforderliche Pakete und Verbindungsinformationen
    Laden von Daten Liest benannte Tabellen aus Sentinel-Datensee
    Datentransformation Bereitet Knoten- und Kantendaten vor
    Diagrammschema Definiert Knoten und Kanten
    Schemaüberprüfung Überprüft die Graphdefinition.
    Graph-Erstellung Materialisiert den Graphen für die Sitzung
    Graph-Abfrage Führt eine Beispiel-GQL-Abfrage aus und visualisiert das Ergebnis.
  3. Fahren Sie mit den folgenden Eingabeaufforderungen fort, um das Notizbuch zu verfeinern:

    Zielsetzung Prompt
    Eine Beziehung hinzufügen @sentinel Add an edge from User to IPAddress
    Daten filtern @sentinel Filter the data to show only failed sign-ins
    Zeitraum ändern @sentinel Change the time range to the last 7 days
    Buildfehler beheben @sentinel Fix the error in the graph build step
    Code verstehen @sentinel Explain how edge keys are defined
    Nachschlagen einer API ohne Bearbeitung What parameters does build_graph_with_data() accept? #Sentinel

Tip

Verwenden Sie @sentinel /graph-authoring, um Notizbuchzellen zu erstellen oder zu ändern. Wenn Sie API-Erklärungen oder Beispielabfragen benötigen, fragen Sie Copilot und geben Sie #Sentinel für Sentinel-spezifische Antworten an.

Manuell erstellen

Führen Sie die folgenden Schritte aus, um ein Diagramm manuell zu erstellen:

  1. Verbinden und Lesen von Objekttabellen

    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. Bereiten Sie Knoten- und Kanten-DataFrames vor.

    # 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. Definieren Sie das Diagrammschema, und binden Sie 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. Erstellen Sie das Diagramm.

    # 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() bereitet Daten vor und veröffentlicht sie in einem Anruf. Um vorbereitete Knoten und Kanten vor der Veröffentlichung zu prüfen, rufen Sie Graph.prepare(spec) auf, überprüfen Sie graph.nodes und graph.edges, und rufen Sie dann graph.publish() auf.

  5. Führen Sie eine GQL-Abfrage aus.

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

Testen des Graph-Notizbuchs

Testen Sie das Notizbuch, um sicherzustellen, dass es die erwartete Graphausgabe erzeugt:

  1. Starten Sie den Kernel neu, und führen Sie alle Zellen von oben nach unten aus. Screenshot der Schaltfläche

  2. Bestätigen Sie, dass jede Zelle erfolgreich abgeschlossen wird.

  3. Wenn Transformationszellen auf einem kleinen Pool länger als 5 Minuten laufen, optimieren Sie Snapshot-Filter und Spaltenprojektion, bevor Sie hochskalieren.

  4. Bestätigen Sie, dass show_schema() die erwarteten Knoten und Kanten zurückgibt.

  5. Führen Sie eine GQL-Beispielabfrage aus, und überprüfen Sie die Visualisierung und tabellarische Ausgabe.

  6. Validieren Sie Randfälle:

    • Leere Eingabe.
    • Schemaabweichung.
    • Kein Zugriff auf die Tabelle.

Tip

Fügen Sie über jedem Codeabschnitt Markdown-Zellen hinzu, um Zweck, Eingaben, Ausgaben sowie die erzeugten Knoten oder Kanten zu dokumentieren.

Planen Sie einen Graph-Job, um den Graphen zu materialisieren.

Diagramme, die in einer interaktiven Sitzung erstellt wurden, sind kurzlebig. Planen Sie einen Diagrammauftrag, um das Diagramm beizubehalten und zu aktualisieren. Weitere Informationen finden Sie unter Planen und Verwalten von Microsoft Sentinel Diagrammaufträgen.

  1. Wählen Sie in Ihrem Graph-Notebook Geplanten Auftrag erstellen>Einen Graph-Auftrag erstellen aus. Screenshot der Schaltfläche

  2. Geben Sie den Diagrammnamen und die Beschreibung ein, und überprüfen Sie den Notizbuchpfad.

  3. Wählen Sie einen Zeitplan aus:

    • Bei Anforderung: wird einmal erstellt, mit einer standardmäßigen Aufbewahrungsdauer von 30 Tagen.
    • Geplant: Wählen Sie das Wiederholungsintervall sowie die Start- und Endzeiten aus.
  4. Wählen Sie "Absenden" aus.

  5. Öffnen Sie das Diagramm in der Sentinel-Erweiterung, und überwachen Sie Auftragsdetails.

  6. Verwenden Sie "Jetzt ausführen" , um nach Bedarf außerhalb des Zeitplans auszuführen.

  7. Bestätigen Sie den Statusfortschritt von Queued zu In Progress zu Ready.

Important

Übermittelte Aufträge werden von Ihrem lokalen Notizbuch entkoppelt. Das Bearbeiten des lokalen .ipynb aktualisiert den geplanten Auftrag nicht. Um ein Auftragsnotizbuch zu aktualisieren, laden Sie es aus dem Bereich "Graphs" herunter, bearbeiten Sie es, und verwenden Sie dann " Auftrag>übermitteln".

Abfragen und Visualisieren aus dem Graph-Explorer

Sobald der Status des Graphauftrags Ready lautet, können Sie im Defender-Portal sowie in Notebooks und über REST-APIs Abfragen ausführen und visualisieren.

  1. Öffnen Sie im Defender-Portal unter Microsoft Sentinel die Graphenumgebung, und wählen Sie Ihren materialisierten Graphen aus.
  2. Führen Sie GQL-Abfragen aus, untersuchen Sie das Schema, wechseln Sie zwischen visueller und tabellarischer Ausgabe und wechseln Sie zum nächsten Sprung.
  3. Verwenden Sie diese GQL-Kurzübersicht:
Muster oder Klausel Example
Knoten mit Beschriftung (g:EntraGroup)
Typisierte, gerichtete Kante -[c:ContainsUser]->
Pfad variabler Länge (1 bis 8 Sprünge) (a)-[e]->{1,8}(b)
Filter WHERE g.displayName = 'Finance Admins'
Projizieren, sortieren, begrenzen RETURN g.displayName ORDER BY g.displayName LIMIT 10
Beschriftungsausdrücke (:EntraUser \| EntraServicePrincipal)

Note

Jede GQL-Abfrage beginnt mit MATCH. Die Engine arbeitet mit UTC. Verwenden Sie ZONED_DATETIME(...) für Datetime-Literale. INSERT und CREATE werden nicht unterstützt. Grafen sind nur lesbar.

  1. Abfrage aus einem Notizbuch.

    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. Abfragen mithilfe von Graph-REST-APIs.

    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 steuert die Ausgabeform. "Table" Gibt Zeilen zurück, "Graph" gibt Knoten und Kanten zurück und ["Table", "Graph"] gibt beide zurück.

Weitere Informationen finden Sie unter Graph-REST-APIs für benutzerdefinierte Diagramme.

Packen und Veröffentlichen Ihrer Graph-Lösung

Nachdem Ihr Diagramm getestet und materialisiert wurde, packen Sie es für die Bereitstellung für Kunden. Ausführliche Anweisungen zum Packen finden Sie unter Microsoft Sentinel Graph- und Notebooklösungen packen und veröffentlichen.

Problembehandlung

Verwenden Sie die folgenden Tabellen, um häufige Probleme nach Symptom zu diagnostizieren.

Diagrammerstellung

Symptom Wahrscheinliche Ursache und Behebung
MicrosoftSentinelProvider oder sentinel_graph nicht gefunden Melden Sie sich erneut bei der Erweiterung an, und bestätigen Sie, dass ein Microsoft Sentinel Kernel ausgewählt ist.
Zelle sitzt fest bei „Startet Spark-Sitzung” Der erste Start kann 3 bis 5 Minuten dauern. Wenn sie 6 Minuten überschreitet, überprüfen Sie die Poolkapazität, und versuchen Sie es erneut.
show_schema() ist leer oder Graph.build() schlägt fehl. Bestätigen Sie, dass Schlüssel- und Anzeigespalten vorhanden sind und nicht null sind, und Quell- und Zielwerte node_type entsprechen Knotenaliasen.
GQL-Abfrage gibt keine Zeilen zurück. Bestätigen Sie, dass Filterwerte in der ausgewählten Momentaufnahme vorhanden sind, und überprüfen Sie die Momentaufnahmefilterung.
publish() schlägt mit „Zugriff verweigert“ fehl. Vergewissern Sie sich, dass Sie über die Rolle "Sicherheitsoperator", "Sicherheitsadministrator" oder "Globaler Administrator" verfügen.

KI-unterstützte Dokumenterstellung

Symptom Wahrscheinliche Ursache und Behebung
@sentinel /graph-authoring macht nichts Vergewissern Sie sich, dass GitHub Copilot- und Jupyter-Erweiterungen installiert und aktiv sind, und Sie verfügen über einen Copilot Business- oder Enterprise-Plan.
Generierter Code verweist auf eine fehlende Tabelle Bestätigen Sie die Konfiguration des Konnektors und überprüfen Sie, ob die Tabelle im Data Lake-Explorer angezeigt wird.

Feinterminierung

Symptom Wahrscheinliche Ursache und Behebung
Änderungen am lokalen Notebook werden im Job nicht berücksichtigt. Laden Sie das Job-Notebook im Bereich Graphen herunter, bearbeiten Sie es und verwenden Sie dann Job bearbeiten>Senden.
Materialisierte Grafik verschwunden On-Demand-Diagramme haben eine Aufbewahrung von 30 Tagen. Planen Sie einen wiederkehrenden Job oder führen Sie einen neuen Build aus.