Em ambientes de producao, nem toda remediação automática deve ser executada sem supervisao humana. O sistema de Approval Workflow do ChatCLI permite definir politicas granulares que controlam quais ações requerem aprovação, quem pode aprovar, e em quais janelas de mudanca (change windows) as ações são permitidas.
Por que Approval Workflows são Essenciais
Seguranca Previne que remediação automática cause impacto maior que o problema original (ex: rollback acidental em producao)
Compliance Auditoria completa de quem aprovou, quando, e por que. Requisito para SOC2, PCI-DSS, HIPAA.
Confianca Equipes adotam AIOps mais facilmente quando sabem que ações criticas requerem aprovação humana.
Sem approval workflows, uma IA que detecta um falso positivo pode executar um rollback desnecessario, afetando um deployment saudavel. Com approval policies, ações de alto impacto são bloqueadas até que um humano valide a análise e o blast radius.
Visao Geral do Fluxo
ApprovalPolicy CRD
O ApprovalPolicy define regras que determinam quais ações de remediação precisam de aprovação, em quais condicoes, e quem pode aprovar.
apiVersion : platform.chatcli.io/v1alpha1
kind : ApprovalPolicy
metadata :
name : production-approval-policy
namespace : production
spec :
rules :
- name : auto-approve-low-risk
match :
severities : [ low , medium ]
actionTypes : [ RestartDeployment , ScaleDeployment ]
namespaces : [ staging , development ]
mode : auto
autoApproveConditions :
minConfidence : 0.85
maxSeverity : medium
historicalSuccessRate : 0.90
- name : manual-approve-rollback
match :
actionTypes : [ RollbackDeployment ]
namespaces : [ production , payments ]
mode : manual
requiredApprovers : 1
timeoutMinutes : 30
- name : quorum-critical-production
match :
severities : [ critical , high ]
namespaces : [ production ]
resourceKinds : [ Deployment , StatefulSet ]
mode : quorum
requiredApprovers : 2
timeoutMinutes : 15
- name : block-critical-namespace-rollback
match :
actionTypes : [ RollbackDeployment ]
namespaces : [ payments , auth ]
severities : [ critical ]
mode : manual
requiredApprovers : 2
timeoutMinutes : 10
changeWindow :
timezone : "America/Sao_Paulo"
allowedDays : [ 1 , 2 , 3 , 4 , 5 ] # Segunda a Sexta
startHour : 9
endHour : 18
overrideForCritical : true # Critical ignora change window
blackoutDates :
- date : "2026-03-20"
reason : "Congelamento pre-release Q1"
- date : "2026-12-24"
reason : "Vespera de Natal"
- date : "2026-12-31"
reason : "Vespera de Ano Novo"
Campos do Spec
ApprovalRule
Cada regra define um par match + mode com configurações especificas.
Campo Tipo Obrigatório Descrição namestring Sim Nome único da regra dentro da policy matchApprovalMatch Sim Criterios de matching modestring Sim auto, manual, quorumrequiredApproversint Para manual/quorum Número mínimo de aprovadores timeoutMinutesint Não Timeout em minutos (padrão: 60) autoApproveConditionsAutoApproveConditions Para auto Condicoes para auto-aprovação
ApprovalMatch
Define quais remediações são cobertas por está regra. A logica e AND entre campos e OR dentro de cada campo.
Campo Tipo Descrição severities[]string critical, high, medium, lowactionTypes[]string ScaleDeployment, RestartDeployment, RollbackDeployment, PatchConfig, AdjustResources, DeletePod, Customnamespaces[]string Namespaces K8s afetados resourceKinds[]string Deployment, StatefulSet, DaemonSet
Quando multiplas regras fazem match, a regra mais restritiva prevalece. A ordem de prioridade e: manual > quorum > auto. Se uma regra exige quorum com 2 aprovadores e outra exige manual com 1, o sistema aplica quorum com 2.
Tres Modos de Aprovação
Auto-approve : O sistema aprova automaticamente se todas as condicoes de autoApproveConditions forem atendidas. Caso contrario, escala para manual.Condição Tipo Descrição minConfidencefloat64 Confianca minima da análise de IA (0.0-1.0) maxSeveritystring Severidade máxima para auto-approve historicalSuccessRatefloat64 Taxa minima de sucesso histórico para este tipo de ação
mode : auto
autoApproveConditions :
minConfidence : 0.90 # IA tem >= 90% de confianca
maxSeverity : medium # Até severidade medium
historicalSuccessRate : 0.85 # >= 85% de sucesso em ações similares
Logica de avaliacao: auto_approve = (
ai_confidence >= minConfidence AND
severity <= maxSeverity AND
historical_success_rate >= historicalSuccessRate
)
Se auto_approve = false -> escala para modo manual (1 approver)
Manual : Requer aprovação explicita de pelo menos requiredApprovers humanos. O RemediationPlan fica pausado até a aprovação ou timeout.mode : manual
requiredApprovers : 1
timeoutMinutes : 30
Quorum : Requer aprovação de requiredApprovers pessoas. Garante que a aprovação não depende de um único individuo.mode : quorum
requiredApprovers : 2
timeoutMinutes : 15
Neste exemplo, são necessarios pelo menos 2 aprovadores para que a ação seja executada.
ChangeWindowSpec
Define janelas de mudanca (change windows) que controlam quando remediação automática pode ser executada.
Campo Tipo Obrigatório Descrição timezonestring Sim Timezone IANA (ex: America/Sao_Paulo) allowedDays[]int Sim Dias permitidos (0=Domingo, 6=Sabado) startHourint Sim Hora de início da janela (0-23) endHourint Sim Hora de fim da janela (0-23) overrideForCriticalbool Não Se true, severidade critical ignora a change window blackoutDates[]BlackoutDate Não Datas especificas com congelamento total
Quando fora da change window, ações de remediação ficam enfileiradas (não descartadas). Elas serão executadas automaticamente quando a proxima janela abrir — desde que o Issue ainda esteja ativo e o approval não tenha expirado.
ApprovalRequest CRD
O ApprovalRequest e criado automaticamente pelo RemediationReconciler quando uma ação requer aprovação. Contem todas as informações necessarias para o aprovador tomar uma decisao informada.
apiVersion : platform.chatcli.io/v1alpha1
kind : ApprovalRequest
metadata :
name : approve-api-gateway-rollback-1234
namespace : production
labels :
platform.chatcli.io/issue : api-gateway-oom-kill-1771276354
platform.chatcli.io/action-type : RollbackDeployment
platform.chatcli.io/severity : critical
spec :
issueRef :
name : api-gateway-oom-kill-1771276354
remediationPlanRef :
name : api-gateway-oom-kill-plan-1
requestedAction :
type : RollbackDeployment
params :
toRevision : "previous"
policyRef :
name : production-approval-policy
rule : manual-approve-rollback
requiredApprovers : 1
timeoutMinutes : 30
blastRadius :
affectedPods : 5
affectedServices :
- name : api-gateway
namespace : production
endpoints : 3
- name : api-gateway-internal
namespace : production
endpoints : 2
affectedIngresses :
- name : api-gateway-ingress
namespace : production
riskLevel : high
estimatedDowntime : "30s"
rollbackAvailable : true
evidence :
aiConfidence : 0.87
analysis : "High restart count caused by OOMKilled. Container memory limit (512Mi) insufficient."
historicalSuccessRate : 0.92
similarIncidents : 3
lastSimilarResolution : "RollbackDeployment to revision 5 (2 days ago, success)"
status :
state : Pending # Pending | Approved | Rejected | Expired
decisions : []
createdAt : "2026-03-19T14:30:00Z"
expiresAt : "2026-03-19T15:00:00Z"
Campos do Spec
Raiz
Campo Tipo Obrigatório Descrição issueRefObjectRef Sim Referência ao Issue que originou o request remediationPlanRefObjectRef Sim Referência ao RemediationPlan pausado requestedActionActionSpec Sim Ação que requer aprovação policyRefPolicyRef Sim Referência a policy e regra que disparou requiredApproversint Sim Número mínimo de aprovadores timeoutMinutesint Sim Tempo até expirar blastRadiusBlastRadiusAssessment Sim Avaliacao de impacto evidenceApprovalEvidence Sim Evidencias para tomada de decisao
BlastRadiusAssessment
Campo Tipo Descrição affectedPodsint Número de pods que serão afetados pela ação affectedServices[]ServiceRef Services que roteiam para os pods afetados affectedIngresses[]IngressRef Ingresses que expoe os services afetados riskLevelstring critical, high, medium, low (calculado)estimatedDowntimestring Estimativa de downtime durante a ação rollbackAvailablebool Se a ação pode ser revertida
ApprovalEvidence
Campo Tipo Descrição aiConfidencefloat64 Nível de confianca da análise da IA (0.0-1.0) analysisstring Resumo da análise da IA historicalSuccessRatefloat64 Taxa de sucesso de ações similares no histórico similarIncidentsint Número de incidentes similares no passado lastSimilarResolutionstring Descrição da ultima resolucao similar
ApprovalDecision
Cada aprovação ou rejeicao e registrada como uma decision no status:
Campo Tipo Descrição approverstring Identificador do aprovador (usuario ou sistema) decisionstring approved ou rejectedreasonstring Justificativa para a decisao timestampTime Quando a decisao foi feita
Estados do ApprovalRequest
Uma única rejeicao e suficiente para bloquear a acao, independente do número de aprovações. Isso garante que qualquer membro da equipe pode vetar uma ação de risco.
Blast Radius Calculator
O blast radius calculator avalia o impacto potencial de uma ação de remediação antes de solicitar aprovação.
Como Funciona
Consulta pods do deployment
O calculator lista todos os pods gerenciados pelo deployment alvo usando label selectors. pods = kubectl get pods -l app=api-gateway -n production
affectedPods = len(pods) // ex: 5
Encontra services que roteiam para os pods
Para cada Service no namespace, verifica se o selector faz match com as labels dos pods do deployment. for service in namespace.services:
if service.selector matches pod.labels:
affectedServices.append(service)
Encontra ingresses que expoe os services
Para cada Ingress no namespace, verifica se referência algum dos services afetados. for ingress in namespace.ingresses:
for rule in ingress.rules:
if rule.backend.service in affectedServices:
affectedIngresses.append(ingress)
Calcula risk level
O risk level e determinado pelo número de pods afetados: if affectedPods > 10: riskLevel = "critical"
if affectedPods > 5: riskLevel = "high"
if affectedPods > 2: riskLevel = "medium"
else: riskLevel = "low"
Estima downtime
Com base no tipo de acao: Ação Downtime Estimado ScaleDeployment (up)0s (nenhum pod removido) RestartDeployment~30s (rolling update) RollbackDeployment~30-60s (rolling update) AdjustResources~30s (rolling update) DeletePod~10s (recreacao pelo ReplicaSet) PatchConfig0s (sem restart)
Fluxo Completo
Annotation de Controle
O RemediationReconciler usa a annotation platform.chatcli.io/approval-pending para controlar o fluxo:
metadata :
annotations :
platform.chatcli.io/approval-pending : "approve-api-gateway-rollback-1234"
Quando está annotation está presente:
O reconciler não executa nenhuma ação
Consulta o status do ApprovalRequest referenciado
Remove a annotation apenas quando o request e Approved
Se Rejected ou Expired, marca o plan como Failed
Como Aprovar
Via kubectl
A maneira mais direta de aprovar e usando annotations:
# Aprovar
kubectl annotate approvalrequest approve-api-gateway-rollback-1234 \
-n production \
platform.chatcli.io/approve="edilson:LGTM, blast radius aceitavel"
# Rejeitar
kubectl annotate approvalrequest approve-api-gateway-rollback-1234 \
-n production \
platform.chatcli.io/reject="edilson:Risk too high, investigate memory leak first"
Formato da annotation:
platform.chatcli.io/approve="<usuario>:<motivo>"
platform.chatcli.io/reject="<usuario>:<motivo>"
O reconciler do ApprovalRequest detecta a annotation, registra a decision no status, e remove a annotation.
Via REST API
O operator expoe uma API REST para integrações:
Aprovar
Rejeitar
Listar pendentes
Detalhes
curl -X POST \
http://localhost:8090/api/v1/approvals/approve-api-gateway-rollback-1234/approve \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $TOKEN " \
-d '{
"approver": "edilson",
"reason": "LGTM, blast radius aceitavel. AI confidence 87% com histórico de sucesso."
}'
Resposta da API (exemplo):
{
"name" : "approve-api-gateway-rollback-1234" ,
"namespace" : "production" ,
"state" : "Approved" ,
"requestedAction" : {
"type" : "RollbackDeployment" ,
"params" : { "toRevision" : "previous" }
},
"blastRadius" : {
"affectedPods" : 5 ,
"riskLevel" : "high"
},
"decisions" : [
{
"approver" : "edilson" ,
"decision" : "approved" ,
"reason" : "LGTM, blast radius aceitavel" ,
"timestamp" : "2026-03-19T14:35:00Z"
}
]
}
Via Slack (interativo)
Quando integrado com o canal Slack via NotificationPolicy, o ApprovalRequest inclui botoes interativos no Block Kit:
Approve : Registra aprovação com o usuário Slack como aprovador
Reject : Abre dialog para motivo de rejeicao
Details : Expande blast radius e evidencias da IA
A integração Slack interativa requer configuração adicional de um Slack App com Interactive Components habilitado e endpoint de callback apontando para o operator.
Exemplos YAML Completos
Auto-approve para Low Severity + High Confidence
apiVersion : platform.chatcli.io/v1alpha1
kind : ApprovalPolicy
metadata :
name : staging-auto-approve
namespace : staging
spec :
rules :
- name : auto-approve-all-staging
match :
severities : [ low , medium ]
actionTypes :
- RestartDeployment
- ScaleDeployment
- AdjustResources
- DeletePod
namespaces : [ staging ]
mode : auto
autoApproveConditions :
minConfidence : 0.80
maxSeverity : medium
historicalSuccessRate : 0.75
- name : manual-for-rollback-staging
match :
actionTypes : [ RollbackDeployment ]
namespaces : [ staging ]
mode : manual
requiredApprovers : 1
timeoutMinutes : 60
changeWindow :
timezone : "America/Sao_Paulo"
allowedDays : [ 0 , 1 , 2 , 3 , 4 , 5 , 6 ] # Todos os dias
startHour : 0
endHour : 23
Quorum de 2 Approvers para Producao
apiVersion : platform.chatcli.io/v1alpha1
kind : ApprovalPolicy
metadata :
name : production-strict
namespace : production
spec :
rules :
- name : quorum-all-production-actions
match :
severities : [ critical , high , medium ]
namespaces : [ production ]
mode : quorum
requiredApprovers : 2
timeoutMinutes : 15
- name : auto-low-severity-restart
match :
severities : [ low ]
actionTypes : [ RestartDeployment ]
namespaces : [ production ]
mode : auto
autoApproveConditions :
minConfidence : 0.95
maxSeverity : low
historicalSuccessRate : 0.98
changeWindow :
timezone : "America/Sao_Paulo"
allowedDays : [ 1 , 2 , 3 , 4 , 5 ]
startHour : 9
endHour : 18
overrideForCritical : true
Change Window Weekdays 9-18 UTC
apiVersion : platform.chatcli.io/v1alpha1
kind : ApprovalPolicy
metadata :
name : change-window-policy
namespace : production
spec :
rules :
- name : all-actions-require-approval
match :
namespaces : [ production ]
mode : manual
requiredApprovers : 1
timeoutMinutes : 120
changeWindow :
timezone : "UTC"
allowedDays : [ 1 , 2 , 3 , 4 , 5 ] # Monday to Friday
startHour : 9
endHour : 18
overrideForCritical : true
blackoutDates :
- date : "2026-03-27"
reason : "End of Q1 freeze"
- date : "2026-03-28"
reason : "End of Q1 freeze"
- date : "2026-06-30"
reason : "End of Q2 freeze"
Use overrideForCritical: true para permitir que incidentes critical sejam remediados fora da change window. Sem isso, um incidente critico as 3h da manha ficara enfileirado até as 9h.
Bloqueio de RollbackDeployment em Namespaces Criticos
apiVersion : platform.chatcli.io/v1alpha1
kind : ApprovalPolicy
metadata :
name : critical-namespace-protection
namespace : payments
spec :
rules :
- name : block-rollback-payments
match :
actionTypes : [ RollbackDeployment ]
namespaces : [ payments , auth , billing ]
mode : quorum
requiredApprovers : 2
timeoutMinutes : 10
- name : block-delete-pod-payments
match :
actionTypes : [ DeletePod ]
namespaces : [ payments ]
mode : manual
requiredApprovers : 1
timeoutMinutes : 15
- name : auto-scale-only
match :
actionTypes : [ ScaleDeployment ]
namespaces : [ payments ]
mode : auto
autoApproveConditions :
minConfidence : 0.90
maxSeverity : high
historicalSuccessRate : 0.95
changeWindow :
timezone : "America/Sao_Paulo"
allowedDays : [ 1 , 2 , 3 , 4 ] # Seg-Qui (sem sexta para freeze pre-fim-de-semana)
startHour : 10
endHour : 16
overrideForCritical : true
blackoutDates :
- date : "2026-03-31"
reason : "Fechamento mensal"
- date : "2026-04-30"
reason : "Fechamento mensal"
Auditoria e Compliance
Todas as decisoes de aprovação são registradas no status do ApprovalRequest CR, criando um trail de auditoria completo:
# Ver histórico de aprovações
kubectl get approvalrequests -n production \
-o custom-columns=NAME:.metadata.name,STATE:.status.state,APPROVER:.status.decisions[0].approver,REASON:.status.decisions[0].reason,TIME:.status.decisions[0].timestamp
# Output:
# NAME STATE APPROVER REASON TIME
# approve-api-gw-rollback-1234 Approved edilson LGTM 2026-03-19T14:35:00Z
# approve-worker-scale-5678 Approved system Auto-approved 2026-03-19T15:00:00Z
# approve-payment-restart-9012 Rejected maria Risk too high 2026-03-19T15:30:00Z
# approve-auth-rollback-3456 Expired - Timeout (15min) 2026-03-19T16:00:00Z
Para compliance SOC2 e PCI-DSS, exporte os ApprovalRequests periodicamente:
kubectl get approvalrequests -A -o json | jq '.items[] | {
name: .metadata.name,
namespace: .metadata.namespace,
action: .spec.requestedAction.type,
state: .status.state,
decisions: .status.decisions,
blastRadius: .spec.blastRadius.riskLevel,
created: .status.createdAt
}' > approval-audit- $( date +%Y%m%d ) .json
Prometheus Metrics
O sistema de approval workflow expoe metricas para monitoramento:
Metrica Tipo Labels Descrição chatcli_approvals_totalCounter policy, rule, namespace, decisionTotal de aprovações por decision (approved/rejected/expired/auto) chatcli_approval_duration_secondsHistogram policy, rule, decisionTempo entre criacao do request e decisao chatcli_approvals_pendingGauge policy, namespaceNúmero de ApprovalRequests pendentes chatcli_approval_auto_approved_totalCounter policy, rule, namespaceTotal de auto-aprovações chatcli_approval_auto_escalated_totalCounter policy, rule, namespaceAuto-approve que escalou para manual chatcli_approval_blast_radius_podsHistogram namespace, action_typeDistribuicao de pods afetados nos requests chatcli_change_window_blocked_totalCounter policy, namespaceAções bloqueadas por change window
Alertas Prometheus recomendados:
groups :
- name : chatcli-approvals
rules :
- alert : ApprovalRequestPendingTooLong
expr : chatcli_approvals_pending > 0 and time() - chatcli_approval_created_timestamp > 600
for : 1m
labels :
severity : warning
annotations :
summary : "ApprovalRequest pendente ha mais de 10 minutos"
description : "{{ $labels.policy }}/{{ $labels.namespace }} tem requests aguardando aprovação"
- alert : HighRejectionRate
expr : rate(chatcli_approvals_total{decision="rejected"}[1h]) / rate(chatcli_approvals_total[1h]) > 0.3
for : 30m
labels :
severity : warning
annotations :
summary : "Taxa de rejeicao de aprovações acima de 30%"
description : "Pode indicar falsos positivos na análise de IA ou politica muito permissiva"
- alert : ApprovalTimeoutRate
expr : rate(chatcli_approvals_total{decision="expired"}[1h]) > 0.1
for : 1h
labels :
severity : warning
annotations :
summary : "Aprovações expirando por timeout"
description : "Equipes podem não estar recebendo notificações ou timeouts estão curtos demais"
Próximo Passo
Notificações e Escalacao Sistema de notificações multi-canal e politicas de escalacao
SLOs e SLAs Gestao de Service Level Objectives com burn rate alerting
AIOps Platform Deep-dive na arquitetura AIOps completa
K8s Operator Configuração e CRDs do operator