monitoring
307 TopicsEvoluindo a Resposta a Incidentes em AKS com Azure SRE Agent - Parte 1
Resumo executivo Em aplicações executadas no Azure Kubernetes Services (AKS), eventos OOMKilled estão entre as causas recorrentes de reinicialização de contêineres e indisponibilidade intermitente em aplicações web. A observabilidade fornecida por Azure Monitor, Container Insights, Log Analytics e métricas Prometheus permite detectar o sintoma, registrar o evento e disparar o alerta. A detecção isolada, porém, ainda deixa para a equipe de plantão o trabalho mais caro: correlacionar métricas, logs, eventos, alterações recentes e limites de recursos até chegar a uma hipótese defensável. Sobre essa base de observabilidade, o Azure SRE Agent adiciona uma camada de raciocínio e execução governada. Ao receber o incidente, ele coleta evidências nas fontes conectadas, valida hipóteses e produz um diagnóstico explicável. Em seguida, recomenda a ação de menor risco e, conforme o modo de execução configurado, solicita aprovação humana ou executa uma remediação pré-autorizada. O resultado é um fluxo mais rápido e rastreável, sem eliminar os controles de acesso e aprovação. Este whitepaper documenta o padrão em um laboratório reproduzível. No cenário, um pod em CrashLoopBackOff por limite de memória subdimensionado (20 Mi de limite, 10 Mi de solicitação) é investigado, diagnosticado e corrigido pelo agente sob aprovação humana, com verificação posterior e disparo automatizado por alerta do Azure Monitor. Além do passo a passo, o documento aprofunda a mecânica que sustenta o diagnóstico, cgroups v2, o OOM killer do kernel, classes de QoS, working set versus RSS e o comportamento de heap dos runtimes, porque a qualidade da resposta assistida depende diretamente da qualidade dos sinais que a alimentam. O que este documento entrega A anatomia técnica de um evento OOMKilled em AKS, do cgroup ao status do pod. Consultas KQL e PromQL prontas para detecção e para o desenho da regra de alerta. O modelo operacional do Azure SRE Agent: fontes de contexto, modos de execução, permissões, hooks e políticas de acesso a ferramentas. Um laboratório completo, do provisionamento do agente à recuperação verificada do workload. Um enquadramento de governança, auditoria e segurança para operações agênticas. O que este documento não cobre Disparo totalmente automatizado a partir do alerta e integração com o processo de gestão de incidentes, tema da Parte 2. Ajuste fino de capacidade em escala de frota (VPA/HPA em produção), tratado apenas como método. Valores de preço vigentes; o modelo de cobrança é descrito de forma qualitativa. 1. Introdução Aplicações nativas de nuvem distribuem o processamento entre pods, serviços, dependências e nós. Essa elasticidade melhora a escala, mas amplia a complexidade da investigação quando uma falha ocorre. Em um incidente de memória, o primeiro sinal pode ser um pod reiniciado, uma elevação de erros HTTP, aumento de latência ou degradação parcial de uma jornada específica. O problema raramente é a ausência de dados. É o custo cognitivo de atravessar métricas, logs, eventos do Kubernetes, histórico de implantação e manifestos sob pressão de tempo, para só então formular uma hipótese. Esse custo é pago integralmente a cada incidente, e não se acumula como conhecimento reutilizável. Este whitepaper apresenta um padrão de resposta a incidentes em que o Azure Monitor sustenta a detecção e a telemetria, enquanto o Azure SRE Agent converte sinais em contexto operacional acionável, preservando a decisão humana onde ela é necessária. 2. Contexto e desafio operacional O cenário considera uma aplicação web em AKS instrumentada com Container Insights, Log Analytics, métricas Prometheus e alertas do Azure Monitor. O desafio não é apenas saber que um contêiner foi encerrado, é determinar por que a memória ultrapassou o limite, qual versão e qual carga estavam envolvidas, qual foi o impacto ao usuário e qual ação reduz risco sem ocultar a causa raiz. Ou seja, transformar sinais distribuídos em uma decisão defensável sobre pressão de tempo. Telemetria distribuída entre métricas, logs, eventos e histórico de implantação. Pressão de tempo para restaurar o serviço antes da violação do SLO. Risco de reinicializações repetitivas que mascaram a ausência de correção estrutural. Necessidade de aprovação, rastreabilidade e segregação de funções em ambientes regulados. Há ainda um viés operacional relevante: sob pressão, o caminho mais curto, reiniciar o pod ou ampliar o limite de memória, quase sempre funciona no curto prazo. Isso torna difícil distinguir, retrospectivamente, um limite subdimensionado de um vazamento de memória lento, porque a evidência que separaria os dois é descartada junto com o contêiner encerrado. 3. Anatomia técnica do evento OOMKilled Antes de delegar a investigação a um agente, é necessário estabelecer com precisão o que o sinal significa. Boa parte dos diagnósticos incorretos de memória em Kubernetes nasce da confusão entre três mecanismos distintos: o OOM killer do kernel atuando no cgroup do contêiner, o despejo (eviction) decidido pelo kubelet por pressão no nó, e o encerramento por falha da aplicação. 3.1 O caminho do kernel: cgroups v2, memory.max e o OOM killer Quando um contêiner declara resources.limits.memory, o kubelet traduz esse valor para o controlador de memória do cgroup correspondente. Em nós AKS com imagens baseadas em Ubuntu 22.04 ou superior e Azure Linux 3.0, padrão em versões recentes do Kubernetes, o runtime opera sobre cgroup v2, e o limite é materializado no arquivo memory.max do cgroup do contêiner. A partir daí, o comportamento é do kernel Linux, não do Kubernetes. Quando as páginas anônimas do cgroup não podem mais ser recuperadas e a alocação ultrapassaria memory.max, o kernel invoca o OOM killer restrito àquele cgroup, escolhe um processo e envia SIGKILL. O contador correspondente é incrementado em memory.events, no campo oom_kill. # Dentro do nó, inspecionando o cgroup do contêiner (cgroup v2) cat /sys/fs/cgroup/.../memory.max # limite efetivo (bytes) cat /sys/fs/cgroup/.../memory.high # ponto de throttling por reclaim cat /sys/fs/cgroup/.../memory.current # uso corrente cat /sys/fs/cgroup/.../memory.events # low / high / max / oom / oom_kill Vale distinguir dois campos frequentemente confundidos em memory.events: max conta quantas vezes a alocação esbarrou no teto e forçou reclaim, enquanto oom_kill conta quantos processos foram efetivamente encerrados. Um valor alto em max com oom_kill igual a zero indica um contêiner operando permanentemente no limite: degradado, porém vivo. É exatamente o estado que antecede o incidente e que raramente dispara alerta. Como o processo recebe SIGKILL (sinal 9), o código de saída observado é 137, resultado da convenção POSIX 128 + número do sinal. O kubelet então registra o término e reinicia o contêiner conforme a restartPolicy. É por isso que a evidência canônica não está no status corrente do pod, mas no estado anterior do contêiner: kubectl get pod <pod> -n pets -o jsonpath='{.status.containerStatuses[0].lastState.terminated}' | jq # Saída esperada em um OOMKill: # { # "exitCode": 137, # "reason": "OOMKilled", # "startedAt": "...", # "finishedAt": "..." # } Reinícios sucessivos levam o pod a CrashLoopBackOff, em que o kubelet aplica um atraso exponencial entre tentativas, iniciando na ordem de dezenas de segundos e dobrando até um teto de poucos minutos, cujo valor padrão vem sendo revisado em versões recentes do Kubernetes. Esse atraso é o motivo pelo qual a indisponibilidade percebida cresce ao longo do incidente mesmo sem agravamento da causa raiz. 3.2 OOMKilled não é eviction: dois mecanismos, duas correções A distinção é operacionalmente decisiva porque as correções divergem: um OOMKill se resolve no manifesto do workload; um despejo se resolve na capacidade ou no agendamento do nó. Dimensão OOMKilled (cgroup) Eviction (kubelet) Gatilho Alocação excede memory.max do cgroup do contêiner memory.available do nó abaixo do limiar evictionHard/evictionSoft Quem decide Kernel Linux (OOM killer restrito ao cgroup) kubelet, ordenando os pods por QoS e excesso sobre requests Escopo Um contêiner O pod inteiro, podendo atingir vários pods do nó Sinal SIGKILL → exit code 137 Encerramento do pod; sem exit code 137 característico Evidência lastState.terminated.reason = OOMKilled status.phase = Failed, reason = Evicted Objeto do pod Preservado; contêiner reinicia no mesmo pod Pod permanece como registro de falha e é reagendado por seu controlador Correção típica Ajustar limits/requests ou o consumo da aplicação Capacidade do nó, requests coerentes, limiares de despejo, distribuição Nota. Um terceiro caso é frequentemente confundido com ambos: o encerramento do processo principal por erro da aplicação, que produz códigos de saída próprios (1, 2, 143 para SIGTERM). Verificar exitCode e reason antes de concluir por memória evita corrigir o sintoma errado. 3.3 Classes de QoS e a ordem em que os pods são sacrificados O Kubernetes deriva a classe de Quality of Service de cada pod a partir da relação entre requests e limits. Essa classe não é apenas rótulo: ela determina a prioridade de despejo e influencia diretamente o valor de oom_score_adj atribuído aos processos do contêiner. Classe de QoS Condição Prioridade de despejo Guaranteed requests iguais a limits para CPU e memória em todos os contêineres Última a ser despejada Burstable Pelo menos um request ou limit definido, sem igualdade entre eles Intermediária, proporcional ao excesso sobre o request BestEffort Nenhum request ou limit definido Primeira a ser despejada Para pods Burstable, o kubelet calcula oom_score_adj em função da fração da memória do nó reservada pelo request: quanto menor o request em relação à capacidade do nó, maior o score e mais atraente o processo se torna para o OOM killer. Pods Guaranteed recebem um valor fortemente negativo, e pods BestEffort recebem o valor máximo. Aplicação ao laboratório O order-service deste cenário declara requests de 10 Mi e limits de 20 Mi. A desigualdade entre os dois o classifica como Burstable, e o request muito baixo em relação à capacidade do nó eleva seu oom_score_adj. O workload é, portanto, simultaneamente o mais provável de estourar o próprio limite e um dos primeiros candidatos ao OOM killer sob pressão do nó, combinação que o torna um caso de teste representativo. Há uma consequência de projeto pouco explorada: elevar apenas o limit sem elevar o request melhora a sobrevivência ao OOMKill do cgroup, mas mantém o pod vulnerável em cenários de pressão do nó, porque o agendador continua reservando pouca memória para ele. Foi exatamente por isso que a recomendação do agente no laboratório ajustou os dois valores, e não apenas o limite. 3.4 Working set, RSS e por que o dashboard pode enganar A métrica que melhor aproxima a decisão do OOM killer é o working set, e não o RSS. Em cAdvisor, a fonte de container_memory_working_set_bytes e da métrica memoryWorkingSetBytes exposta pelo Container Insights, o working set corresponde ao uso total do cgroup menos o page cache inativo, isto é, a porção da memória que o kernel não conseguiria liberar trivialmente sob pressão. Métrica O que representa Uso recomendado container_memory_working_set_bytes Uso do cgroup menos page cache inativo Referência para alertas e para dimensionar limits container_memory_rss Páginas anônimas residentes do processo Investigação de vazamento no heap da aplicação container_memory_usage_bytes Uso total, incluindo page cache reclaimável Diagnóstico; superestima a pressão real container_memory_cache Page cache atribuído ao cgroup Explicar divergência entre usage e working set A armadilha prática: um painel construído sobre container_memory_usage_bytes pode indicar uso próximo ao limite sem risco real, porque boa parte é cache recuperável. Inversamente, um painel com média de 5 minutos pode mostrar 60% de uso e ainda assim o contêiner ser encerrado, porque o OOM killer reage a um pico instantâneo que a agregação suavizou. Alertas de memória devem usar working set e agregação por máximo, não por média. 3.5 Heap do runtime versus limite do contêiner Uma causa frequente de OOMKilled não está no limite em si, mas no desalinhamento entre o limite do cgroup e a política de heap do runtime. Runtimes que dimensionam o heap a partir da memória visível do host, e não do limite do cgroup, planejam crescer muito além do que o contêiner pode alocar, e o kernel encerra o processo antes que o coletor de lixo julgue necessário agir. Runtime Controle recomendado Observação Node.js --max-old-space-size (MB) Fixar abaixo do limite do contêiner; o order-service deste laboratório é Node.js JVM -XX:MaxRAMPercentage com UseContainerSupport Reservar espaço para metaspace, threads e buffers fora do heap .NET DOTNET_GCHeapHardLimitPercent; avaliar Server GC Server GC eleva o consumo por número de núcleos visíveis Go GOMEMLIMIT Limite flexível: intensifica a coleta em vez de abortar Python Limitar workers e pool de conexões Sem heap gerenciado; o consumo escala com concorrência Regra prática: o limite do contêiner deve acomodar o heap máximo do runtime somada a memória fora do heap, pilhas de threads, buffers de I/O, conexões, bibliotecas nativas e o próprio page cache anônimo. Dimensionar o heap igual ao limite do contêiner é uma causa clássica de OOMKilled sob carga. 3.6 Causas frequentes Limite subdimensionado: o consumo legítimo da carga excede o valor configurado, como ocorre neste laboratório. Vazamento de memória: o processo retém memória de forma progressiva entre requisições. Pico de tráfego ou payload atípico: a demanda transitória ultrapassa a capacidade provisionada. Concorrência excessiva: workers, filas ou caches locais ampliam o working set de forma não linear. Requests e limits incoerentes: o agendamento e a contenção não refletem o perfil real de consumo. Heap do runtime maior que o limite do cgroup: o processo planeja crescer além do permitido. Valores herdados de um dimensionamento anterior que nunca foi revisado após mudanças de código ou de carga. 4. Impactos para aplicações web em AKS Dimensão Impacto potencial Usuário Erros HTTP 5xx, timeouts, perda de sessão e latência elevada. Aplicação Interrupção de requisições em andamento, reprocessamento e perda de cache local. Plataforma CrashLoopBackOff, aumento de restarts e pressão sobre outros pods ou nós. Negócio Violação de SLO, risco à receita e degradação da experiência digital. Operações Escalonamento de plantão, investigação manual e aumento do MTTR. Um agravante específico do OOMKilled é o efeito em cascata: ao reiniciar, o contêiner reconstrói caches e refaz conexões, produzindo um pico de consumo de memória e CPU justamente no momento em que a capacidade agregada do serviço está reduzida. Isso pode encadear novos encerramentos em réplicas ainda saudáveis e transformar uma falha localizada em degradação do serviço. 5. Detecção: sinais, consultas e desenho do alerta A qualidade da investigação assistida depende da qualidade dos sinais disponíveis. Esta seção consolida as consultas usadas para detectar OOMKilled em AKS e o desenho da regra de alerta empregada no laboratório. 5.1 Sinais canônicos # Estado atual e contagem de reinícios kubectl get pods -n pets -o wide # Razão do término anterior, a evidência decisiva kubectl get pods -n pets -o custom-columns=\ NAME:.metadata.name,\ STATUS:.status.phase,\ RESTARTS:.status.containerStatuses[0].restartCount,\ REASON:.status.containerStatuses[0].lastState.terminated.reason,\ EXIT:.status.containerStatuses[0].lastState.terminated.exitCode # Limites efetivamente aplicados ao contêiner kubectl get deployment order-service -n pets \ -o jsonpath='{.spec.template.spec.containers[0].resources}' # Eventos correlatos na janela do incidente kubectl get events -n pets --sort-by=.lastTimestamp 5.2 Consultas KQL no Log Analytics Com Container Insights habilitado, o inventário de pods carrega o estado anterior de cada contêiner em formato JSON, o que permite isolar terminações por OOMKilled diretamente na consulta: // Contêineres encerrados por OOMKilled nas últimas 6 horas KubePodInventory | where TimeGenerated > ago(6h) | where isnotempty(ContainerLastStatus) | extend LastStatus = parse_json(ContainerLastStatus) | where tostring(LastStatus.reason) == "OOMKilled" | project TimeGenerated, ClusterName, Namespace, Name, ContainerName = ContainerName, ExitCode = toint(LastStatus.exitCode), RestartCount = ContainerRestartCount, FinishedAt = todatetime(LastStatus.finishedAt) | summarize Ocorrencias = count(), Ultima = max(FinishedAt), MaxRestarts = max(RestartCount) by ClusterName, Namespace, ContainerName | order by Ocorrencias desc Os eventos do Kubernetes oferecem uma segunda camada de confirmação, útil quando o intervalo de coleta do inventário perde uma terminação de curta duração: // Eventos de OOM e falhas de inicialização correlatas KubeEvents | where TimeGenerated > ago(6h) | where Reason in ("OOMKilling", "OOMKilled", "BackOff", "Failed") | project TimeGenerated, ClusterName, Namespace, Name, Reason, Message | order by TimeGenerated desc Para separar limite subdimensionado de vazamento, a consulta relevante é a tendência do working set contra o limite declarado. Um platô estável junto ao teto sugere subdimensionamento; uma inclinação positiva sustentada entre reinícios sugere retenção progressiva: // Working set máximo por contêiner, em janelas de 5 minutos Perf | where TimeGenerated > ago(24h) | where ObjectName == "K8SContainer" | where CounterName == "memoryWorkingSetBytes" | summarize MaxWorkingSetMi = max(CounterValue) / 1024 / 1024 by bin(TimeGenerated, 5m), InstanceName | render timechart 5.3 Equivalentes em PromQL Em clusters com Azure Monitor managed service for Prometheus, os mesmos sinais ficam disponíveis como séries temporais, o que facilita alertas baseados em razão de utilização: # Razão entre working set e limite declarado, por pod max by (namespace, pod, container) ( container_memory_working_set_bytes{namespace="pets", container!=""} ) / max by (namespace, pod, container) ( kube_pod_container_resource_limits{namespace="pets", resource="memory"} ) # Contêineres cuja última terminação foi OOMKilled kube_pod_container_status_last_terminated_reason{reason="OOMKilled"} == 1 # Taxa de reinícios na última hora increase(kube_pod_container_status_restarts_total{namespace="pets"}[1h]) > 0 Nota. Um alerta preventivo sobre a razão working set / limite acima de 0,85 por vários minutos antecipa o incidente antes do primeiro OOMKill, transformando uma interrupção em uma tarefa de dimensionamento planejada. Essa é a regra que mais reduz incidentes desta classe. 5.4 Desenho da regra de alerta utilizada no laboratório A regra empregada no cenário é uma Log Alert V2 sobre o workspace do Log Analytics, avaliando a consulta de OOMKilled e disparando quando a contagem de resultados é maior que zero. Parâmetro Valor no laboratório Consideração de produção Tipo Log search alert (Log Alerts V2) Consultas sobre logs; considerar alerta de métrica para latência menor Escopo Workspace do Log Analytics do cluster Escopo por cluster ou por assinatura, conforme o modelo de plantão Lógica Contagem de resultados maior que 0 Aumentar o limiar para tolerar reinícios isolados e evitar ruído Severidade 1, Error Alinhar à criticidade do serviço e à política de plantão Frequência / janela Avaliação periódica sobre janela curta Janela igual ou maior que a frequência, para não perder eventos Ação Action group com notificação por e-mail Encaminhar também a ITSM/PagerDuty e ao gatilho do agente Auto-resolução Padrão da regra Habilitar para incidentes transitórios; desabilitar se exigir baixa manual Latência esperada de ponta a ponta No laboratório, o pod entrou em OOMKilled às 17h45 e a notificação chegou às 17h47. Esses dois minutos somam ingestão no Log Analytics, período de avaliação da regra e entrega pelo action group. Alertas baseados em log carregam essa latência por construção, um dado relevante ao definir SLOs de detecção e ao decidir entre alerta de log e alerta de métrica. 6. O processo tradicional e seus limites 6.1 Fluxo típico de resposta O Azure Monitor dispara o alerta e notifica o plantão. O plantonista abre o portal, os dashboards e o Log Analytics. Executa comandos kubectl para localizar o pod e confirmar a razão do término. Compara consumo, limite, reinícios, eventos e alterações recentes. Formula uma hipótese, reinicia ou reimplanta o workload e acompanha a recuperação. Registra evidências e ações no sistema ITSM. 6.2 Limitações do modelo reativo Esse fluxo depende da experiência individual, exige alternância constante entre ferramentas e produz decisões inconsistentes entre plantonistas. Um restart reduz o sintoma, mas não distingue vazamento de memória, limite inadequado ou pico legítimo de carga. Sob pressão, cresce também o risco de ampliar recursos sem validação, perder evidências ao encerrar o contêiner afetado ou executar ações privilegiadas fora do processo de mudança. O custo mais alto, porém, é invisível: o conhecimento produzido durante a investigação permanece no indivíduo e não fica disponível para o próximo incidente da mesma classe. 7. Azure SRE Agent: arquitetura e modelo operacional O Azure SRE Agent é um agente de confiabilidade que conecta fontes de observabilidade, plataformas de incidente, repositórios de código e conhecimento operacional. Ele investiga causas prováveis, propõe mitigações e automatiza respostas orientadas por planos e runbooks, dentro de guardrails e fluxos de aprovação. Princípio de arquitetura O Azure Monitor permanece como fonte de detecção e evidência. O SRE Agent atua como camada de investigação, decisão e orquestração governada. O agente não substitui a observabilidade: ele consome e correlaciona o que ela produz. 7.1 Fontes de contexto A qualidade do diagnóstico é função direta das fontes conectadas. Durante a configuração, o agente solicita explicitamente a associação de quatro categorias de contexto. Fonte O que habilita Uso no cenário OOMKilled Recursos do Azure Consultar e operar recursos por meio da identidade do agente Ler o estado do cluster AKS e aplicar a mitigação aprovada Logs Consultar workspaces do Log Analytics Correlacionar eventos, inventário de pods e métricas de working set Código Acessar repositórios e artefatos de engenharia Relacionar o limite aplicado ao manifesto de origem Incidentes Integrar Azure Monitor, ServiceNow e PagerDuty Receber o alerta e vincular a investigação ao incidente 7.2 Execução por ferramentas e classificação de risco O agente não age por um canal opaco, cada passo é uma chamada de ferramenta explícita, um comando da CLI do Azure, uma consulta KQL, um comando kubectl, apresentada na thread com o comando exato e uma classificação de risco associada. No laboratório, comandos de leitura como az aks show aparecem marcados como Safe, enquanto operações como kubectl get deployments e kubectl patch recebem a marcação Medium risk. Essa transparência tem duas consequências práticas. A primeira é auditoria: a thread registra a sequência exata de comandos, permitindo reconstruir a investigação. A segunda é revisão: o operador avalia o comando concreto, não uma descrição em linguagem natural do que o agente pretende fazer. 7.3 Modos de execução (Run Modes) Os modos de execução controlam o fluxo de aprovação, isto é, se o agente pergunta antes de agir. É importante separar esse conceito das permissões, que controlam o acesso ao recurso. O agente precisa das duas condições satisfeitas para executar uma ação. Modo Comportamento Indicação Review O agente propõe a ação e aguarda Approve ou Deny Produção, infraestrutura crítica, alertas de segurança Autonomous O agente executa imediatamente e relata o que fez Ambientes de não produção e tarefas recorrentes confiáveis Três detalhes que mudam o desenho de governança Primeiro: o modo de execução é definido por plano de resposta e por tarefa agendada, não no nível do agente; a configuração do agente serve apenas como padrão de fallback. Segundo: os botões Approve e Deny aparecem para operações de infraestrutura do Azure; outras ações, como enviar e-mail, publicar no Teams ou consultar fontes externas, seguem a instrução do plano de resposta e exigem hooks ou políticas de acesso a ferramentas para receber controle equivalente. Terceiro: apenas administradores do SRE Agent podem aprovar ações, o que materializa a segregação de funções. Uma observação de adoção relevante: os planos de resposta e as tarefas agendadas assumem Autonomous como padrão, enquanto o agente é criado em Review. Assumir que criar o agente em Review protege automaticamente todos os fluxos é um erro de configuração fácil de cometer e caro de descobrir. 7.4 Permissões, escopo e elevação sob demanda O agente opera por meio de uma identidade gerenciada, e o que ele consegue fazer é delimitado pelas atribuições RBAC dessa identidade e pelo escopo em que foram concedidas. Quando o agente não possui a permissão necessária para uma operação, ele solicita acesso temporário por meio do fluxo On-Behalf-Of do Microsoft Entra, em vez de falhar silenciosamente. Esse comportamento é arquiteturalmente importante: ele permite conceder à identidade do agente um conjunto mínimo e permanente de permissões de leitura, deixando as operações de escrita dependentes de uma elevação explícita e rastreável. É o oposto do padrão adotado no laboratório, que concede permissões amplas por conveniência de demonstração. 7.5 Hooks e políticas de acesso a ferramentas Hooks são pontos de verificação personalizados que validam, auditam ou bloqueiam o comportamento do agente em momentos específicos do fluxo. Eles complementam os modos de execução: enquanto os modos controlam quando o agente pode agir, os hooks controlam o que acontece antes e depois de cada ação. Evento Quando dispara Aplicações típicas PostToolUse Após a execução de uma ferramenta Auditar o uso, bloquear ou sinalizar operações inseguras, injetar contexto adicional no resultado Stop Quando o agente vai devolver a resposta final Validar completude, exigir formato, rejeitar a resposta e forçar continuidade da investigação Tipos de execução: Prompt, avaliado pelo modelo para verificações que exigem julgamento; e Command, script determinístico para auditoria e aplicação de política. Escopos de configuração: no nível do agente, aplicando-se a todas as threads; ou no nível de um agente personalizado. Quando ambos correspondem, os dois executam. Políticas de acesso a ferramentas complementam os hooks ao restringir previamente quais ferramentas podem ser invocadas em cada contexto. 7.6 Provedor de modelo e residência de dados O provedor de modelo é escolhido na criação do agente e pode ser alterado depois, sem recriar o recurso. Há duas famílias disponíveis, com perfis distintos: modelos do Azure OpenAI e modelos Anthropic Claude. Para organizações reguladas, essa escolha ultrapassa o critério de qualidade de raciocínio e entra no domínio de conformidade: os provedores diferem quanto à cobertura de requisitos de residência de dados, incluindo o EU Data Boundary, e a disponibilidade varia por região. A recomendação é validar os requisitos de residência e a lista de regiões suportadas na documentação vigente antes de padronizar o provedor para cargas de produção. 7.7 Modelo de consumo O consumo do agente é medido em Azure Agent Units e combina dois componentes: um fluxo contínuo, associado à existência do agente e ao monitoramento de base, e um fluxo ativo, proporcional aos tokens processados durante investigações. Modelos com janelas de contexto maiores tendem a consumir mais no fluxo ativo. A implicação de FinOps é direta: o custo escala com o volume de investigações e com a profundidade do contexto conectado, não com o número de recursos monitorados. Reduzir alertas ruidosos diminui o custo do agente pelo mesmo mecanismo que reduz a fadiga do plantão. Consulte a página de preços para os valores vigentes. 8. Processo de resposta com o SRE Agent Receber e classificar: consumir o incidente do Azure Monitor e aplicar filtros por severidade, serviço e título. Coletar evidências: consultar Log Analytics, métricas, eventos do Kubernetes, estado do pod, histórico de implantação e runbooks. Formar hipóteses: comparar limite versus uso, tendência temporal, payload, versão implantada e eventos correlatos. Validar: sustentar cada hipótese com evidência observável e registrar as alternativas descartadas. Recomendar: apresentar ação imediata, correção estrutural, risco associado e critérios de rollback. Agir sob governança: executar apenas ações pré-autorizadas ou aguardar aprovação, conforme o modo de execução do plano. Verificar e aprender: confirmar a estabilidade, documentar o resultado e enriquecer a memória operacional. A etapa 4 é a que mais diferencia uma investigação assistida de uma sugestão genérica. Um diagnóstico útil não afirma apenas qual é a causa provável: registra qual evidência sustenta a conclusão, qual hipótese foi descartada e por quê. É esse registro que permite ao operador revisar a decisão em segundos, em vez de refazer a investigação. 9. Cenário do incidente 9.1 Situação O serviço order-service, no namespace pets, processa requisições de uma aplicação web de comércio eletrônico. Após aumento de tráfego e uso de payloads maiores, as réplicas passam a reiniciar. O Azure Monitor detecta a elevação na contagem de reinicializações e a ocorrência de eventos OOMKilled. 9.2 Linha de investigação # Evidência buscada Interpretação 1 reason igual a OOMKilled e exitCode 137 em lastState Encerramento pelo kernel por ultrapassagem do limite do cgroup, não falha da aplicação. 2 Working set atingindo o limite declarado Distinguir limite inadequado de crescimento anômalo entre requisições. 3 Pico correlacionado a tráfego ou tamanho de payload Avaliar comportamento legítimo versus retenção progressiva de memória. 4 Implantação recente do workload Determinar se houve regressão em código ou em configuração de recursos. 5 Contagem de restarts e erros HTTP Quantificar impacto ao usuário e urgência da mitigação. 6 Classe de QoS e relação requests/limits Avaliar exposição adicional a despejo por pressão no nó. 9.3 Formato do diagnóstico assistido O agente entrega um resumo com causa provável, grau de confiança, evidências que a sustentam, alternativas descartadas e plano de mitigação com critério de reversão. A estrutura importa tanto quanto o conteúdo: ela permite que a revisão humana seja auditoria, e não repetição do trabalho. O contêiner atingiu repetidamente o limite de memória durante o processamento de payloads acima do padrão histórico. Não há evidência suficiente de crescimento contínuo entre requisições; a hipótese principal é limite subdimensionado para a nova carga. Mitigação proposta: elevar limits e requests de memória, com verificação do consumo após a alteração. 10. Implementação e validação do cenário no AKS A seguir, o padrão conceitual é aplicado a um ambiente AKS de demonstração. O objetivo é conectar o cluster ao SRE Agent, conceder as permissões necessárias, integrar as fontes de observabilidade e validar o fluxo de diagnóstico e recuperação de um pod afetado por OOMKilled. Preparar o ambiente: validar o cluster AKS, a aplicação de demonstração e o estado inicial do workload. Criar o SRE Agent: provisionar o agente e selecionar o provedor de modelo conforme os requisitos do ambiente. Conectar as fontes de dados: integrar o cluster, o Azure Monitor e o Log Analytics para disponibilizar alertas, logs e métricas. Conceder permissões: atribuir à identidade gerenciada do agente o acesso necessário para investigar e, no laboratório, executar a remediação aprovada. Validar diagnóstico e recuperação: provocar o evento OOMKilled, acompanhar a investigação, aprovar a recomendação e confirmar a recuperação do pod. Escopo do laboratório As permissões concedidas nesta seção são deliberadamente amplas para reduzir o atrito da demonstração. Elas não representam uma configuração recomendada para produção. A seção 10.5 apresenta o desenho de menor privilégio equivalente, e a seção 12 detalha as implicações de segurança. 10.1 Ambiente e pré-requisitos A aplicação utilizada é o AKS Store Demo, exemplo de referência da Microsoft que representa uma loja de comércio eletrônico decomposta em microsserviços poliglotas. A tabela a seguir consolida a configuração do ambiente, para permitir a reprodução do cenário. Componente Configuração no laboratório Cluster AKS-SRE-Demo-Cluster, SKU Base, tier Free, 1 node pool Versão do Kubernetes 1.35.6 Região East US 2 Rede Azure CNI Overlay Observabilidade Container Insights habilitado, enviando logs e métricas ao Log Analytics Aplicação AKS Store Demo, namespace pets, exposta por Service do tipo LoadBalancer Workload em falha order-service (Node.js), requests 10 Mi / limits 20 Mi de memória Alerta Alert-OOMKilled-Pods, Log Alerts V2, severidade 1, Error Agente Azure SRE Agent provisionado no grupo de recursos Azure-SRE-RG A arquitetura da aplicação é relevante para o diagnóstico: o order-service recebe pedidos do store-front e os publica em uma fila RabbitMQ, consumida pelo makeline-service. Um serviço que faz buffer de mensagens antes de publicar é estruturalmente sensível ao tamanho do payload e à concorrência, precisamente o perfil que torna um limite de 20 Mi insustentável sob carga. 10.2 Arquitetura e estado inicial da aplicação Figura 1: Arquitetura do AKS Store Demo. O store-front e o store-admin consomem o order-service (Node.js), o product-service (Rust), o makeline-service (Go) e o ai-service (Python), com RabbitMQ como broker de mensagens e MongoDB como armazenamento de estado. Figura 2: Página inicial da aplicação de demonstração, publicada por meio de um Service do tipo LoadBalancer. O endereço IP público foi suprimido. Figura 3: Visão geral do cluster AKS antes da investigação: Kubernetes 1.35.6, região East US 2, configuração de rede Azure CNI Overlay e um único node pool. Identificadores de assinatura e o endereço do servidor de API foram suprimidos. A inspeção do namespace revela o estado que servirá de referência para todo o exercício. O pod do order-service encontra-se em CrashLoopBackOff, acumulando reinicializações sucessivas, o sintoma de superfície de um encerramento repetido pelo kernel. Figura 4: Saída de kubectl get all -n pets. O pod do order-service aparece em CrashLoopBackOff com reinicializações acumuladas, enquanto os demais serviços do namespace permanecem íntegros. Endereços IP públicos foram suprimidos. Nota. Observe que apenas um serviço está afetado. Essa assimetria já elimina hipóteses de escopo mais amplo, pressão de memória no nó, falha do runtime de contêiner ou problema de rede, e concentra a investigação na configuração ou no comportamento daquele workload específico. 10.3 Criação do agente e escolha do provedor de modelo O agente é provisionado no portal do SRE Agent, em sre.azure.com. Figura 5: Portal do Azure SRE Agent. A criação inicia pela opção Create Agent. No formulário, define-se o grupo de recursos, o nome do agente e o provedor de modelo. É possível escolher entre Azure OpenAI, com a família GPT-5, e Anthropic, com a família Claude, e alterar essa opção posteriormente sem recriar o recurso. Conforme discutido na seção 7.6, essa escolha deve considerar também os requisitos de residência de dados da organização. Figura 6: Formulário de criação do agente, com a seleção do grupo de recursos, do nome e do provedor de modelo. Figura 7: Revisão da configuração antes da confirmação. Nomes de assinatura foram suprimidos. Figura 8: Provisionamento do agente em andamento. Figura 9: Agente criado. A opção Set up your agent conduz à configuração das fontes de contexto. 10.4 Conexão das fontes de contexto O objetivo do agente é investigar as aplicações em execução no cluster AKS. Para isso, conecta-se primeiro o recurso do cluster. Figura 10: Associação do recurso do cluster AKS ao agente. Figura 11: Seleção do grupo de recursos onde o cluster AKS está provisionado. Figura 12: Confirmação do escopo selecionado. Nomes de assinatura foram suprimidos. Neste laboratório, o agente receberá permissões ampliadas para executar tarefas específicas no cluster. Essa configuração é restrita ao ambiente de demonstração. Em produção, recomenda-se aplicar o princípio do menor privilégio, limitar o escopo das funções, exigir aprovação para ações de maior impacto e validar previamente operações autorizadas, como alterar um pod ou recuperar um nó com estado desconhecido. Figura 13: Definição do nível de permissão concedido ao agente sobre os recursos conectados. Em seguida, integra-se o agente ao Azure Monitor, para que ele acesse os alertas configurados e inicie uma investigação quando o incidente correspondente for emitido. Figura 14: Integração com o Azure Monitor, habilitando o consumo de alertas como gatilho de investigação. Além do Azure Monitor, o agente pode ser integrado ao ServiceNow e ao PagerDuty para apoiar fluxos de investigação e gestão de incidentes, permitindo que a thread da investigação seja correlacionada ao registro formal do incidente. Figura 15: Integrações disponíveis com plataformas de gestão de incidentes. O cluster tem o Container Insights habilitado e envia logs e métricas ao workspace do Log Analytics. Conectar esse workspace é o que permite ao agente executar as consultas KQL apresentadas na seção 5 durante a investigação. Figura 16: Início da conexão com o Log Analytics. Figura 17: Seleção do workspace do Log Analytics associado ao cluster. Figura 18: Preenchimento dos dados do workspace. Identificadores de assinatura foram suprimidos. Figura 19: Conclusão da conexão com o Log Analytics. Figura 20: Painel de configuração das fontes de contexto, consolidando código, logs, recursos do Azure e incidentes. A amplitude do contexto conectado determina diretamente a profundidade possível do diagnóstico. 10.5 Identidade gerenciada e atribuições RBAC Neste ponto o agente já é funcional para investigação. Para que ele também possa executar a remediação no cluster, atribuem-se funções à sua identidade gerenciada. O primeiro passo é identificar essa identidade. Figura 21: Identidade gerenciada associada ao agente. Os identificadores de cliente, de principal e de assinatura foram suprimidos. No laboratório, foram atribuídas as funções Azure Kubernetes Service Cluster Admin Role e Azure Kubernetes Service Contributor Role, com escopo no grupo de recursos do cluster. az role assignment create ` --assignee "<uami-client-id>" ` --role "Azure Kubernetes Service Cluster Admin Role" ` --scope "/subscriptions/<subscription-id>/resourceGroups/Azure-SRE-RG" az role assignment create ` --assignee "<uami-client-id>" ` --role "Azure Kubernetes Service Contributor Role" ` --scope "/subscriptions/<subscription-id>/resourceGroups/Azure-SRE-RG" Figura 22: Resultado da atribuição da função Azure Kubernetes Service Cluster Admin Role. Identificadores de assinatura, de principal e da atribuição foram suprimidos. Figura 23: Resultado da atribuição da função Azure Kubernetes Service Contributor Role. A confirmação é feita no painel Access control (IAM) do cluster, localizando as atribuições concedidas à identidade gerenciada do agente. Figura 24: Painel de controle de acesso do cluster, confirmando as duas atribuições à identidade gerenciada do agente (destacadas). Identificadores de objeto e nomes de entidades de serviço do locatário foram suprimidos. Por que essa configuração não deve ir para produção A função Azure Kubernetes Service Cluster Admin Role autoriza a obtenção da credencial administrativa do cluster. Essa credencial é um certificado de cliente que opera fora da integração com o Microsoft Entra ID e da autorização RBAC do Kubernetes, ou seja, contorna exatamente os controles de identidade que a organização configurou no cluster. Some-se a isso a função Contributor no grupo de recursos, e a identidade do agente passa a acumular controle administrativo do plano de dados e amplo poder no plano de controle. O desenho equivalente sob menor privilégio troca esse par de funções por um conjunto mínimo, com escopo no cluster e não no grupo de recursos, apoiando-se no fluxo de elevação sob demanda descrito na seção 7.4 para as operações de escrita eventuais. Necessidade Função recomendada Escopo Obter kubeconfig respeitando o Entra ID Azure Kubernetes Service Cluster User Role Cluster Leitura no plano de dados do Kubernetes Azure Kubernetes Service RBAC Reader Cluster ou namespace Escrita controlada no plano de dados Azure Kubernetes Service RBAC Writer Namespace do workload Consultar métricas e logs Monitoring Reader Workspace do Log Analytics Operações de infraestrutura do cluster Elevação sob demanda via fluxo On-Behalf-Of Por operação, com registro Nota. As funções RBAC do Kubernetes (Reader, Writer, Admin) exigem que a autorização RBAC do Azure para Kubernetes esteja habilitada no cluster. Escopar por namespace, e não pelo cluster inteiro, reduz o raio de impacto de uma ação incorreta ao conjunto de workloads sob responsabilidade daquele agente. 10.6 Investigação assistida A primeira interação é deliberadamente simples: uma pergunta aberta sobre a saúde do cluster, sem indicar o problema. O objetivo é avaliar se o agente chega ao workload afetado por conta própria. Figura 25: Estado do pod do order-service imediatamente antes da investigação, usado como linha de base para validar diagnóstico e recuperação. Figura 26: O agente inicia a investigação executando comandos de inspeção. Cada chamada de ferramenta exibe o comando exato e a classificação de risco associada: Safe para az aks show e Medium risk para kubectl get deployments. Identificadores de assinatura foram suprimidos. A Figura 26 concentra o que diferencia esse modelo de uma automação convencional. O agente não executa um runbook fixo: ele escolhe o próximo comando a partir do resultado do anterior, e cada escolha fica registrada com o comando literal e sua classificação de risco. O operador acompanha a cadeia de raciocínio como uma sequência auditável de operações, não como uma caixa-preta que devolve uma conclusão. Figura 27: O agente identifica o pod do order-service em CrashLoopBackOff, com 13 reinicializações acumuladas. A partir do estado do pod, o agente correlaciona a razão do término com os limites declarados no manifesto e conclui que o limite de 20 Mi é insuficiente para a carga observada. A recomendação é elevar o limite para 128 Mi e a solicitação para 64 Mi, acompanhando o consumo após a alteração. Figura 28: Diagnóstico do agente: OOMKilled associado ao limite de 20 Mi e à solicitação de 10 Mi, com recomendação de elevação para 128 Mi e 64 Mi respectivamente. Figura 29: Continuação do diagnóstico, com o detalhamento das evidências e das alternativas consideradas. Leitura crítica da recomendação A recomendação ajusta requests e limits em conjunto, e não apenas o limite, o que, conforme a seção 3.3, preserva a classe Burstable com uma reserva de memória compatível e reduz a exposição a despejo por pressão no nó. O agente também sinaliza que valores maiores, como 256 Mi, só devem ser adotados após análise de métricas, testes de carga e investigação de possível vazamento. Essa ressalva é o que separa uma mitigação de uma correção: o número proposto restabelece o serviço, mas ainda não é um dimensionamento validado. 10.7 Mitigação aprovada e verificação A recomendação é apresentada como uma ação concreta a ser aprovada. O comando exibido é exatamente o que será executado: kubectl patch deployment order-service -n pets --type='json' -p='[ {"op":"replace", "path":"/spec/template/spec/containers/0/resources/limits/memory", "value":"128Mi"}, {"op":"replace", "path":"/spec/template/spec/containers/0/resources/requests/memory", "value":"64Mi"} ]' O efeito é alterar os recursos de memória do deployment order-service no namespace pets: o limite passa de 20 Mi para 128 Mi e a solicitação, de 10 Mi para 64 Mi. Como a alteração atinge o template do pod, o controlador executa um rollout, substituindo as réplicas existentes. Figura 30: Proposta de alteração apresentada para revisão. A ação é classificada como Medium risk e apresenta os controles Approve action e Cancel, com a indicação de que as permissões do agente serão utilizadas para concluí-la. Aprovada a ação, o agente a executa e passa espontaneamente à verificação, consultando o estado do novo pod em vez de declarar sucesso pela ausência de erro no comando. Figura 31: Após aplicar o patch, o agente consulta o estado do novo pod e aguarda a conclusão do startup probe antes de concluir. Esse detalhe merece destaque: o agente distingue a execução bem-sucedida de um comando da recuperação efetiva do serviço, e aguarda a passagem pelo startup probe antes de afirmar que o problema foi resolvido. É a mesma disciplina que se espera de um operador experiente. Figura 32: Comparação entre o estado anterior e o posterior apresentada pelo agente, acompanhada da ressalva sobre reconciliação com a fonte da verdade quando o deployment é gerenciado por GitOps, Helm ou pipeline de IaC. Dimensão Antes Depois Estado do pod CrashLoopBackOff, 13 reinicializações Running, Ready, 0 reinicializações Memória (request/limit) 10 Mi / 20 Mi 64 Mi / 128 Mi Classe de QoS Burstable, com reserva mínima Burstable, com reserva compatível Figura 33: Validação manual por kubectl: todos os objetos do namespace pets em execução, com o order-service estável e sem reinicializações. 10.8 Reconciliação com a fonte da verdade Um ponto levantado pelo próprio agente na Figura 32 merece tratamento explícito, porque é onde a maioria das remediações assistidas falha silenciosamente: a alteração foi aplicada diretamente ao objeto no cluster. Se o deployment for gerenciado por GitOps, Helm ou qualquer pipeline de infraestrutura como código, a fonte da verdade continua declarando 20 Mi. A próxima reconciliação do controlador, ou a próxima implantação, reverterá a correção e reintroduzirá o incidente, agora sem a memória do diagnóstico que o originou. O sintoma reaparece dias depois, aparentemente sem causa. Modelo de gestão Efeito do kubectl patch Ação obrigatória de fechamento Manifesto aplicado manualmente Persiste até a próxima aplicação Atualizar o manifesto no repositório Helm Revertido no próximo upgrade Atualizar o values.yaml e versionar o chart GitOps (Flux/Argo CD) Revertido na próxima reconciliação Abrir pull request na fonte da verdade Pipeline de IaC Revertido na próxima execução Atualizar o template e o registro de mudança Regra operacional Toda mitigação aplicada diretamente ao cluster deve gerar um item de acompanhamento na fonte da verdade antes do encerramento do incidente. Um incidente cuja correção existe apenas no cluster não está resolvido: está agendado para reincidir. 10.9 Do acionamento sob demanda ao disparo por alerta Até aqui, o agente foi acionado sob demanda. A etapa seguinte valida o caminho automatizado: um alerta do Azure Monitor configurado para disparar quando um pod apresentar terminação por OOMKilled. Figura 34: Regra de alerta configurada no Azure Monitor para detectar terminações por OOMKilled no cluster. Para provocar o evento de forma controlada, utiliza-se uma aplicação local que gera carga sobre o order-service até que o consumo ultrapasse o limite do cgroup. Figura 35: Painel local de simulação, com o gatilho de geração de carga sobre o order-service e o acompanhamento de pods íntegros, terminações por OOMKilled e alertas disparados. Às 17h45, o pod entra em estado OOMKilled com código de saída 137. Figura 36: Confirmação do estado por kubectl, evidenciando a terminação por OOMKilled. Dois minutos após o evento, a notificação do alerta chega ao destinatário configurado no action group, intervalo que corresponde à soma da ingestão no Log Analytics, do período de avaliação da regra e da entrega da notificação. Figura 37: Notificação recebida por e-mail às 17h47, referente à regra Alert-OOMKilled-Pods. Figura 38: Detalhe da notificação, indicando a condição atendida: contagem de resultados maior que zero, com o valor alcançado igual a 1. O disparo é então confirmado no portal do Azure, com a severidade e o tipo de sinal registrados. Figura 39: Alerta registrado no portal do Azure com estado Fired. Figura 40: Detalhes do alerta: severidade 1, Error, tipo de sinal Log Alerts V2 e horário de disparo consistente com o evento observado no cluster. Com esse alerta emitido e o agente integrado ao Azure Monitor, o gatilho necessário para a automação completa está validado. A Parte 2 tratará da transição do acionamento assistido para o fluxo disparado automaticamente pelo alerta, incluindo planos de resposta, modos de execução por plano e a integração com o processo de gestão de incidentes. 10.10 Do restabelecimento ao dimensionamento correto O laboratório encerra com o serviço estável, mas os valores aplicados são uma mitigação informada, não um dimensionamento validado. Fechar o ciclo exige um método, e esse método é independente do agente. Estabelecer a linha de base: medir o working set em percentil 95 e 99 sobre uma janela que cubra o ciclo completo de carga do serviço, incluindo picos previsíveis. Definir o request pelo consumo típico: o percentil 95 do working set em regime normal, valor que o agendador usará para reservar capacidade. Definir o limit com folga sobre o pico: o percentil 99 acrescido de margem para transientes, tipicamente entre 25% e 50%, evitando folga excessiva que desperdiça capacidade do nó. Alinhar o runtime: ajustar o heap máximo conforme a seção 3.5, reservando espaço para memória fora do heap. Validar sob carga: reproduzir o cenário que originou o incidente e confirmar que o working set permanece abaixo do limite com margem estável. Descartar vazamento: comparar a inclinação do consumo entre reinícios; crescimento sustentado sem correlação com a carga indica retenção progressiva, que nenhum aumento de limite resolve. Automatizar a revisão: usar o Vertical Pod Autoscaler em modo recomendação para acompanhar a adequação dos valores ao longo do tempo, sem aplicação automática. Nota. Elevar o limite de memória é uma resposta legítima quando a evidência aponta subdimensionamento, e ilegítima quando serve para adiar a investigação de um vazamento. A diferença entre as duas situações está na inclinação do consumo entre reinícios, um dado que só existe se a telemetria for retida além do ciclo de vida do contêiner. 11. Governança, aprovação e rastreabilidade Esta seção separa deliberadamente dois planos: capacidades do produto, que podem ser verificadas na documentação, e recomendações de arquitetura, que cada organização deve validar e adaptar às próprias políticas. Nota. Nomenclaturas, opções e comportamentos evoluem. Antes de aplicar este padrão em produção, valide a documentação vigente, os controles disponíveis no ambiente e os requisitos internos de segurança, auditoria e mudança. 11.1 O que foi observado no laboratório O agente coletou métricas, eventos e o estado dos pods para investigar o incidente, com cada comando registrado na thread. Identificou que os valores de memória estavam subdimensionados para a carga observada. Propôs um comando kubectl patch explícito, exibindo a alteração de 20 Mi para 128 Mi no limite e de 10 Mi para 64 Mi na solicitação. Apresentou a ação para revisão humana, classificada como Medium risk, e aguardou aprovação antes de executar. Após a aprovação, executou a alteração e verificou a recuperação do pod antes de concluir. Sinalizou espontaneamente o risco de reversão da correção em cenários gerenciados por GitOps ou Helm. Esse comportamento reflete o cenário demonstrado e não estabelece regra universal para todas as ferramentas, comandos ou ambientes. 11.2 Referência de governança para a organização A tabela a seguir é uma recomendação de desenho, não uma matriz fixa nem garantia de comportamento do produto. Categoria Exemplos Política sugerida Leitura get, list, show, describe, consultas KQL Permitir quando escopo e RBAC forem compatíveis com a investigação. Escrita patch, update, scale, restart Exigir revisão humana em ambientes críticos por meio de Review Mode no plano de resposta ou de hooks. Alto impacto delete, redução de capacidade, mudanças destrutivas Restringir por RBAC e por política de acesso a ferramentas; submeter a processo formal de mudança ou negar conforme o risco. A classificação de risco deve ser definida pela organização conforme o ambiente, o tipo de recurso, a criticidade do serviço e os requisitos regulatórios. A documentação do produto não deve ser interpretada como regra universal de que toda leitura é sempre permitida, toda escrita sempre exige aprovação ou todo delete é sempre negado. 11.3 Camadas de evidência para auditoria Nenhuma fonte isolada reconstrói o incidente por completo. A rastreabilidade útil vem da correlação entre camadas com escopos distintos. Camada O que registra Limitação Thread do agente Comandos executados, evidências, proposta e aprovação Escopo da conversa; confirmar retenção e exportação no ambiente Telemetria de auditoria do agente Atividade do agente para acompanhamento e conformidade Confirmar granularidade e campos disponíveis no ambiente Log de auditoria do Kubernetes Chamadas ao servidor de API do cluster Requer habilitação e destino de coleta configurados Azure Activity Log Operações do plano de controle do Azure Não cobre alterações internas do Kubernetes Sistema de ITSM Registro formal de incidente e mudança Depende da integração e da disciplina de preenchimento Recomenda-se correlacionar, conforme disponibilidade: horário da proposta e da execução; a ação ou comando apresentado ao operador; o estado anterior e posterior do recurso; o resultado da ferramenta e mensagens de erro relevantes; os identificadores do agente, recurso, alerta, incidente e mudança; e as informações de aprovação expostas pelos mecanismos disponíveis. 11.4 Fluxo recomendado para este cenário Etapa Aplicação no laboratório Controle recomendado 1. Diagnóstico e proposta O agente consulta métricas, eventos e estado do cluster e apresenta a ação recomendada. RBAC de menor privilégio, escopo por namespace e evidências observáveis. 2. Revisão humana Em Review Mode, o operador analisa o comando, o impacto e o escopo antes da execução. Critérios de aprovação e rollback definidos; aprovação restrita a administradores do agente. 3. Execução controlada Após a aprovação, o agente executa a alteração dentro das permissões concedidas. Identidade gerenciada, escopo mínimo, hooks de PostToolUse para auditoria. 4. Verificação O agente valida a recuperação antes de concluir. Critério de sucesso objetivo, baseado em estado observado e não em ausência de erro. 5. Reconciliação Não aplicável ao laboratório; a alteração permaneceu no cluster. Atualizar a fonte da verdade e vincular ao registro de mudança. 6. Registro O resultado é apresentado na thread do agente. Correlação entre telemetria, logs do cluster, registros do Azure e ITSM. Enquadramento Os modos de execução, os controles de acesso, os hooks e a telemetria são capacidades do produto. A matriz de risco, as evidências exigidas, as convenções de repositório e as integrações de auditoria são decisões de governança da organização. Manter essa separação explícita evita transformar recomendações de arquitetura em garantias de produto. 12. Considerações de segurança para operações agênticas Introduzir um agente com capacidade de execução no caminho de resposta a incidentes altera o modelo de ameaças da plataforma. As considerações a seguir derivam diretamente da configuração demonstrada. Consideração Risco Mitigação Privilégio excessivo Cluster Admin Role concede credencial que contorna o Entra ID e o RBAC do Kubernetes Substituir por Cluster User + RBAC Reader/Writer com escopo por namespace; elevar sob demanda Escopo amplo demais Funções no grupo de recursos alcançam recursos não relacionados ao incidente Escopar no recurso, não no grupo de recursos Segregação de funções Quem opera aprova a própria ação Restringir aprovação a administradores do agente distintos de quem aciona a investigação Conteúdo não confiável no contexto Logs e eventos podem carregar texto capaz de influenciar o raciocínio do agente Hooks de PostToolUse e políticas de acesso a ferramentas; revisão humana para ações de escrita Raio de impacto Uma ação incorreta atinge o cluster inteiro Escopo por namespace, janelas de mudança e critérios de rollback definidos previamente Residência de dados O provedor de modelo determina onde o contexto é processado Selecionar o provedor conforme os requisitos regulatórios e as regiões suportadas Exposição em capturas e threads Identificadores e segredos aparecem em evidências compartilhadas Revisar artefatos antes de circular; suprimir identificadores, como feito neste documento O item sobre conteúdo não confiável merece atenção particular. Durante a investigação, o agente lê logs e eventos produzidos pela aplicação, dados que, em última instância, podem ser influenciados por entradas de usuários. Tratar esse conteúdo como dado, e não como instrução, é responsabilidade compartilhada entre o produto e o desenho de governança: manter operações de escrita sob revisão humana em ambientes críticos é a defesa mais direta contra essa classe de risco. Princípio de composição Nenhum controle isolado é suficiente. A defesa em profundidade nesse modelo compõe quatro camadas independentes: RBAC delimita o que a identidade alcança; os modos de execução determinam se há aprovação humana; a classificação de risco por chamada de ferramenta informa a decisão do revisor; e os hooks aplicam política e auditoria antes e depois de cada ação. Remover qualquer uma delas transfere risco às demais. 13. Métricas para avaliar a adoção A adoção de resposta assistida deve ser avaliada por evidência, não por percepção. As métricas a seguir permitem comparar o antes e o depois de forma objetiva. Métrica O que mede Sinal de maturidade MTTD Tempo entre o evento e a detecção Estável; limitado pela latência de ingestão e avaliação MTTA Tempo entre o alerta e o início da investigação Redução acentuada com investigação automática MTTR Tempo entre o alerta e a recuperação verificada Redução sustentada, sem aumento de reincidência Taxa de aprovação sem alteração Recomendações aprovadas sem ajuste pelo operador Crescente; habilita migração seletiva para modo autônomo Taxa de reincidência em 30 dias Incidentes da mesma classe que retornam Decrescente; indica correção estrutural e não apenas mitigação Aderência à reconciliação Mitigações refletidas na fonte da verdade Próxima de 100%; principal defesa contra reincidência Ações autônomas por classe de risco Distribuição entre leitura, escrita e alto impacto Crescimento apenas nas classes com histórico consistente A recomendação de adoção é conservadora e apoiada na própria documentação do produto: iniciar em Review Mode, observar as recomendações por algumas semanas e migrar para modo autônomo apenas os gatilhos cujo padrão de aprovação já se mostrou consistente. A taxa de aprovação sem alteração é o indicador que sustenta essa decisão com dados. 14. Limitações e armadilhas observadas A mitigação foi aplicada diretamente ao cluster. Em ambientes gerenciados por GitOps, Helm ou IaC, a correção será revertida se a fonte da verdade não for atualizada. Os valores de 128 Mi e 64 Mi restabeleceram o serviço, mas constituem mitigação informada, não dimensionamento validado por testes de carga. As permissões concedidas no laboratório são amplas por conveniência de demonstração e contornam a integração com o Entra ID no plano de dados do cluster. Alertas baseados em log carregam latência de ingestão e de avaliação, dois minutos no laboratório, o que os torna inadequados para SLOs de detecção mais agressivos. Um restart bem-sucedido mascara a distinção entre limite subdimensionado e vazamento de memória; sem telemetria retida além do ciclo do contêiner, a diferença se perde. O modelo pode propor valores plausíveis, mas a validação por métricas e carga permanece responsabilidade da engenharia. O cenário cobre uma única classe de falha em um único workload; a generalização para outras classes exige validação própria. 15. Conclusão da Parte 1 O Azure Monitor e o Azure SRE Agent transformaram um evento OOMKilled em um fluxo governado de detecção, investigação, recomendação, aprovação e recuperação verificada. O resultado demonstra valor não apenas por restabelecer o pod, mas por correlacionar evidências, manter a decisão explicável e executar a remediação dentro dos limites de acesso definidos. Três observações se destacam do exercício. A primeira é que a transparência por chamada de ferramenta, com o comando literal e sua classificação de risco, transforma a revisão humana em auditoria rápida em vez de repetição do trabalho. A segunda é que o agente verificou a recuperação antes de concluir, distinguindo execução bem-sucedida de serviço restabelecido. A terceira é que ele sinalizou o risco de reversão por GitOps, armadilha que mais frequentemente converte uma correção em incidente recorrente. A conclusão arquitetural permanece: a observabilidade continua sendo a base. O agente amplifica o valor de uma telemetria bem construída, e amplifica igualmente as lacunas de uma telemetria pobre. Investir em sinais corretos, como working set em vez de uso bruto, agregação por máximo em vez de média e retenção além do ciclo de vida do contêiner, é pré-requisito, não consequência. Na Parte 2, o fluxo evoluirá do acionamento assistido para o disparo automatizado por alertas, com planos de resposta, definição de modos de execução por plano, hooks de auditoria e integração com o processo de gestão de incidentes. 16. Referências Azure SRE Agent Documentação do Azure SRE Agent Run Modes in Azure SRE Agent Agent Hooks in Azure SRE Agent Tutorial: Configure Agent Hooks Model Provider Selection in Azure SRE Agent Execute Mitigations in Azure SRE Agent Set up ServiceNow incident indexing Azure SRE Agent: preços Azure Monitor e observabilidade de contêineres Azure Monitor overview Overview of Azure Monitor alerts Container insights overview Consultas de exemplo para KubePodInventory Azure Monitor managed service for Prometheus Kubernetes e AKS Configure Quality of Service for Pods Node-pressure Eviction Resource Management for Pods and Containers Access and identity options for AKS AKS Store Demo: code sample170Views4likes1CommentNow Generally Available: Built-in CIS Benchmark Auditing for Linux on Azure
A few months ago, in From Policy to Practice: Built-in CIS Benchmarks on Azure – Flexible, Hybrid-Ready, we introduced a new way to bring Center for Internet Security (CIS) Benchmarks to your Linux estate using Azure Policy with Machine Configuration. It builds on the broader customizable security baseline policies in Machine Configuration capability. Today we're excited to share the next milestone: the audit capability for CIS Benchmarks on Linux is now Generally Available (GA). This release is officially powered by kompli - our native Linux compliance and hardening engine for CIS, STIG, and custom baselines. kompli is the evolution of the engine that drove the preview, now established as the dedicated home for this capability going forward. What "GA" means for you The audit experience is now ready for production use. You can continuously assess your Linux workloads against official, CIS-certified benchmarks - at scale, across Azure and hybrid environments through Azure Arc - and get clear, CIS-style compliance reporting directly in Azure Policy and Azure Resource Graph. If you've read the previous post, the how hasn't changed, so we'll keep this one short: Automated compliance assessment - continuously monitor Linux systems against official CIS benchmarks. Tailored benchmarks - customize evaluations with exceptions and custom parameters, no code changes required. Compliance reporting - detailed, CIS-style reports across your fleet. Hybrid-ready - the same baselines apply to Azure VMs and Arc-enabled servers on-premises or in other clouds. All supported benchmarks are CIS Benchmark Assessment Certified and stay in parity with the content published on the CIS website. Supported distributions and benchmark versions With this release, audit is GA across the following distributions, covering Level 1 + Level 2 Server profiles: Distribution CIS Benchmark Version(s) Profiles Audit Ubuntu 20.04 / 22.04 / 24.04 LTS + Pro v3.0.0 / v2.0.0 + v3.0.0 / v1.0.0 L1 + L2 Server ✓ Red Hat Enterprise Linux 8 / 9 / 10 v3.0.0 + v4.0.0 / v2.0.0 / v1.0.1 L1 + L2 Server ✓ AlmaLinux 8 / 9 v3.0.0 + v4.0.0 / v2.0.0 L1 + L2 Server ✓ Rocky Linux 8 / 9 v2.0.0 + v3.0.0 / v2.0.0 L1 + L2 Server ✓ Oracle Linux 8 / 9 v3.0.0 + v4.0.0 / v2.0.0 L1 + L2 Server ✓ Debian 11 / 12 v2.0.0 / v1.1.0 L1 + L2 Server ✓ SUSE Linux Enterprise 12 / 15 v3.2.1 / v2.0.1 L1 + L2 Server ✓ AKS Optimized Azure Linux 3 v1.0.0 L1 + L2 Server ✓ This GA covers the audit (assessment) capability. Looking ahead, STIG benchmarks are coming next, followed by a granular per-rule auto-remediation capability with dynamic scope assignments. You can run these benchmarks against your own hardened images, against CIS hardened images, and against custom images built on top of vanilla distros — as long as /etc/os-release retains its original content. We're also working with vendors to minimize deviations. Getting started Open Azure Policy in the Azure portal. Under Authoring, select the new Machine Configuration blade. Choose Official Center for Internet Security (CIS) Benchmarks for Linux Workloads, then Modify Settings to pick the distributions you want to assess. Full documentation, including per-distribution rule details, supported parameters, and any known deviations from the official CIS toolset, is available here: Overview: CIS Security Benchmarks for Linux Workloads Per-distribution references: AlmaLinux, Azure Linux, Debian, Oracle Linux, Red Hat Enterprise Linux, Rocky Linux, SUSE Linux Enterprise, and Ubuntu - all linked from the overview page. We're building this with you As part of this GA release, we've also expanded the set of exposed rule parameters compared to the preview - giving you more out-of-the-box customization across rules and distributions. That said, our customer-driven approach still stands: we keep the experience clean by enabling parameters based on real demand, so if there's a rule, benchmark version, or distribution you'd like parameters enabled for - or any feedback on rules, evaluations, or distro coverage - let us know: Open a GitHub issue in the kompli repository Open an Azure support case Try it out, tell us what you think, and help shape what we build next.354Views1like0CommentsAnnouncing the Open-Source Release of ML Video Codec (MLVC)
Video codecs compress video for transmission or storage, reducing bandwidth and storage requirements. MLVC is a modern machine-learning-based codec that uses substantially less bandwidth than conventional codecs, improving streaming and video-call quality—especially on constrained or unreliable networks—while lowering delivery and storage costs. MLVC is the product iteration of DCVC (Deep Contextual Video Compression) family of NVC (Neural Video Codec), open sourced by Microsoft Research since 2021, with improved compression efficiency, real-time performance on commodity Neural Processing Units (NPUs), and cross-platform support. We recently published this work in the paper MLVC: Multi-platform Learned Video Codec for Real-World Deployment. We are releasing the source code because we believe the next generation of video coding will be built openly, and we want the broader community — researchers, video codec engineers, platform vendors, product teams, as well as general developer community — to build it with us. Why MLVC Traditional video codecs (e.g., H.264/AVC, H.265/HEVC) have served the industry for a long time, but each generation requires enormous engineering effort for incremental gains and needs dedicated hardware which takes years to become commonly available. MLVC replaces conventional primitives — motion estimation, transforms, entropy modeling — with end-to-end learned neural compression, trained directly against rate-distortion objectives, and run on general-purpose NPU devices. The table below compares MLVC to popular video codecs, showing its lower bitrate and resulting savings in bandwidth and storage. Resolution vs H.264 vs H.265 360p 87.8% 75.5% 540p 82.7% 65.4% For example, for 360p video at 30 fps, where H.264 requires 1 Mbps, MLVC requires roughly 122 kbps for equivalent quality — about one-eight the bitrate under real-time conditions. The inference compute was kept approximately equal for the 360p and 540p resolutions. These results are based on a P.910 subjective test and are based on the Video Conferencing Dataset (VCD) dataset that we developed and also recently released as an open-source project. The following video demo illustrates the extent of quality enhancement achieved by MLVC relative to H.265/HEVC at the same bitrate of 200kbps (please watch by opening in a new window for better demonstration) \ Beyond video compression efficiency, MLVC also offers: NPU-first design. MLVC is built to run almost entirely on the AI accelerators already shipping in modern devices — Apple Neural Engine, Qualcomm and Intel NPUs — at no more than 50% NPU utilization, leaving NPU headroom for the rest of the system. Real-time execution at the targeted operating points. Demonstrated 540p at 30 fps on Apple, Intel, and Qualcomm hardware. A scaling-law trajectory. Empirically, MLVC's coding efficiency improves with increased model capacity and additional training compute. Content-adaptive behavior out of the box, without hand-tuned Rate Distortion Optimization heuristics. Already running in Microsoft Teams MLVC is more than just a research concept for Microsoft. We are currently rolling it out in Microsoft Teams, where it is being validated on real peer-to-peer video calls with active telemetry and A/B testing. The integration runs alongside fallback to conventional video codecs for hardware or reliability constraints — the kind of mixed-environment deployment that real products need. The scaling and reliability insights from this rollout are shaping the codec and its roadmap. We welcome your contributions We can not cover every use case, every device class, or every content domain by ourselves. That is why we are open sourcing MLVC. If you work on: Streaming, Video On Demand (VOD), or live broadcast Real-time communication and conferencing Cloud gaming or remote rendering Surveillance, drones, or robotics Mobile capture, Augmented Reality (AR) / Virtual Reality (VR), or volumetric video Codec hardware, NPUs, or inference runtimes We would love your help. Contributions of all kinds are welcome, including model improvements, training recipes, new platform ports and conversion targets, runtime backends, domain-specific fine-tunes, evaluation tooling, bug reports, and feedback on what is missing for your scenario. We particularly welcome platform ports that expand NPU coverage and efficiency improvements that push the rate-distortion frontier. What's in the release The MLVC repository is available at https://github.com/microsoft/mlvc and shared under the MIT License. It includes: MLVC model source code of the full network architecture. Trained model weights ready to run. Training scripts used to produce shipping models. Training data collection documentation to help reproduce and improve MLVC. Platform conversion scripts to target different NPUs and runtimes. Issues and pull requests will be open from day one. A follow-up release will add a C++ codec library, simplifying integration into real-world applications. Where we're heading Our long-term goal with MLVC is to create an open, learned video codec that meets or exceeds the coding efficiency of the best conventional codecs across the full range of video content, runs efficiently on the AI hardware already shipping in client and cloud devices, scales with compute the way modern ML systems do, and evolves in the open at the pace of the ML community rather than the pace of standardization cycles. In the near term that means stabilizing 540p real-time performance, expanding hardware coverage, and improving loss resilience. In the medium term: higher resolution, e.g., 1080p, and broader streaming scenarios. In the long term: an open video codec ecosystem that meaningfully replaces legacy stacks where it makes sense to. We can't create the future of MLVC alone. We're glad you're here, and we are looking forward to building the next-generation video codec with you. Who are we MLVC is brought to you by the following awesome folks working on the project at Microsoft: Ross Cutler, Ando Saabas, Tanel Pärnamaa, Ardi Loot, Haiyan Xie, Lauri Ehrenpreis, Andrei Znobishchev, Martin Lumiste, Evgenii Indenbom, Yan Lu, Bin Li, Jiahao Li, Naba Kumar, Babak Naderi, Juhee Cho, Badal Yadav, Jinxin Zhou, Tianyu Ding, Patrick Gregory. — The MLVC Team, Microsoft15KViews0likes4CommentsDesigning for cloud sovereignty with Radius and Dapr
In 2026, cloud sovereignty matters more than ever. It has moved from a policy discussion to an operational and architectural problem. The word “sovereignty” gets used loosely, and it can mean different things to different people. While definitions vary, in this post we define “cloud sovereignty” as the ability for an organization to retain control over where its data and compute run, which jurisdictions govern them, who operates them, and how its applications can adapt as regulatory, commercial, or operational requirements shift. This is especially relevant for developers and platform teams building applications that need to run on hyperscaler infrastructure, such as Azure, as well as in sovereign environments. Those requirements may come from regulation, procurement policies, customer expectations, or internal risk management. In Europe, this pressure is already visible through measures such as the EU Data Act, in force since September 12, 2025, which mandates data portability and interoperability between cloud and edge data processing services. More recently, the European Commission proposed the Cloud and AI Development Act (CADA) as part of its broader European Technological Sovereignty Package. For application teams, the practical takeaway is clear: more organizations need applications that can adapt to changing deployment requirements without requiring a rewrite. Portability is therefore a real engineering concern, not a theoretical one. If requirements change, moving a workload that is deeply integrated with provider-specific APIs can mean rewriting application code, not just reconfiguring infrastructure. Portable applications for sovereign environments The goal is to use the right managed service for each environment while keeping application code portable across environments. Microsoft Sovereign Cloud provides the platform foundation for digital sovereignty across sovereign public cloud, sovereign private cloud, and national partner cloud deployment models. Azure managed services provides strong platform capabilities for regulated workloads. Open source can help, especially when the same technology can be used as a managed service in one environment and self-operated in another. CADA also elevates an explicit "open source first" principle, reflecting how inspectable, portable components can reinforce resilience and reduce strategic dependency. Even with those options, portability is not automatic - applications still need a clear architectural boundary between the capabilities they require and the infrastructure selected for each environment. This boundary is what lets organizations use the right services in each deployment model while keeping workloads adaptable as regulatory, commercial, or operational requirements change. See the diagram below: To address building applications that are cleanly separated from their infrastructure, lets look at Radius, a CNCF project that provides a cloud native application model that addresses the boundary at the deployment layer by letting teams define applications in terms of what they need, while platform teams decide how those needs are met in each environment. For the runtime layer, lets consider Dapr, also a CNCF project which complements Radius by giving application code consistent APIs for common distributed application capabilities. Radius: portability at the deployment layer Radius provides a cloud-native application model. It separates the concerns of what an application needs from how those needs are met in each environment. Resource Types define the interface that developers use to build applications. Radius ships with built-in types and supports user-defined Resource Types for an organization's own abstractions. Recipes implement a Resource Type for a given environment. A Recipe is Infrastructure as Code; a Bicep template or a Terraform configuration that provisions infrastructure and returns the connection details. The same Resource Type can have different Recipes for different environments. Environments bind a set of Recipes against the compute target and credentials for a given deployment context (local Kubernetes, AKS, AKS enabled by Azure Arc, or others). Applications define the full set of resources (containers, Dapr building blocks, databases) and their relationships. At deploy time, Radius resolves each Resource Type to the Recipe registered in the target Environment provisions the infrastructure, and captures the result in an Application Graph that developers and operators can query. Dapr: runtime portability for Radius applications Dapr provides building block APIs for common distributed systems concerns: state management, publish and subscribe messaging, service invocation, workflows, secrets, and more. Dapr runs as a sidecar alongside each service and exposes its APIs over HTTP or gRPC. Application code calls the Dapr API instead of the underlying technology directly, which helps keep runtime dependencies more portable across environments. In a Radius application, Dapr building blocks such as state stores, pub/sub brokers, and secret stores can be declared as application resources. Radius binds those resources to the right infrastructure for each environment, while Dapr exposes them to the application through consistent runtime APIs. A concrete example: order-console The order-console sample, available in the official Radius project labs repo, demonstrates this architectural pattern end to end. It is a three-service order-management application (a Next.js frontend, an orders-api, and a fulfillment-worker) wired through Dapr state management and Dapr pub/sub. The sample ships two Radius environments: A Kubernetes environment that provisions PostgreSQL and Apache Kafka in-cluster. An Azure environment that provisions Azure Database for PostgreSQL Flexible Server and Azure Event Hubs in Kafka mode. The same app.bicep deploys against both environments. Container images, Dapr component names, and application code are identical across both. Only the Recipes change. The Recipes are written in Terraform, which Radius supports as a first-class IaC option alongside Bicep. For a step-by-step walkthrough, including the Bicep application model, the Resource Type definitions, the Terraform Recipes, and deployment instructions, see the order-console walkthrough. Don’t let the app become the lock-in What Radius and Dapr contribute is the application architecture layer: a way to ensure the application itself does not become the reason a workload cannot move to a more sovereign environment when requirements change. Radius Resource Types and Recipes allow platform teams to define governance requirements such as data residency, encryption standards, and audit integration as part of the platform definition. This helps ensure that workloads are deployed consistently and in line with organizational policies, regardless of the target environment. Because these requirements are abstracted from the underlying infrastructure, the same application can be deployed across public cloud, on-premises, and sovereign environments without requiring changes to the application itself. Where a workload runs, and under which controls, becomes a deployment decision rather than a redevelopment project. Learn more To learn more about Radius and Dapr, explore the resources below: Radius documentation Radius Resource Types concept Dapr documentation Expanding platform engineering capabilities with Radius Resource Types1.8KViews1like0CommentsIntroducing kars - an Agent Reference Stack for Kubernetes
kars is an open-source, Kubernetes-native runtime for AI agents on Azure. It treats every agent as untrusted code - per-pod kernel isolation, zero credentials in the agent process, and an end-to-end encrypted inter-agent mesh - and governs agents on any framework with one set of Kubernetes policies via the Microsoft Agent Governance Toolkit. kars dev runs a governed agent on your laptop in minutes.2.2KViews1like2CommentsLog Insights in Minutes: A Simpler pgBadger Workflow
Sometimes the fastest way to understand a PostgreSQL workload is not another dashboard. It is a good log report. pgBadger is a PostgreSQL log analysis tool that turns raw PostgreSQL logs into an interactive HTML report. It helps summarize query activity, connection patterns, errors, temporary files, lock waits, autovacuum activity, and more. Earlier guidance for generating pgBadger reports from Azure Database for PostgreSQL Flexible Server focused on exporting logs through Diagnostic Settings, storing them in a storage account, and then using tools such as BlobFuse and jq to extract PostgreSQL log lines from JSON files. That workflow is still useful when customers centralize logs across multiple servers. However, if you are already using the Server logs feature in Azure Database for PostgreSQL Flexible Server, there is a much simpler path. In this post: You’ll learn how to generate a pgBadger HTML report from Azure Database for PostgreSQL Flexible Server by downloading native PostgreSQL .log files directly from the Azure portal. No storage account, BlobFuse mount, or JSON extraction required. Fast path Configure log_line_prefix . Enable Server logs for download. Download the PostgreSQL .log files. Run pgBadger with the matching prefix. Open pgbadger-report.html . Why use this workflow? With Server logs, you can download native PostgreSQL .log files directly from the Azure portal and run pgBadger locally. Older path Simpler path in this blog Diagnostic Settings → Storage account → BlobFuse → JSON extraction → pgBadger Server logs → Download .log files → pgBadger Area Older Diagnostic Settings workflow Server logs workflow Export path Diagnostic Settings to storage account Download .log files directly from the portal Format JSON payloads need extraction Native PostgreSQL .log files Extra tooling BlobFuse and jq JSON parsing None Best suited for Centralized or multi-server logging Quick per-server analysis Outcome Flexible, but more setup Faster path to pgBadger Recommended: Use the Server logs workflow when you want a fast, low-friction way to generate a pgBadger report from one Azure Database for PostgreSQL Flexible Server. When should you use this workflow? Use this workflow when... Use Diagnostic Settings when... You need a quick report for one Flexible Server. You centralize logs from many servers. You want to run pgBadger locally. You need long-term retention or workspace-level querying. You want to avoid JSON extraction. You already have automated log export pipelines. Before you start A machine where you can install or run pgBadger. A working Perl runtime. Git Bash on Windows, so the multi-line shell commands work as shown. Portal access to your Azure Database for PostgreSQL Flexible Server. Permission to update server parameters and enable Server logs. Important: pgBadger can only analyze what PostgreSQL logs capture. To populate query timing and slow-query sections in the report, enable log_min_duration_statement before collecting logs. Logs collected before that change will not include duration data. Workflow overview Task Type Rough effort Install or prepare pgBadger One-time setup per analysis machine 5–10 minutes Configure log_line_prefix One-time setup per server 2–3 minutes Enable Server logs One-time setup per server 2–3 minutes Download logs and run pgBadger Repeatable 2–5 minutes Install or prepare pgBadger on the machine where you will analyze logs. Configure log_line_prefix so pgBadger can parse each log line. Enable Server logs, so PostgreSQL logs are available for download. Download the logs and run pgBadger locally. 💡Pro tip: Start with a narrow log window first. Use one or two hourly log files, confirm the report looks right, and then expand the analysis window if needed. Step 1: Install pgBadger Before generating a report, you need pgBadger available on the machine where you plan to analyze the downloaded PostgreSQL log files. Run this on a Linux VM, WSL, or another Linux-based environment where you can install packages. Note: Azure Cloud Shell may work for quick testing, but package installation and build-tool availability can vary by session. For repeatable analysis, use a Linux VM, WSL, or another environment you control. Copy and run sudo apt-get update && sudo apt-get install -y git perl make gcc && \ git clone https://github.com/darold/pgbadger.git && \ cd pgbadger && \ perl Makefile.PL && \ make && \ sudo make install && \ pgbadger -V What good looks like: The install command completes successfully and pgbadger -V returns the installed pgBadger version. Step 2: Configure log_line_prefix This is a one-time server configuration step. The log_line_prefix parameter controls the beginning of each PostgreSQL log line. pgBadger uses this prefix to extract useful fields such as timestamp, user, database, and process ID. In the Azure portal, open your Flexible Server and go to Server parameters. Search for: Parameter log_line_prefix Set this value %m user=%u db=%d pid=%p: Then select Save. In Server parameters, confirm that the custom value is saved for log_line_prefix . Figure 1: Set log_line_prefix so pgBadger can correctly parse timestamp, user, database, and process ID from each log line. Prefix tokens Token Meaning %m Timestamp with milliseconds %u Username %d Database name %p Process ID After this change, log lines should look like this: Example log line 2026-06-22 19:00:00.070 UTC user=pgadmin db=highcpu pid=3805603: LOG: statement: SELECT 1 FROM pg_extension WHERE extname='pg_stat_statements' The matching pgBadger prefix for this log format is: Matching pgBadger prefix %m user=%u db=%d pid=%p: You will use this same value later in the pgBadger command. What good looks like: The server parameter is saved, and new PostgreSQL log lines begin with timestamp, user, database, and process ID fields that match the pgBadger prefix. Step 3: Enable Server logs for download This is also a one-time setup step. In the Azure portal, open your Flexible Server and go to Server logs. Enable: Portal setting Capture logs for download Set the retention period based on how long you want logs to remain available for download. For example, a 7-day retention period keeps logs available for download for 7 days. In Server logs, enable Capture logs for download and choose the retention window. Figure 2: Enable Capture logs for download and set a retention period long enough to cover the analysis window you want to inspect. What good looks like: After Server logs are enabled, hourly PostgreSQL log files appear in the Server logs blade and can be downloaded from the Azure portal. Once enabled, hourly log files appear in the Server logs blade. The files are named by date and hour, for example: Example log files postgresql_2026_06_22_19_00_00.log postgresql_2026_06_22_20_00_00.log Step 4: Download and organize the logs locally From the Server logs page, select the .log files for the time window you want to analyze and download them. For example, to analyze activity between 19:00 and 21:00 UTC, download: Example files to download postgresql_2026_06_22_19_00_00.log postgresql_2026_06_22_20_00_00.log On your local machine, create a folder for that analysis window. A simple convention is to use the Mon-DD format. Folder name Jun-22 Place the downloaded .log files inside that folder. Your local folder structure should look like this: Folder structure pgbadger-13.1/ pgbadger Jun-22/ postgresql_2026_06_22_19_00_00.log postgresql_2026_06_22_20_00_00.log Step 5: Generate the pgBadger report Open Git Bash from the folder where pgBadger is located. For example, if pgBadger is inside the pgbadger-13.1 folder, open Git Bash from that folder. # Action Command 1 Set the folder FOLDER=Jun-22 2 Confirm files ls -lh ./$FOLDER 3 Run pgBadger Use the full command below. Copy and run FOLDER=Jun-22 ls -lh ./$FOLDER perl -X ./pgbadger -f stderr \ --prefix '%m user=%u db=%d pid=%p:' \ ./$FOLDER/*.log \ -o ./$FOLDER/pgbadger-report.html Command breakdown Part of command Purpose perl -X ./pgbadger Runs pgBadger and suppresses non-critical Perl warnings. -f stderr Parses PostgreSQL stderr log files. --prefix '%m user=%u db=%d pid=%p:' Matches the log_line_prefix set on the server. ./$FOLDER/*.log Analyzes every .log file in the selected folder. -o ./$FOLDER/pgbadger-report.html Writes the HTML report into the same folder. When the command completes successfully, you should see output like this: Expected output Parsed 12134249 bytes of 12134249 (100.00%), queries: 26684, events: 83 LOG: Ok, generating html report... What good looks like: pgBadger finishes parsing the logs and creates pgbadger-report.html in the selected folder. Step 6: Open the report Open the generated report: Copy and run start ./$FOLDER/pgbadger-report.html The report opens in your default browser. The final report is created here: Generated report path Jun-22/pgbadger-report.html What the report can show The pgBadger report gives you a quick view into the workload shape for the selected log window. For example, in a sample run across two hourly log files, pgBadger summarized: Total number of queries. Number of unique normalized queries. Query traffic over time. Events such as errors and fatal messages. Session and connection patterns. Once the report opens, start with Global Stats to confirm the time range, total queries, normalized queries, and query peak. Figure 3: Start with Global Stats to validate the selected time range, total query count, normalized query count, and query peak. Query volume and normalized queries Many raw queries can often reduce to a smaller number of normalized query patterns. This helps identify whether the workload is spread across many different query shapes or dominated by a smaller set of repeated statements. Example: In this sample run, 26,684 queries reduced to 59 normalized query shapes. That suggests the workload is mostly a small set of repeated statements, which can help focus tuning effort. Traffic patterns The SQL Traffic section helps identify spikes, quiet periods, and workload changes over time. Figure 4: Use SQL Traffic to identify query spikes, quiet periods, and workload changes during the selected log window. Figure 5: Review the query breakdown to compare read vs. write volume and query-type distribution for the selected Server logs window. For example, if the report shows a steady baseline followed by a sharp spike, that spike can be correlated with application activity, batch jobs, synthetic tests, or operational events during the same time window. Query duration If query duration shows 0 ms or the slow query sections are empty, it usually means duration logging was not enabled when the logs were collected. In that case, pgBadger can still show query counts and events, but it cannot calculate the slowest queries, total execution time, average duration, or maximum duration. To unlock those timing sections, enable log_min_duration_statement , collect fresh logs, and rerun pgBadger. What pgBadger cannot infer from missing logs pgBadger reports are only as complete as the log data you provide. If PostgreSQL did not log duration, lock waits, temporary files, or autovacuum activity during the selected time window, pgBadger cannot reconstruct those details later. To analyze... Enable before collecting logs Slow queries log_min_duration_statement Lock waits log_lock_waits Temporary files log_temp_files Autovacuum activity log_autovacuum_min_duration Repeatable copy/paste block Reusable command block Change only FOLDER for each new analysis window. Copy and run FOLDER=Jun-22 ls -lh ./$FOLDER perl -X ./pgbadger -f stderr \ --prefix '%m user=%u db=%d pid=%p:' \ ./$FOLDER/*.log \ -o ./$FOLDER/pgbadger-report.html start ./$FOLDER/pgbadger-report.html For another date, change only this line: Update this value FOLDER=Jun-22 Examples: Example folder values FOLDER=Jun-23 FOLDER=Jul-01 FOLDER=Aug-15 Optional: Improve report quality pgBadger can only analyze the information captured in PostgreSQL logs. The default logs may be enough for query frequency, connection activity, and errors. For deeper performance troubleshooting, consider enabling additional logging parameters based on your scenario. Scenario Parameter Suggested value Notes Slow query analysis log_min_duration_statement 1000 Logs statements slower than 1 second. Short controlled test log_min_duration_statement 0 Logs every statement. Use carefully. Lock troubleshooting log_lock_waits on Helps identify lock waits. Temporary file analysis log_temp_files 0 Logs all temporary files. Autovacuum visibility log_autovacuum_min_duration 0 Useful during focused analysis. Useful parameters include: Recommended logging parameters log_lock_waits = on log_temp_files = 0 log_autovacuum_min_duration = 0 To capture query durations, configure: Duration logging log_min_duration_statement = 1000 This logs statements that run longer than 1000 milliseconds. For short test runs, you can temporarily use: Short test run only log_min_duration_statement = 0 Caution: Use log_min_duration_statement = 0 carefully on busy production servers. It logs every statement and can generate a large volume of logs. Duration matters: If duration logging is not enabled, pgBadger can still show query counts and events, but slowest-query, total duration, average duration, and maximum duration sections will be limited or empty. Common mistakes and quick fixes Symptom Likely cause Fix Report is empty Prefix mismatch Match --prefix with log_line_prefix . No duration data Duration logging was not enabled Set log_min_duration_statement before collecting logs. No files visible Server logs disabled or retention expired Enable capture and check retention. pgBadger command fails pgBadger is not in the current folder or path Run pgbadger -V to confirm installation. Common troubleshooting FAQs 1. Report is created but empty This usually means the pgBadger prefix did not match the actual log format. Check the first few lines: Copy and run head -5 ./$FOLDER/*.log Make sure the pgBadger --prefix matches the server’s log_line_prefix . 2. Report shows queries but no duration PostgreSQL logged statements but did not log durations. Enable one of the following, collect fresh logs, and rerun pgBadger: Parameter options log_min_duration_statement = 1000 # or temporarily for testing log_min_duration_statement = 0 3. No .log files are visible Confirm that Server logs are enabled: Portal setting Capture logs for download Also check the retention period. If the retention period has expired, older logs may no longer be available for download. 4. pgBadger command fails Confirm that pgBadger is available in the current folder or installed in your path. Copy and run pgbadger -V If you are running pgBadger from the local folder, use: Copy and run perl -X ./pgbadger Summary For customers already using Azure Database for PostgreSQL Flexible Server logs, the pgBadger workflow is straightforward: Install pgBadger. Configure log_line_prefix . Enable Server logs for download. Download the .log files. Place them in a local date-based folder. Run pgBadger with the matching prefix. Open pgbadger-report.html . Bottom line: Server logs give you the shortest path from Azure Database for PostgreSQL Flexible Server logs to a pgBadger report. Download the native .log files, run pgBadger with the matching prefix, and open the generated HTML report. References pgBadger - source and documentation GitHub pgBadger - project site Azure - Download server logs from the portal Flexible Server Azure - Logging concepts Flexible Server Azure - Configure server parameters via the portal PostgreSQL - log_line_prefix and logging parameters493Views2likes0CommentsLessons Learned #542: Reviewing Historical Azure SQL Database Storage Growth
This week I worked on a service request where our customer needed to understand how an Azure SQL Database had grown over time. This information can be useful for capacity planning, cost analysis, and performance reviews. There are several possible approaches, depending on whether we need to review recent historical data that is still available in Azure Monitor, or whether we need to start collecting long-term historical data from now on. In this lesson learned, I would like to summarize some of the options available. 1. Reviewing recent historical data using Azure Monitor metrics The first point to clarify is how Azure Monitor metrics retention works. Most Azure platform metrics are retained for up to 93 days. However, a single Azure Monitor Metrics chart can query no more than 30 days of data at a time. This means that, if the data is still within the Azure Monitor retention window, we might need to review the metric in 30-day intervals. For Azure SQL Database storage usage, the metric commonly used is Data space used 2. Exporting metrics to Log Analytics for long-term analysis If the requirement is to perform long-term analysis, I would like to recommended option is to enable Diagnostic Settings on the Azure SQL Database and send the metrics to a Log Analytics workspace. Azure SQL Database diagnostic telemetry can be exported to different destinations, including: Log Analytics workspace Storage Account Event Hubs Using Log Analytics provides a very flexible way to query, aggregate, and visualize the data by using KQL. Once the metrics are available in Log Analytics, we can calculate the monthly database growth. For example: AzureMetrics | where ResourceProvider =~ "MICROSOFT.SQL" | where ResourceId == "/SUBSCRIPTIONS/your subscription/RESOURCEGROUPS/yourresourcegroup/PROVIDERS/MICROSOFT.SQL/SERVERS/yourserver/DATABASES/yourdatabase" | where MetricName == "storage" | summarize arg_max(TimeGenerated, Average) by Month = startofmonth(TimeGenerated) | project Month, DataSpaceUsedGB = round(Average / 1024 / 1024 / 1024, 2) | order by Month asc This query takes the last available value for each month and converts the metric from bytes to GB. Depending on the analysis requirements, the query can be customized. 3. Creating a custom database space usage history process If we need more control, or if we want to collect more granular database-level information, another option is to create a custom process that periodically captures the current database space usage into a table. This approach can be useful when we want to keep the information inside the database itself and avoid depending on external telemetry storage for this specific requirement. For example, the following table can be used to store daily or weekly snapshots: CREATE TABLE dbo.DatabaseSpaceUsageHistory ( SnapshotTimeUtc datetime2(3) NOT NULL DEFAULT SYSUTCDATETIME(), DatabaseName sysname NOT NULL, DataAllocatedMB decimal(19,2) NULL, DataUsedMB decimal(19,2) NULL, DataUnusedMB decimal(19,2) NULL, LogAllocatedMB decimal(19,2) NULL ); --Example collection query: INSERT INTO dbo.DatabaseSpaceUsageHistory ( DatabaseName, DataAllocatedMB, DataUsedMB, DataUnusedMB, LogAllocatedMB ) SELECT DB_NAME() AS DatabaseName, SUM(CASE WHEN type_desc = 'ROWS' THEN size END) * 8.0 / 1024 AS DataAllocatedMB, SUM(CASE WHEN type_desc = 'ROWS' THEN FILEPROPERTY(name, 'SpaceUsed') END) * 8.0 / 1024 AS DataUsedMB, ( SUM(CASE WHEN type_desc = 'ROWS' THEN size END) - SUM(CASE WHEN type_desc = 'ROWS' THEN FILEPROPERTY(name, 'SpaceUsed') END) ) * 8.0 / 1024 AS DataUnusedMB, SUM(CASE WHEN type_desc = 'LOG' THEN size END) * 8.0 / 1024 AS LogAllocatedMB FROM sys.database_files; This process can be executed daily, weekly, or monthly using the automation method that best fits the environment. This approach provides more control over the data collected, the retention period, and the frequency of collection.103Views0likes0CommentsFour open source projects to explore at Microsoft Build
Open source is where developers experiment, collaborate, and turn new ideas into tools that others can build on. At Microsoft Build, we’re creating a dedicated space for that energy: the Open Source Zone. This year, the Open Source Zone will bring together maintainers, contributors, and developers working on some of the most interesting open source projects in AI. Whether you’re building agents, experimenting with local models, exploring prompt workflows, or looking for practical ways to bring AI into your development process, this is a place to meet the people behind the projects and see what they’re building. The Open Source Zone is inspired by similar community spaces we’ve hosted at GitHub Universe: hands-on, conversation-driven, and centered on the people and projects moving open source forward. Meet the projects OpenClaw OpenClaw, originally Clawbot, formerly Clawdbot and briefly Moltbot,before landing on its current name (because naming is hard), is a personal AI assistant project built for developers who want more control over how AI agents run across tools, devices, and workflows. Its repository describes it as “your own personal AI assistant” across operating systems and platforms, with support for agent workspaces, skills, and device nodes. It has also become one of the fastest-growing open source projects on GitHub, with over 370,000 stars to date. At the Open Source Zone, attendees can learn how OpenClaw approaches personal agents, extensibility, and local-first experimentation. AutoGPT AutoGPT is one of the best-known open source projects in the autonomous agent space. The project’s mission is to make AI accessible for everyone to use and build on, with tools for building, testing, and delegating work to agents. Visit AutoGPT in the Open Source Zone to learn how the project is evolving agent development, benchmarking, frontend experiences, and practical workflows for building agent-powered applications. Come for the autonomous agents; stay for the very human maintainers. AutoGPT is also a member of GitHub’s Secure Open Source Fund, with a goal of enhancing AI security across the open source ecosystem. Open WebUI Open WebUI is a self-hosted, extensible AI platform for working with large language models. The project supports Ollama and OpenAI-compatible APIs and includes built-in RAG capabilities, making it a strong option for developers and organizations exploring local, private, or provider-flexible AI experiences. At Build, the Open WebUI team will show how developers can run, customize, and extend AI interfaces for their own environments. prompts.chat prompts.chat, formerly Awesome ChatGPT Prompts, is a curated collection of prompt examples for AI chat models. The project is designed to help people discover, share, and build better prompts for modern AI assistants. Created by Fatih Kadir Akın, a GitHub Star from Istanbul, prompts.chat reflects his work at the intersection of open source, developer education, and AI-assisted development. Fatih leads Developer Relations at Teknasyon, has authored books on JavaScript and prompt engineering, and is active in the community as a speaker, organizer, and contributor. Stop by to explore prompt libraries, prompt engineering resources, self-hosting options, and ways the community is making prompting more reusable and collaborative. Register for Microsoft Build Microsoft Build takes place June 2–3, 2026, in San Francisco and online. In-person passes are available, and online registration is free for livestreamed keynote and select session access. Register for Microsoft Build and come visit the Open Source Zone to meet the teams behind OpenClaw, AutoGPT, Open WebUI, and prompts.chat. We’ll see you there. <3809Views0likes0CommentsGoverning AI Agents Against Every OWASP Agentic Risk: A Deep Dive with the Agent Governance Toolkit
AI agents are moving from prototypes to production. They book flights, write code, negotiate contracts, and operate across enterprise systems with minimal human oversight. The attack surface is not theoretical: OWASP has catalogued the top 10 risks specific to agentic applications, and every one of them maps to a real-world failure mode. The Agent Governance Toolkit (AGT) is an open-source, MIT-licensed framework that enforces deterministic governance at runtime, before every tool call, message, and action an agent takes. This is not prompt engineering or guardrails bolted on after the fact. AGT provides policy-as-code enforcement, zero-trust identity, execution isolation, and tamper-evident audit trails across the full agent lifecycle. In this post, we walk through all 10 OWASP Agentic risks with real code from the AGT repository. By the end, you will have concrete examples for every risk category and a clear path to production-grade agent governance. Coverage at a Glance # OWASP Risk AGT Component Key Mechanism ASI-01 Agent Goal Hijack Agent OS Policy Engine + Action Interception ASI-02 Tool Misuse & Exploitation Agent OS Capability Sandboxing + Input Sanitization ASI-03 Identity & Privilege Abuse AgentMesh DID Identity + Trust Scoring ASI-04 Supply Chain Vulnerabilities AgentMesh AI-BOM (Model + Data + Weights Provenance) ASI-05 Unexpected Code Execution Agent Runtime Execution Rings (Ring 0-3) ASI-06 Memory & Context Poisoning Agent OS VFS Policies + CMVK Verification ASI-07 Insecure Inter-Agent Comms AgentMesh IATP + E2E Encrypted Channels ASI-08 Cascading Agent Failures Agent SRE Circuit Breakers + SLOs ASI-09 Human-Agent Trust Exploitation Agent OS Approval Workflows + Quorum Logic ASI-10 Rogue Agents Agent Runtime Kill Switch + Ring Isolation + Merkle Audit ASI-01: Agent Goal Hijack The risk: Attackers manipulate the agent's objectives via indirect prompt injection or poisoned inputs. The agent believes it is following its original instructions, but it has been redirected. AGT mitigates this through the Agent OS policy engine. Every agent action passes through a declarative policy evaluation layer before execution. The policy engine supports three modes: strict (deny by default), permissive (allow by default), and audit (log only). Unauthorized goal changes are blocked at the action layer, not at the prompt layer. from agent_os import StatelessKernel, ExecutionContext kernel = StatelessKernel() ctx = ExecutionContext(agent_id="my-agent", policies=["read_only"]) # This action is blocked by policy -- goal hijack prevented result = await kernel.execute( action="delete_database", params={"target": "production"}, context=ctx, ) # result.success = False, result.error = "Policy violation: read_only" The MCP Governance Proxy extends this to Model Context Protocol tool calls, evaluating policy before any tool invocation reaches the agent runtime. ASI-02: Tool Misuse & Exploitation The risk: An agent's authorized tools are abused in unintended ways, such as exfiltrating data via read operations or chaining benign tools into dangerous workflows. AGT provides capability-based security inspired by POSIX. Agents receive explicit capability grants (read, write, execute, network), not blanket tool access. The built-in strict mode blocks dangerous tools like run_shell, execute_command, and eval. Tool inputs are sanitized for command injection patterns and shell metacharacters. The verify_code_safety MCP tool checks generated code before execution, and tool allowlists/denylists give operators fine-grained control over which tools each agent can invoke. ASI-03: Identity & Privilege Abuse The risk: Agents escalate privileges by abusing identities or inheriting excessive credentials. Without proper identity, agents operate as ambient authority, and any compromise cascades. AgentMesh implements zero-trust identity using Decentralized Identifiers (DIDs). Every agent gets a cryptographic identity: did:agentmesh:{agentId}:{fingerprint} backed by Ed25519 key pairs. Trust is earned through a tiered model: Untrusted, Provisional, Trusted, Verified. Trust decays over time without positive signals, and delegation chains must always narrow scope (child capabilities must be a subset of parent capabilities). from agentmesh import AgentIdentity identity = AgentIdentity.create( name="data-analyst", sponsor="admin@contoso.com", capabilities=["read:data"], # Scoped -- cannot write or delete ) # Delegation MUST narrow, never widen child = identity.delegate( name="chart-helper", capabilities=["read:data:charts"], # Subset of parent ) ASI-04: Agentic Supply Chain Vulnerabilities The risk: Vulnerabilities in third-party tools, plugins, agent registries, or runtime dependencies that agents use to act, plan, or delegate. AgentMesh implements the AI-BOM (AI Bill of Materials), a comprehensive standard for tracking the full AI supply chain. This includes model provenance (base model ancestry, fine-tuning history, training cutoff dates), dataset tracking (training data, RAG sources, evaluation benchmarks with data cards including PII status, bias assessment, and consent tracking), weights versioning (SHA-256 hashes, quantization records, LoRA adapter metadata, SLSA build provenance), and software dependencies (SPDX-aligned package tracking with CI security scanning). # AI-BOM tracks the full supply chain ai_bom = { "modelProvenance": { "primary": {"provider": "anthropic", "model": "claude-3-sonnet"}, "fineTuning": {"method": "LoRA", "evaluationMetrics": {"accuracy": 0.94}}, }, "datasets": [ {"name": "FAQ KB", "type": "fine-tuning", "dataCard": {"piiStatus": "redacted"}}, {"name": "Product Docs", "type": "rag-source", "updateFrequency": "weekly"}, ], "weights": {"hash": "sha256:...", "format": "safetensors", "precision": "bf16"}, } ASI-05: Unexpected Code Execution The risk: Agents trigger remote code execution through tools, interpreters, or APIs. Without isolation, a single compromised tool call can escalate to full system access. Agent Runtime implements CPU ring-inspired execution isolation. Agents run in one of four execution rings: Ring 0 (root/supervisor), Ring 1 (privileged), Ring 2 (standard), and Ring 3 (sandbox/untrusted). Each ring has resource limits and the kill switch provides instant termination of runaway agents. from hypervisor.models import ( ActionDescriptor, ExecutionRing, ReversibilityLevel, ) from hypervisor.rings.enforcer import RingEnforcer from hypervisor.security.kill_switch import KillSwitch, KillReason # Define agent privilege levels AGENTS = { "supervisor": {"ring": ExecutionRing.RING_0_ROOT, "role": "Orchestrator"}, "data-agent": {"ring": ExecutionRing.RING_1_PRIVILEGED, "role": "Data Engineer"}, "analyst": {"ring": ExecutionRing.RING_2_STANDARD, "role": "Analyst"}, "user-bot": {"ring": ExecutionRing.RING_3_SANDBOX, "role": "User-Facing"}, } # Create a sandboxed action descriptor action = ActionDescriptor( name="run_query", required_ring=ExecutionRing.RING_2_STANDARD, reversibility=ReversibilityLevel.REVERSIBLE, ) # Enforce: sandbox agent cannot run a Ring 2 action enforcer = RingEnforcer() result = enforcer.check(agent_ring=ExecutionRing.RING_3_SANDBOX, action=action) # result.allowed = False -- ring violation prevented # Kill switch for runaway agents kill_switch = KillSwitch() kill_switch.terminate(agent_id="user-bot", reason=KillReason.RING_BREACH) ASI-06: Memory & Context Poisoning The risk: Persistent memory or long-running context is poisoned with malicious instructions. An attacker embeds hostile content in a document the agent later retrieves, causing it to follow injected goals. Agent OS provides a policy-controlled virtual filesystem (VFS) for agent memory. The VFS uses POSIX-style mount points: /mem/working for current context, /mem/episodic for past interactions, /mem/semantic for knowledge, /policy for read-only policy files, and /tools for tool interfaces. Each mount point has enforced permissions (read, write, execute, append). The policy directory is always read-only from user-space, preventing agents from modifying their own governance rules. from agent_control_plane.vfs import AgentVFS, MemoryBackend, FileMode # Create agent VFS with POSIX-style memory abstraction vfs = AgentVFS(agent_id="data-analyst") # Mount memory backends with explicit permissions vfs.mount("/mem/working", MemoryBackend(), mode=FileMode.READ | FileMode.WRITE) vfs.mount("/mem/semantic", MemoryBackend(), mode=FileMode.READ) # Read-only knowledge vfs.mount("/policy", MemoryBackend(), mode=FileMode.READ) # Policies always read-only # Agent can read working memory data = vfs.read("/mem/working/context.json") # Agent CANNOT write to policy -- enforced at VFS layer # vfs.write("/policy/rules.yaml", content) # Raises PermissionError # Agent CANNOT read semantic memory if not mounted # vfs.read("/mem/procedural/skills") # Raises FileNotFoundError The CMVK (Cross-Model Verification Kernel) adds a second layer: claims from agent context are verified across multiple AI models to detect poisoned content. Prompt injection patterns like 'ignore previous instructions' and 'disregard prior' are detected and blocked by the MCP proxy sanitizer before reaching the agent. ASI-07: Insecure Inter-Agent Communication The risk: Agents collaborate without adequate authentication, confidentiality, or validation. Messages between agents can be intercepted, forged, or replayed. AgentMesh provides IATP (Inter-Agent Trust Protocol) with E2E encrypted channels using the Signal protocol (X3DH key agreement + Double Ratchet). Every message gets per-message forward secrecy and post-compromise security. The EncryptedTrustBridge requires a successful trust handshake before any encrypted channel can be established, and mutual authentication via Ed25519 challenge-response ensures both parties prove identity at connection time. from agentmesh.encryption.bridge import EncryptedTrustBridge bridge = EncryptedTrustBridge(agent_did="did:mesh:alice", key_manager=keys) channel = await bridge.open_secure_channel("did:mesh:bob", bob_bundle) ciphertext = channel.send(b"governed action") # E2E encrypted ASI-08: Cascading Agent Failures The risk: An initial error or compromise triggers multi-step compound failures across chained agents. One agent's failure propagates through the entire system. Agent SRE brings production-grade reliability engineering to agent fleets. Circuit breakers automatically isolate failing agents before failures cascade. SLO enforcement with error budgets provides quantified failure tolerance that triggers automatic intervention. Cascading failure detection monitors dependency chains for propagation patterns, and canary deploys enable gradual rollout of agent changes to detect issues early. OpenTelemetry integration provides distributed tracing across multi-agent workflows. The key insight: treat AI agents like microservices. Apply the same SRE discipline (SLOs, error budgets, circuit breakers, chaos testing) that keeps cloud infrastructure reliable. ASI-09: Human-Agent Trust Exploitation The risk: Attackers leverage misplaced user trust in agents' autonomy to authorize dangerous actions. Users rubber-stamp agent requests because they trust the agent, and attackers exploit this approval fatigue. Agent OS implements approval workflows that require explicit human confirmation for high-risk actions. The system supports configurable risk assessment (critical, high, medium, low), quorum logic for critical actions requiring multiple approvals, and expiration tracking to prevent stale authorizations. The escalation handler includes fatigue detection: if an agent floods reviewers with escalation requests, subsequent requests are auto-denied to prevent the approval-fatigue attack. from agent_os.integrations.escalation import ( EscalationHandler, InMemoryApprovalQueue, DefaultTimeoutAction, QuorumConfig, ) # Configure approval workflow with fatigue protection handler = EscalationHandler( backend=InMemoryApprovalQueue(), timeout_seconds=300, # 5-minute approval window default_action=DefaultTimeoutAction.DENY, # Deny if no human responds quorum=QuorumConfig(required=2, total=3), # 2-of-3 approvers for critical fatigue_threshold=5, # Auto-deny after 5 rapid requests fatigue_window_seconds=60, # Within a 60-second window ) # Three-outcome model: allow, deny, or escalate # High-risk actions trigger escalation to human reviewers # If the agent triggers too many escalations, fatigue detection kicks in ASI-10: Rogue Agents The risk: Agents operating outside their defined scope through configuration drift, reprogramming, or emergent misbehavior. A rogue agent might gradually expand its actions beyond its mandate without any single action triggering a block. AGT combines runtime behavioral monitoring with instant kill capability. Ring isolation confines rogue agents to their execution ring, preventing privilege escalation. The kill switch provides immediate termination for agents exhibiting rogue behavior (behavioral drift, rate limit violations, ring breaches). Trust score decay tracks agent behavior over time, and the Merkle audit chain provides tamper-evident, cryptographic proof of every agent action. from agentmesh.governance.audit import AuditEntry, MerkleAuditChain from hypervisor.security.kill_switch import KillSwitch, KillReason # Tamper-evident audit trail chain = MerkleAuditChain() entry = AuditEntry( event_type="tool_call", agent_did="did:agentmesh:data-bot:abc123", action="query_database", outcome="allowed", policy_decision="permit", matched_rule="read_only_policy", ) chain.add_entry(entry) # Auto-computes hash chain # Verify integrity -- any tampering breaks the chain proof = chain.get_proof(entry.entry_id) assert chain.verify_proof(proof) # Cryptographic verification # Kill switch for rogue behavior kill = KillSwitch() kill.terminate( agent_id="data-bot", reason=KillReason.BEHAVIORAL_DRIFT, # Also: RATE_LIMIT, RING_BREACH, MANUAL ) Cross-Cutting Principle: Least Agency The Least Agency principle is emphasized throughout the OWASP Agentic Top 10 as a foundational design principle. Agents should be granted the minimum capabilities, permissions, and autonomy necessary to complete their assigned tasks. Layer Least Agency Mechanism Agent OS Policy engine enforces deny-by-default; agents must be explicitly granted each capability AgentMesh DID identity with scoped capabilities; delegation requires narrowing (child <= parent) Agent Runtime Execution rings (Ring 0-3) enforce privilege tiers; untrusted agents run in Ring 3 Agent SRE Resource limits and error budgets cap agent impact radius Performance: Governance Without Latency Tax A common concern with runtime governance is performance overhead. AGT's benchmarks demonstrate that policy enforcement adds negligible latency: Metric Value Single rule evaluation 84,000 ops/sec 1000 concurrent agents 47,000 ops/sec Policy evaluation latency <0.1ms (p99) Prompt-based violation rate 26.67% AGT policy violation rate 0.00% Conformance tests 992 Architecture Decision Records 25 The key takeaway: deterministic policy enforcement is orders of magnitude more reliable than prompt-based guardrails, and it runs fast enough for real-time agent workloads. Framework Integrations AGT is framework-agnostic. SDKs are available in Python, TypeScript, .NET, Rust, and Go. Native integrations exist for: LangChain and LangGraph CrewAI AutoGen (Microsoft) Semantic Kernel (Microsoft) OpenAI Agents SDK PydanticAI Model Context Protocol (MCP) Agent-to-Agent Protocol (A2A) Each integration wraps the agent framework's tool-calling and message-passing interfaces with AGT's policy engine, trust scoring, and audit logging. Adding governance to an existing agent takes minutes, not weeks. Compliance Framework Alignment Framework AGT Coverage OWASP Agentic Top 10 (2026) All 10 risk categories mapped NIST AI RMF Govern, Map, Measure, Manage functions addressed EU AI Act Risk classification, audit trails, human oversight SOC 2 Type II Audit logging, access controls, change management CSA ATF Zero-trust agent architecture alignment Singapore MGF Zero-trust, accountability, oversight layers Getting Started # Install the complete governance stack pip install agent-governance-toolkit[full] # Or install individual components pip install agent-os-kernel # Policy engine, VFS, approval workflows pip install agentmesh-platform # Identity, trust, encryption, audit pip install agentmesh-runtime # Execution rings, kill switch, saga pip install agent-sre # Circuit breakers, SLOs, chaos testing The quickstart tutorial walks through adding policy enforcement to an existing LangChain agent in under 10 minutes. Start with a single policy rule and expand as your governance requirements grow. Contribute and Collaborate AGT is open source under the MIT license. The project has over 2,000 GitHub stars and contributors from 40+ countries. Whether you are building agent governance for your enterprise, integrating a new framework, or extending the policy engine with OPA/Rego or Cedar policies, we welcome contributions. Repository: https://github.com/microsoft/agent-governance-toolkit Documentation: https://microsoft.github.io/agent-governance-toolkit Discussions: GitHub Discussions on the repository Disclaimer: This document is provided for informational purposes. Code examples are from the public AGT repository and may evolve. Always refer to the latest repository documentation for current APIs.809Views0likes0Comments