Por que Approval Workflows são Essenciais
Segurança
Previne que remediação automática cause impacto maior que o problema original (ex: rollback acidental em produção)
Compliance
Cada requisição, decisão e expiração fica registrada no CR
ApprovalRequest e como AuditEvent.Confiança
Equipes adotam AIOps mais facilmente quando sabem que ações críticas requerem aprovação humana.
Visão Geral do Fluxo
O operator não envia notificação quando um ApprovalRequest é criado. As NotificationPolicies são disparadas por mudanças de estado do Issue, não por requisições de aprovação. Acompanhe com
kubectl get approvalrequests -A, pelo dashboard web, ou crie alertas com as métricas abaixo para saber que há uma requisição esperando.ApprovalPolicy CRD
AApprovalPolicy (short name ap) define regras que decidem quais planos de remediação precisam de aprovação e como essa aprovação é obtida. Ela só vale para planos do próprio namespace: o operator lista as ApprovalPolicies habilitadas no namespace do RemediationPlan (o namespace do Issue), nunca entre namespaces.
Campos do Spec
ApprovalRule
Cada regra define um par match + mode com configurações específicas.ApprovalMatch
Define quais remediações são cobertas por esta regra. A lógica é AND entre campos e OR dentro de cada campo. Campo vazio casa com tudo, então uma regra commatch vazio casa com qualquer plano.
Não existe combinação do tipo “a regra mais restritiva prevalece”. Dentro de uma policy vale a primeira regra que casar e as demais são ignoradas, então coloque as regras mais rígidas primeiro. Se houver várias ApprovalPolicies habilitadas no mesmo namespace, a ordem em que elas são avaliadas não é garantida; mantenha uma policy por namespace, ou faça os matches não se sobreporem.
Três Modos de Aprovação
- auto
- manual
- quorum
Auto: uma regra A confiança vem do AIInsight do Issue; um AIInsight ausente conta como confiança
auto sem autoApproveConditions que casa significa “este plano não precisa de aprovação desta policy”. Nenhum ApprovalRequest é criado e o plano segue (o tier do cluster e o decision engine, quando habilitados, ainda o avaliam).Como vale a primeira regra que casar, uma regra auto também encobre todas as regras abaixo dela para os planos que ela casa.Com autoApproveConditions, a regra para o plano num ApprovalRequest, e o controller de aprovação o aprova automaticamente (status.autoApproved: true, decisão de auto-policy) só quando todas as condições valem. Caso contrário, a requisição espera uma decisão humana como numa regra manual, e continua expirando pelo timeoutMinutes:0, então as condições não são atendidas e um humano decide.ChangeWindowSpec
A change window é definida por regra (rules[].changeWindow), não no nível da policy. Ela só afeta as requisições geradas por aquela regra.
Não existem datas de blackout nem exceção para severidade crítica.
A janela controla quando uma aprovação tem efeito, venha a decisão de onde vier (annotation, API REST ou dashboard):
- Decisões são registradas a qualquer hora, e uma rejeição tem efeito na hora.
- O relógio do timeout só corre com a janela aberta, então uma requisição aberta de madrugada guarda o
timeoutMinutesinteiro para quando os aprovadores puderem agir. - Uma requisição que já tem as aprovações necessárias e só espera a janela não expira. Ela recebe a condition
ChangeWindow=False(reasonOutsideChangeWindow) e viraApprovedquando a janela abre (reverificado a cada minuto); aprovações dentro da janela gravamChangeWindow=True(WithinChangeWindow).
ApprovalRequest CRD
OApprovalRequest (short name ar) é criado pelo RemediationReconciler quando um plano precisa esperar. O nome é sempre approval-<nome-do-plano>, ele fica no namespace do plano e pertence ao RemediationPlan (apagar o plano apaga a requisição).
Campos do Spec
Raiz
BlastRadiusAssessment
ApprovalEvidence
Status
Estados do ApprovalRequest
Uma única rejeição basta para bloquear o plano, independentemente do número de aprovações. Um plano rejeitado ou expirado conta como tentativa de remediação falha: o Issue volta para
Analyzing para gerar um novo plano enquanto houver tentativas (o que pode abrir um novo ApprovalRequest) e passa a Escalated ao atingir o máximo. Apagar o ApprovalRequest antes da decisão também faz o plano falhar; nunca o libera para rodar.Blast Radius Calculator
Rodam dois cálculos, ambos informativos: nenhum deles bloqueia um plano sozinho.Como Funciona
1
Avaliação gravada no spec (na criação da requisição)
Para um alvo
Deployment, o calculador conta os pods que casam com o selector do Deployment (usando spec.replicas se nenhum for encontrado) e os Services do namespace cujo selector casa com as labels do pod template. Para outros kinds, ele conta os pods do namespace que têm owner reference com o nome do alvo e informa 0 services.2
Nível de risco pela contagem de pods
3
Ajuste pelo tipo de ação
Uma ação
RollbackDeployment sobe low para medium. Uma ação Custom sobe low ou medium para high. Os demais tipos não mudam o nível. Ingresses e downtime estimado não são calculados.4
Annotations de predição (controller de aprovação)
Enquanto a requisição está
Pending, o controller de aprovação roda o preditor de blast radius sobre a primeira ação do plano (checagens de PodDisruptionBudget, ResourceQuota, capacidade dos nodes e Services afetados) e grava o resultado em duas annotations do ApprovalRequest: platform.chatcli.io/blast-radius (resumo em texto) e platform.chatcli.io/blast-risk-level. Isso acontece uma vez por requisição. A API REST devolve as annotations da requisição, então o card de aprovação do dashboard mostra o nível de risco como um badge.Integração com RemediationReconciler
Fluxo Completo
Quando um RemediationPlan estáPending, o RemediationReconciler passa por três gates, nesta ordem. O primeiro que parar o plano vence; os seguintes não rodam.
O gate falha fechado. Se o Issue, o AIInsight ou as ApprovalPolicies não puderem ser lidos, ou o decision engine devolver erro, o plano continua Pending, um Event de Warning ApprovalGateUnavailable é registrado nele e o reconcile é tentado de novo com backoff; o plano nunca roda porque um gate deu erro. Se a criação do ApprovalRequest ou a anotação do plano falhar, o plano também continua Pending e é tentado de novo. Um ApprovalRequest que já existe com o mesmo nome é reaproveitado, não ignorado.
Um plano cujo Issue pai não existe mais falha (“Parent issue not found; approval policies cannot be evaluated without it”) em vez de rodar sem gate. Um AIInsight ausente não é erro: a evidência leva confiança 0, o que só deixa as condições de auto-aprovação e o decision engine mais rígidos. O gate de tier do cluster segue a mesma regra: uma falha ao listar as ClusterRegistrations mantém o plano Pending e tenta de novo, e um CHATCLI_OPERATOR_CLUSTER_NAME que não casa com nenhuma ClusterRegistration retém o plano para aprovação manual sob a política cluster-tier, com o motivo Cluster name "<name>" (CHATCLI_OPERATOR_CLUSTER_NAME) is not registered: .... Com a variável vazia o gate de tier não se aplica.
Requisições sem ApprovalPolicy
O tier do cluster e o decision engine podem parar um plano mesmo sem nenhuma ApprovalPolicy. As requisições deles têm umpolicyRef sintético (cluster-tier ou decision-engine) e seguem sempre a mesma regra embutida: modo manual, um aprovador, timeout de 30 minutos, sem change window. Elas são aprovadas ou rejeitadas exatamente como qualquer outra requisição.
O decision engine também deixa o veredito no plano como annotations:
platform.chatcli.io/decision-mode, platform.chatcli.io/confidence, platform.chatcli.io/risk e platform.chatcli.io/decision-reason. Os limiares estão na página do Decision Engine.
Annotation de Controle
Quando um plano é parado, o reconciler gravaplatform.chatcli.io/approval-pending no RemediationPlan com o nome do ApprovalRequest:
WaitingApproval do plano mais o status do ApprovalRequest, que o reconciler sempre lê diretamente, então apagar a annotation não pula a aprovação. Na aprovação ou rejeição o controller de aprovação a remove; na rejeição ele também grava platform.chatcli.io/rejection-reason no plano.
Uma requisição cuja ApprovalPolicy (ou regra) foi apagada nesse meio-tempo continua sendo avaliada, com o próprio requiredApprovers e timeoutMinutes, sem change window e sem aprovação automática: ela ainda precisa de um humano e ainda expira.
Como Aprovar
Via kubectl
A forma recomendada de decidir é uma annotation no ApprovalRequest:status.decisions, depois remove a annotation (a decisão é gravada primeiro, então nunca se perde) e avalia a regra: quorum, change window, timeout. Uma segunda decisão do mesmo aprovador é ignorada. Num quorum, cada aprovador adiciona a annotation depois que a anterior foi consumida; se duas pessoas anotarem antes de o controller rodar, a segunda precisa de --overwrite e substitui a primeira.
O
<aprovador> é o texto que for escrito: o operator não o confere com a identidade do usuário do Kubernetes. Restrinja update/patch em approvalrequests via RBAC às pessoas que podem aprovar.Via REST API
A API REST do operator (porta8090) expõe as requisições. A autenticação é pelo header X-API-Key; listar exige o papel viewer, aprovar/rejeitar exige operator. Passe ?namespace= para escolher o namespace; sem ele a requisição é procurada pelo nome em todos os namespaces.
Pending, exatamente como uma annotation: uma entrada em status.decisions com o aprovador, o motivo e um timestamp. Ela nunca define o estado por conta própria; o ApprovalReconciler avalia as decisões contra a regra (requiredApprovers, change window) e leva a requisição a Approved ou Rejected, então a resposta costuma ainda mostrar Pending e a nova entrada em decisions.
approveré obrigatório no corpo (400quando vazio). O aprovador registrado é<nome digitado> (api-key: <identidade>), onde a identidade é onameda entrada da API key, senão odescription, senão uma impressão digitalkey-<hash>(dev-modeno dev mode). Veja Autenticação Fail-Closed.- Um quorum conta API keys distintas: duas chamadas com a mesma chave contam uma vez, sejam quais forem os nomes digitados. Dê a cada aprovador a sua própria chave.
409quando a requisição não está maisPending, ou quando a mesma chave já decidiu sobre ela.404quando a requisição não existe.
resource é o nome do Issue, action é a primeira ação solicitada e reason é o nome da policy. approvedBy, rejectedBy e decisionReason são derivados de decisions, e decidedAt é preenchido quando a requisição termina.
O dashboard web usa os mesmos endpoints: ele pede o seu nome (lembrado no navegador) e mostra o progresso do quorum nas requisições que precisam de mais de um aprovador.
Via Slack
Não existe aprovação interativa pelo Slack. O operator não tem endpoint de callback do Slack e não publica requisições de aprovação em nenhum canal.Exemplos YAML Completos
Sem Aprovação para Ações de Baixo Risco em Staging
Quorum de 2 Aprovadores para Produção
Change Window Dias Úteis 9-18 UTC
Proteção de Rollback em Namespace Crítico
payments, auth, billing, …).
Auditoria e Compliance
As decisões feitas por annotation ficam registradas no status doApprovalRequest:
kubectl get ar são Issue, Plan, State, Rule, Age.
O RemediationReconciler também grava CRs AuditEvent do ciclo de vida: approval_requested quando um plano é parado, e approval_approved, approval_rejected ou approval_expired quando ele age sobre o resultado (correlationId = nome do Issue). Uma aprovação ou rejeição humana registra como actor do evento os aprovadores de status.decisions (actor.type: user, mais um detalhe approvers); uma auto-aprovação ou uma expiração é atribuída ao ApprovalReconciler. Veja Auditoria e Compliance.
Os ApprovalRequests pertencem ao seu RemediationPlan e são apagados junto com ele, então exporte-os periodicamente se precisar de registros de longo prazo:
totalApproved, totalRejected, totalExpired e totalAutoApproved (não mantidos para requisições sintéticas). Cada requisição finalizada é contada uma vez (a requisição é marcada com platform.chatcli.io/policy-counted), inclusive entre restarts do operator.
Métricas Prometheus
O sistema de aprovação expõe estas métricas no endpoint de métricas do operator (porta8080):
Não existe gauge de requisições pendentes; conte-as com
kubectl get ar -A ou pela API REST (?state=Pending).
Alertas Prometheus recomendados:
Próximo Passo
Notificações e Escalação
Sistema de notificações multi-canal e políticas de escalação
SLOs e SLAs
Gestão de Service Level Objectives com burn rate alerting
AIOps Platform
Deep-dive na arquitetura AIOps completa
K8s Operator
Configuração e CRDs do operator