Nota
O acesso a esta página requer autorização. Pode tentar iniciar sessão ou alterar os diretórios.
O acesso a esta página requer autorização. Pode tentar alterar os diretórios.
Note
Esta funcionalidade está atualmente em pré-visualização. Consulte Termos Suplementares de Utilização para Versões Prévias do Microsoft Azure.
Uma solução personalizada de grafos Microsoft Sentinel é uma solução baseada em cadernos que define nós e arestas a partir de tabelas de data lake do Microsoft Sentinel, constrói um grafo e permite aos utilizadores consultar esse grafo com a Linguagem de Consulta de Grafos (GQL).
Use este guia para construir, testar, materializar, empacotar e publicar uma solução de grafos personalizada como uma oferta SaaS no Centro de Parceiros Microsoft, para que os clientes possam descobri-la na Microsoft Security Store.
Pré-requisitos
Tens de estar integrado no data lake para criar soluções Custom Graph. Para mais informações, veja Como integrar o data lake Microsoft Sentinel.
Permissions
A tabela seguinte lista as permissões necessárias para cada operação ou âmbito neste guia.
| Operation | Função necessária |
|---|---|
| Adesão ao data lake do Sentinel | Microsoft Entra ID - Administrador de Segurança ou Administrador Global |
| Integrar a área de trabalho do Sentinel no portal Defender | Proprietário da Subscrição ou Administrador de Acesso do Utilizador ao nível da subscrição e Contribuidor do Microsoft Sentinel ao nível da subscrição ou do grupo de recursos |
| Integrar o espaço de trabalho do Sentinel no data lake | Proprietário da subscrição ou Contribuidor do Microsoft Sentinel ao nível da subscrição ou do grupo de recursos |
| Modelar e criar um gráfico de bloco de notas | Função RBAC unificada personalizada do Microsoft Defender XDR com a permissão data (manage) para a recolha de dados do Microsoft Sentinel |
| Guardar de forma persistente (materializar) um grafo | Operador de Segurança, Administrador de Segurança ou Administrador Global |
| Consultar um gráfico persistente | Função unificada de RBAC personalizada do Microsoft Defender XDR com security data basics (read) controlo sobre a recolha de dados do Microsoft Sentinel |
| Publicação da solução Custom Graph | Conta do Marketplace Publisher no Centro de Parceiros Microsoft |
Tools
As seguintes ferramentas são necessárias para construir e publicar uma solução de grafos personalizada:
- Código do Visual Studio.
- Extensão Microsoft Sentinel para Visual Studio Code. Para mais informações, consulte Instalar Visual Studio Code e a extensão Microsoft Sentinel.
- Extensão Jupyter para Visual Studio Code.
- Extensão do GitHub Copilot e um plano GitHub Copilot Business ou Enterprise.
- Python 3.10 ou posterior na tua máquina local.
Sugestão
Reutilize um data lake existente se o seu inquilino já estiver integrado para consultas KQL, notebooks ou um Security agente do Copilot. Há um lago de dados por locatário. No portal do Defender, aceda a Sistema>Definições>Microsoft Sentinel>Data lake. Se o estado estiver Provisionado, salta a tarefa 1.
Fluxo de compilação
O fluxo de trabalho seguinte descreve os passos para construir e publicar uma solução de grafos personalizada.
- Ingere dados de amostra nas tabelas que o seu gráfico modela.
- Valide a conectividade com um notebook básico.
- Criar o gráfico personalizado.
- Testa o caderno de gráficos.
- Agende um trabalho de gráfico para materializar o gráfico.
- Consulta e visualiza o grafo a partir do explorador de grafos.
- Empacote e publique a solução de gráfico personalizada.
Importar dados de exemplo
Esta tarefa ingere tabelas de ativos do Microsoft Entra ID usadas pelo gráfico de exemplo neste guia: EntraUsers, EntraGroups, EntraServicePrincipals, e EntraMembers.
- No portal do Defender, aceda a Sistema>Definições>Microsoft Sentinel>Conectores de dados.
- Ative o conector Microsoft Entra ID para que as tabelas de ativos do Entra sejam importadas para o data lake. Para mais informações, consulte Dados de ativos no Microsoft Sentinel data lake.
- Confirme que estas tabelas aparecem no explorador do lago de dados:
EntraUsersEntraGroupsEntraServicePrincipalsEntraMembers
- Estas tabelas são colocadas no espaço de trabalho Tabelas do sistema.
- Opcional: importar outros conectores e substituir nomes de tabelas nos passos seguintes se o seu cenário utilizar dados diferentes.
Note
Se uma tabela não aparecer no explorador de lagos de dados, não pode usá-la para criação de grafos, e a assistência de IA não a referencia.
Validar a conectividade com um notebook simples
Crie e execute um bloco de notas mínimo para verificar a conectividade do data lake antes de criar grafos.
Abra o Visual Studio Code e inicie sessão na extensão Microsoft Sentinel com a mesma conta que tem acesso ao data lake.
No Visual Studio Code, em Sentinel Extension–Graphs, selecione Criar novo caderno.
Guarde o caderno, por
hello-world-show-tables.ipynbexemplo.Selecione Select kernel, selecione Microsoft Sentinel e selecione um pool de spark disponível.
Adicione as células seguintes por ordem.
Célula 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
Célula 2 - Código (liga e define o teu espaço de trabalho):
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}")
Célula 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.
Célula 4 - Código (leia uma tabela e mostre as linhas):
# 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)
Célula 5 - Código (contagens opcionais de sanidade):
# Confirm the read returned data and inspect the schema.
print("Row count:", df_groups.df.count())
df_groups.df.printSchema()
- Analise todas as células de cima a baixo.
- Confirme que todas as células estão concluídas sem um rastreamento vermelho, os dados de pré-visualização da tabela aparecem e a contagem de linhas é diferente de zero.
Note
Se as leituras falharem ou não devolverem linhas, confirme que o conector da secção Ingerir dados de exemplo concluiu o seu primeiro instantâneo, que LOG_ANALYTICS_WORKSPACE corresponde a uma área de trabalho real e que a sua conta tem acesso de leitura. Verifique o conteúdo da tabela com KQL no portal Defender para confirmar a presença de dados. Para mais informações, consulte Executar consultas KQL no data lake Microsoft Sentinel.
Criar gráfico personalizado
Autor de uma destas formas:
- Criação de grafos assistida por IA.
- Autor à mão.
Autoria de grafos assistida por IA
Para criar um gráfico com assistência de IA, siga estes passos:
No Visual Studio Code, abra o Chat do GitHub Copilot.
Comece o prompt com o assistente de criação de grafos
@sentinel /graph-authoringe descreva o seu grafo em linguagem simples:@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.O Copilot gera as seguintes células para o ciclo de criação do grafo:
Fase do ciclo de vida Produção gerada Configuração do ambiente Verifica os pacotes necessários e as informações de ligação Carregamento de dados Lê tabelas nomeadas do lago de dados Sentinel Transformação de dados Prepara dados de nós e arestas Esquema de grafo Define os nós e as arestas Validação de esquemas Valida a definição do grafo Construção de grafos Materializa o gráfico da sessão Consulta de grafos Executa uma consulta GQL de exemplo e visualiza o resultado Continue a aperfeiçoar o bloco de notas com pedidos como estes:
Goal Prompt Adicionar uma relação @sentinel Add an edge from User to IPAddressFiltrar dados @sentinel Filter the data to show only failed sign-insAlterar intervalo de tempo @sentinel Change the time range to the last 7 daysCorrigir erro de compilação @sentinel Fix the error in the graph build stepCompreender o código @sentinel Explain how edge keys are definedProcure uma API sem editar What parameters does build_graph_with_data() accept? #Sentinel
Sugestão
Use @sentinel /graph-authoring para criar ou modificar células de caderno. Se precisares de explicações sobre a API ou de consultas de exemplo, pergunta ao Copilot e inclui #Sentinel para obter respostas específicas do Sentinel.
Escrever manualmente
Para criar um gráfico manualmente, siga estes passos:
Ligue-se a e leia tabelas de recursos.
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") )Prepare os DataFrames de nós e arestas.
# 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"))) )Defina o esquema do grafo e associe 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()Constrói o gráfico.
# 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 dados e publica numa só chamada. Para inspecionar os nós e as arestas preparados antes da publicação, chameGraph.prepare(spec), revejagraph.nodesegraph.edgese, em seguida, chamegraph.publish().Executa uma consulta 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()
Teste o caderno de grafos
Teste o caderno para garantir que produz a saída esperada do gráfico:
Reinicia o kernel e executa todas as células de alto a baixo.
Confirme que cada célula está concluída com sucesso.
Se as células de transformação demorarem mais de 5 minutos num pool pequeno, restrinja os filtros de snapshot e a projeção de colunas antes de aumentar a escala.
Confirme que
show_schema()devolve os nós e arestas esperados.Executa uma consulta GQL de exemplo e verifica a visualização e a saída tabular.
Validar casos limite:
- Entrada vazia.
- Desvio do esquema.
- Falta acesso à mesa.
Sugestão
Adicione células de Markdown acima de cada secção de código para documentar a finalidade, as entradas, as saídas e os nós ou arestas produzidos.
Agende uma tarefa de grafo para materializar o grafo
Os grafos criados numa sessão interativa são efémeros. Agende um trabalho de grafo para persistir e atualizar o gráfico. Para mais informações, consulte Agendar e gerir trabalhos de grafos Microsoft Sentinel.
No seu notebook de grafos, selecione Criar Tarefa Agendada>Criar uma tarefa de grafo.
Introduza o Nome e Descrição do grafo e verifique o caminho do caderno.
Selecione um horário:
- A pedido: compila uma vez, com um período de retenção predefinido de 30 dias.
- Programado: selecionar a frequência de repetição e as horas de início e de fim.
Selecione Enviar.
Abre o gráfico na extensão Sentinel e monitoriza os Detalhes da tarefa.
Utilize Run Now para executar fora da programação quando necessário.
Confirme a progressão do estado de
QueuedparaIn ProgressparaReady.
Importante
Os trabalhos submetidos são independentes do seu notebook local. Editar o local .ipynb não atualiza o trabalho agendado. Para atualizar um caderno de trabalhos, descarrega-o do painel Graphs, edita-o e depois usa Editar Enviar trabalho>.
Consultar e visualizar a partir do explorador de grafos
Quando o estado da tarefa do gráfico for Ready, consulte e visualize dados no portal do Defender, em notebooks e em APIs REST.
- No portal do Defender, em Microsoft Sentinel, abra a experiência de grafos e selecione o grafo materializado.
- Executar consultas GQL, inspecionar o esquema, trocar as saídas visuais e tabulares, e percorrer o próximo salto.
- Usa esta referência rápida do GQL:
| Padrão ou cláusula | Exemplo |
|---|---|
| Nó com rótulo | (g:EntraGroup) |
| Aresta tipada e dirigida | -[c:ContainsUser]-> |
| Caminho de comprimento variável (1 a 8 saltos) | (a)-[e]->{1,8}(b) |
| Filter | WHERE g.displayName = 'Finance Admins' |
| Projetar, ordenar, limitar | RETURN g.displayName ORDER BY g.displayName LIMIT 10 |
| Expressões de etiqueta | (:EntraUser \| EntraServicePrincipal) |
Note
Toda consulta GQL começa com MATCH. O motor funciona em UTC. Use ZONED_DATETIME(...) para literais de data e hora.
INSERT e CREATE não são suportados. Os gráficos são apenas de leitura.
Consulta a partir de um 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()Consulta usando APIs Graph REST.
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 Controla a forma da saída.
"Table" devolve linhas, "Graph" devolve nós e arestas, e ["Table", "Graph"] devolve ambos.
Para mais informações, consulte Graph REST APIs para grafos personalizados.
Empacote e publique a sua solução de grafos
Depois de o seu gráfico ser testado e materializado, empacote-o para implementação nos clientes. Para instruções detalhadas de embalagem, consulte Empacotar e publicar soluções para grafos e cadernos Microsoft Sentinel.
Troubleshooting
Use as tabelas seguintes para diagnosticar problemas comuns por sintoma.
Autoria de grafos
| Symptom | Causa provável e solução |
|---|---|
MicrosoftSentinelProvider ou sentinel_graph não encontrado |
Inicie sessão novamente na extensão e confirme que um kernel Microsoft Sentinel foi selecionado. |
| A célula fica bloqueada na "Sessão de início do Spark" | O primeiro arranque pode demorar entre 3 a 5 minutos. Se ultrapassar os 6 minutos, verifica a capacidade da piscina e tenta novamente. |
show_schema() é vazio ou Graph.build() falha |
Confirme que as colunas de chave e de apresentação existem e não são nulas, e que os valores de origem e de destino node_type correspondem aos aliases dos nós. |
| A consulta GQL não retorna linhas | Confirme que os valores do filtro existem no instantâneo selecionado e verifique a filtragem do instantâneo. |
publish() falha devido a permissão negada |
Confirme que tem funções de Operador de Segurança, Administrador de Segurança ou Administrador Global. |
Autoria assistida por IA
| Symptom | Causa provável e solução |
|---|---|
@sentinel /graph-authoring Não faz nada |
Confirma que as extensões GitHub Copilot e Jupyter estão instaladas e ativas, e tens um plano Copilot Business ou Enterprise. |
| Código gerado faz referência a uma tabela em falta | Confirme a configuração do conector e verifique se a tabela aparece no explorador do lago de dados. |
Agendamento de tarefas
| Symptom | Causa provável e solução |
|---|---|
| As edições locais do notebook não são refletidas na tarefa | Descarrega o caderno de tarefas a partir do painel de Gráficos, edita-o e depois usa Editar Enviar trabalho>. |
| O grafo materializado desapareceu | Os gráficos on-demand têm retenção de 30 dias. Agende uma tarefa recorrente ou execute uma nova compilação. |
Conteúdo relacionado
- Gráficos personalizados na visão geral do Microsoft Sentinel
- Comece a usar gráficos personalizados
- Autoria de grafos personalizados assistida por IA
- Referência do fornecedor de grafos Microsoft Sentinel
- Referência GQL para grafo personalizado Sentinel
- APIs REST de grafos para grafos personalizados
- Integrar no lago de dados do Microsoft Sentinel
- Executar notebooks no lago de dados do Microsoft Sentinel
- Publique um agente do Security Copilot ou uma solução analítica na Security Store
- Centro de Parceiros da Microsoft