Atualizar de versão
Subir de uma versão para a mais recente (ex.: 2.3.0 → 2.3.1) é, na mecânica, uma
operação de rotina: você troca a tag da imagem, puxa a nova imagem e recria os
serviços. Não há reinstalação, não há passo manual de migração, e os dados são
preservados. Esta página cobre a mecânica genérica (vale para qualquer versão) e traz,
no fim, as Notas da versão com o que muda em cada release.
A 2.3.0 tem um defeito que pode pendurar o primeiro boot numa instalação que já tem dados: a API fica presa na migração de schema, sem erro no log, e nunca fica saudável. Quem está na 2.2.0 deve pular a 2.3.0 e ir direto para a 2.3.1. Se você já tentou a 2.3.0 e ficou nesse estado, o caminho de saída está em A atualização ficou pendurada na migração. Detalhes em Notas da versão → 2.3.1.
Quem já está numa 2.x pode pular este aviso. A 2.0.0 subiu o número maior de propósito: ela remove a superfície de Alertas
(rota /alerts, endpoints de alerts da API, o Accept v1 de /dashboard/summary e a
ferramenta MCP list_integration_alerts). Os dados e o schema são preservados — o que
muda é o contrato de leitura. Se você tem bookmarks, automações ou integrações que
batem nesses caminhos, migre-as antes de atualizar (detalhes em
Notas da versão → 2.0.0). A ingestão de alertas Sophos/Wazuh não muda.
Esta página trata de subir de versão (ex.: 2.3.0 → 2.3.1), dentro da mesma
edição. Para trocar de edição — Community → Enterprise, ativando os módulos MSSP com
a sua licença — veja Upgrade para Enterprise. Os dois
processos são independentes: você atualiza a versão de uma stack Community ou Enterprise
exatamente da mesma forma.
Antes de começar
- Faça backup do banco. Um
pg_dumprápido antes de qualquer upgrade (docker compose -f compose/docker-compose.yml exec postgres pg_dump -U centralops centralops > backup.sql). - Leia as Notas da versão de destino — em especial as mudanças que quebram compatibilidade (breaking changes).
- Fixe uma tag imutável (com
sha) em produção, para saber exatamente o que está rodando e para um rollback confiável.
Como as versões são identificadas
As imagens de cada release recebem duas tags — uma móvel (acompanha a versão) e uma imutável (nunca muda de conteúdo). Em produção, fixe a imutável.
| Edição | Tag de release (móvel) | Tag imutável (fixe em produção) | Tag extra |
|---|---|---|---|
| Community | vX.Y.Z — ex.: v2.0.0 | sha-<shortsha> — ex.: sha-a1b2c3d | — |
| Enterprise | vX.Y.Z-ee — ex.: v2.0.0-ee | vX.Y.Z-ee.<sha> — ex.: v2.0.0-ee.9f8e7d6 | core-<coresha> |
- A tag de release é ótima para acompanhar a versão, mas pode ser re-publicada — ruim para reprodutibilidade.
- A tag imutável (com
<sha>) é a mesma imagem para sempre — use-a em produção e guarde a tag da versão anterior para o rollback. - Na Community, a imutável é a
sha-<shortsha>(ex.:sha-a1b2c3d). Se preferir não fixar por commit, acompanhe a tag de release móvelvX.Y.Zou mantenha uma tag estável própria (ex.:production). - As imagens Enterprise são privadas no GHCR e exigem
docker logincom a credencial de pull da sua assinatura — ver Upgrade para Enterprise.
Docker Compose
Community
Em compose/.env, aponte para a nova tag:
IMAGE_NAME=ghcr.io/segark-oficial/centralops
IMAGE_TAG=sha-a1b2c3d # a tag imutável da nova versão
Puxe as imagens e recrie os serviços (a partir da raiz do repositório):
docker compose -f compose/docker-compose.yml pull
docker compose -f compose/docker-compose.yml up -d
Não há build local — as imagens já vêm prontas do registry.
Enterprise
Numa stack Enterprise, troque as duas imagens EE em compose/.env:
CENTRALOPS_EE_IMAGE=ghcr.io/segark-oficial/centralops-ee:v2.0.0-ee.9f8e7d6
CENTRALOPS_WEB_EE_IMAGE=ghcr.io/segark-oficial/centralops-ee-frontend:v2.0.0-ee.9f8e7d6
E recrie sempre com os dois arquivos (-f base + -f overlay EE):
docker compose -f compose/docker-compose.yml -f compose/docker-compose.ee.yml pull
docker compose -f compose/docker-compose.yml -f compose/docker-compose.ee.yml up -d
Um up -d/pull só com o arquivo base rebaixa a stack para Community
silenciosamente (a imagem volta a ser a CE e o mount do keyring da licença some). Se
ainda não fez, torne a overlay permanente com
COMPOSE_FILE=docker-compose.yml:docker-compose.ee.yml no compose/.env. A mecânica
completa está em Upgrade para Enterprise.
Kubernetes (Helm)
Faça um helm upgrade trocando só a tag da imagem.
Community:
helm upgrade centralops kubernetes/helm/centralops -n centralops \
--set image.tag=sha-a1b2c3d \
--set frontendImage.tag=sha-a1b2c3d \
--reuse-values
Enterprise — mantenha também os repositórios EE:
helm upgrade centralops kubernetes/helm/centralops -n centralops \
--set image.repository=ghcr.io/segark-oficial/centralops-ee \
--set image.tag=v2.0.0-ee.9f8e7d6 \
--set frontendImage.repository=ghcr.io/segark-oficial/centralops-ee-frontend \
--set frontendImage.tag=v2.0.0-ee.9f8e7d6 \
--reuse-values
O Helm faz um rollout gradual — a API, o frontend e os workers são Deployments separados. Acompanhe:
kubectl -n centralops rollout status deploy/centralops-api
Prefira editar image.tag/frontendImage.tag no seu values.override.yaml e rodar
helm upgrade centralops kubernetes/helm/centralops -n centralops -f values.override.yaml
— assim o estado desejado fica no Git, em vez de --set na linha de comando. Os -set
exatos para uma stack Enterprise estão em
Upgrade para Enterprise.
O que acontece com os dados
No primeiro boot da nova versão, a API roda uma migração/seed leve e idempotente — não há passo manual de Alembic neste release. Os dados são preservados:
- As definições de mapping existentes (que já têm uma versão ativa) não são sobrescritas.
- Só definições vazias ganham uma
v1— é assim que os novos defaults de um release aparecem (ver Notas da versão). - Rodar a migração de novo (num restart) não muda nada — ela é idempotente.
Como o seed é aditivo e não-destrutivo, o rollback para a versão anterior é seguro (ver abaixo). Se, logo após o upgrade, a plataforma parecer indisponível por um instante enquanto os serviços sobem, aguarde alguns segundos — a nova versão leva um curto período para ficar totalmente pronta. Persistindo, veja o runbook A plataforma não está respondendo?.
Verifique
-
Edição e boot — o log de boot mostra a edição resolvida (e confirma que a API subiu na versão nova):
docker compose -f compose/docker-compose.yml logs centralops | grep edition=# edition=community (ou "edition=enterprise plan=... features=..." numa stack EE) -
Saúde geral — abra Roteia → Fluxo de dados (
/flow) e Visão geral → Saúde do pipeline (/pipeline-health) e confirme que os eventos continuam fluindo normalmente.
O /readyz só reporta prontidão (db/redis) — não a edição nem a versão. O
endpoint /api/edition existe, mas exige autenticação. Para a edição, use o log de
boot (edition=) ou a tela Configurações → Licença.
Rollback
Como este release não tem migração destrutiva, voltar é seguro:
- Compose: re-aponte a tag imutável anterior no
compose/.enve rodepull+up -d(com os dois-fnuma stack Enterprise). - Helm:
helm rollback centralops(volta à revisão anterior) ouhelm upgrade ... --set image.tag=<tag-anterior>.
Os dados gravados pela versão nova continuam legíveis pela anterior — as mudanças de schema são aditivas.
Notas da versão
Cada versão adiciona uma seção aqui. Leia a da sua versão de destino antes de atualizar.
2.3.1
Versão de correção. Ela conserta um defeito da 2.3.0 que podia deixar a atualização pendurada. Não há nada de novo para configurar: tudo que a 2.3.0 trouxe (leia a seção abaixo) continua valendo, com o boot funcionando.
Quem está na 2.2.0: atualize direto para a 2.3.1. Não passe pela 2.3.0.
Quem já tentou a 2.3.0 e ficou pendurado: siga A atualização ficou pendurada na migração para destravar o banco e, em seguida, atualize para a 2.3.1.
Numa instalação que já tinha dados, o primeiro boot da 2.3.0 podia parar no passo de migração de schema e nunca sair de lá. O que você via:
- o container da API de pé, mas nunca saudável —
running,exit=0,health=unhealthy. Ele não reiniciava em laço: o processo não morria, ficava travado. (No Kubernetes o pod nunca ficavaReadye acabava reiniciado pelostartupProbe— e o pod novo travava igual.); - o log parado na linha
start-api: migração de schema (python -m app.db.migrate)...— e nenhuma linha de erro depois; - os serviços de coleta no mesmo estado, porque rodam a mesma migração no boot;
- consultas normais à tabela de integrações também travadas, enquanto o impasse durasse.
Instalação nova não era afetada. O travamento dependia de existir uma coluna nova a acrescentar numa tabela que já existia com dados — numa stack criada do zero, o schema nasce inteiro e o passo problemático nem roda. Foi por isso que o defeito passou pelos testes: eles sobem um banco limpo.
Nada a desfazer no banco, e nenhum passo manual de schema. Neste travamento a migração ainda não tinha aplicado nada quando pendurou — isso foi verificado: o impasse acontece antes do primeiro commit, e a 2.3.0 não cria tabela nova. O banco fica exatamente como estava. É por isso que a mecânica normal de rollback — voltar à tag imutável da 2.2.0 — restabelece o serviço sem nenhum ajuste de banco; mas o destino é a 2.3.1, não a 2.2.0.
E se um upgrade for interrompido em outro ponto? Também não sobra schema pela metade, por um motivo diferente: a migração não é uma transação única — são cerca de vinte passos independentes, cada um com o seu próprio commit. Interromper no meio deixa os passos já concluídos aplicados, mas todos são idempotentes: o estado que sobra é parcial e válido, e o boot seguinte completa o que faltou sozinho. Em nenhum dos casos há algo para consertar à mão no banco.
O que mudou no código: a migração conferia quais colunas uma tabela já tinha abrindo uma segunda conexão com o banco no meio da própria transação — e essa segunda conexão ficava esperando a liberação de uma tabela que a primeira, da mesma migração, mantinha bloqueada. A verificação passou a usar a conexão da própria transação. O passo continua idempotente.
A migração também ganhou um teto de espera por bloqueio (15 s por padrão). Se outra sessão do banco estiver segurando uma tabela que a migração precisa alterar, o boot agora falha com erro explícito em vez de pendurar em silêncio. É um sintoma novo, e melhor — o procedimento está em A migração abortou com "lock timeout".
2.3.0
Versão menor: nenhuma mudança que quebre compatibilidade. Atualizar é a mecânica de rotina descrita acima, e uma instalação que não abrir as telas novas se comporta exatamente como na 2.2.0.
Filtro de coleta — nasce desligado. As integrações cujo fornecedor permite restringir a consulta ganharam um filtro de coleta: o descarte passa a acontecer na consulta feita ao fornecedor, em vez de depois de coletar e normalizar. Hoje o Wazuh (detecções) é a integração que o oferece, com um nível mínimo de regra.
Nenhuma instalação muda de comportamento ao atualizar. O filtro nasce no valor que não corta nada, e a consulta enviada ao fornecedor é idêntica à da versão anterior enquanto ninguém abrir a tela. Não há nada a configurar e nada a reverter.
Ele existe para um caso concreto: quando o roteamento descarta a maior parte do que entra, o coletor está gastando cada ciclo transportando ruído — e é essa a causa de coletas que não alcançam o presente. Veja Filtro de coleta antes de ligar: o que é filtrado na origem nunca entra na plataforma (não aparece na captura ao vivo, não gera campo novo no Drift, não fica disponível para uma rota futura), e ligar ou desligar não é retroativo.
Ciclos concorrentes do mesmo fluxo agora são pulados. Quando um ciclo de coleta demora
mais que o intervalo agendado, o ciclo seguinte daquele mesmo (integração, fluxo) é
pulado em vez de rodar em paralelo. Se você monitora os workers, vai ver um ciclo
onde antes via dois ou três simultâneos.
Os ciclos simultâneos liam a mesma posição de coleta e buscavam os mesmos eventos — em produção, ciclos concorrentes chegaram a terminar com 34 ms de diferença sobre o mesmo lote. Só um avançava a posição; o resto era trabalho jogado fora que ainda pressionava a fonte e deixava cada ciclo mais lento. Coletar deixou de ser feito em duplicata; a quantidade de evento coletado por hora não cai.
O contador collector_cycles_skipped_locked_total mostra quantos ciclos foram pulados.
Subindo de forma sustentada, ele indica que o ciclo passou a durar mais que o intervalo
agendado — ou seja, há acúmulo. Veja
Eventos chegando horas depois.
Saúde do Pipeline: atraso dos dados. O card de cada integração passa a mostrar, além do atraso desde a última coleta, o Atraso dos dados — de quando é o evento mais recente que a coleta já trouxe. São perguntas diferentes: o primeiro responde "a coleta está rodando?", o segundo responde "o que eu estou vendo é de agora?".
O indicador antigo media apenas o tempo desde a última coleta bem-sucedida — e esse número
zera a cada ciclo que termina sem erro, mesmo quando o ciclo processou eventos de ontem.
Um coletor que estava 15 horas atrás reportava atraso 0 s e status Saudável.
Ao atualizar, esse ponto cego se fecha. Um card que ficar amarelo (ou passar a exibir horas no Atraso dos dados) logo após o upgrade quase certamente já estava atrasado antes — a atualização não criou o atraso, tornou-o visível. Trate como diagnóstico, não como regressão, e siga Eventos chegando horas depois.
O card só fica amarelo por backlog quando as duas condições valem ao mesmo tempo: o último ciclo terminou no teto de eventos e o Atraso dos dados daquele fluxo passa de 30 minutos. Atraso dos dados alto sozinho não muda a cor — um fluxo sem eventos mantém a posição parada de propósito. Detalhes em Saúde do Pipeline.
2.2.0
Detecção em voo (correlação no hot path). Regras de correlação passam a poder ser avaliadas durante a ingestão, e não só ao fim de uma busca federada. A tela ganhou pré-visualização de uma regra contra amostras reais sem persistir nada, contadores de 24h por regra, e documentação de por que uma regra fica silenciosa.
Nada muda para quem não criar regra em voo — o modo de avaliação nasce no comportamento anterior.
2.1.0
Correções de fidelidade OCSF e de coleta. O timestamp_t passou a ser emitido em
milissegundos (era segundos — erro de 1000× em todos os mapeamentos), o Veeam passou a
mapear para Scheduled Job Activity e o CloudWatch para Base Event.
Coletores que paginam ganharam teto por ciclo. Sem ele, um acúmulo grande era drenado num único run até estourar o tempo limite da task, que revertia a posição de coleta e recomeçava — o coletor ficava preso sem progredir. Com o teto, o ciclo encerra e o seguinte retoma de onde parou.
Ele limita o volume bruto puxado por ciclo, sem saber quanto daquilo o roteamento vai descartar em seguida. Uma fonte cujo descarte é alto continua gastando cada ciclo transportando o que será jogado fora. É esse o problema que o filtro de coleta da 2.3.0 ataca.
Contadores de rota e métricas de economia passaram a ser gravados incondicionalmente, e não só quando a amostragem estava ligada.
2.0.0
A 2.0.0 é um major: ela remove a superfície de Alertas — por isso o salto de
1.x para 2.0. É a única mudança que quebra compatibilidade; o resto são features,
correções e melhorias de performance (sem ação necessária).
A área de Alertas foi totalmente removida nesta versão. A mudança está no
changelog automático (marcada como ⚠ BREAKING CHANGE) — é o que fez o release virar
2.0.0. O que sai:
- A rota
/alertsdeixa de existir (bookmarks antigos → 404). - Os endpoints de alerts da API foram removidos.
- O caminho Accept v1 do
GET /dashboard/summary(application/vnd.centralops.v1+json) foi removido. - A ferramenta MCP
list_integration_alertsfoi removida.
O que fazer: a triagem agora é vendor-neutra, por Detecta → Busca federada
(Enterprise) e Detecta → Detecções. Se você tem automações ou integrações batendo nos
endpoints de alerts (ou no Accept v1 do /dashboard/summary), migre-as para esses
caminhos antes de atualizar.
A ingestão de sophos.alert (o dado que entra no pipeline) não muda — só a
superfície de leitura de "alertas" saiu.
Novidades (nada a configurar — já vêm ligadas):
- Exportação CSV robusta da Busca federada, com rótulos localizados (PT/EN/ES) — em Detecta → Busca federada.
- Mapa de fluxo
/flowque escala. O Fluxo de dados agrupa colunas densas num nó "+N" expansível e cabe sozinho na tela (fit-to-view), com realce de caminho ao passar o mouse — legível mesmo com dezenas de fontes/rotas/destinos. - Rótulos de condição de rota legíveis. No editor de rotas, os operadores de condição aparecem com nomes humanos e localizados (em vez do rótulo cru).
- Validação de mapping de detecção do Wazuh + correção de uma definição de seed faltante.
Metering de custo ligado por padrão. O COST_METERING_ENABLED agora vem true
por padrão. Com isso, o card "Redução de volume & custo" passa a aparecer em
Roteia → Fluxo de dados: no Community ele mostra volume, percentual e bytes
economizados; no Enterprise ele soma o valor em US$ (a partir do cost_per_gb
configurado em cada destino). Para desligar, defina COST_METERING_ENABLED=false.
Redação de PII ligada por padrão. O PII_REDACTION_ENABLED agora vem true.
Sem regra de mascaramento configurada numa rota, nada muda — a entrega segue idêntica.
A diferença aparece onde existe regra de mascaramento — e o alcance é maior do que
parece. Com a flag desligada, uma única rota com mascaramento derrubava o
carregamento de todas as rotas daquela organização: o tráfego inteiro dela caía no
destino padrão (ou na fila de reenvio, se não houvesse). É fail-closed — nunca houve
entrega em claro, mas houve perda de roteamento silenciosa. Ao subir esta versão, o
roteamento daquela organização volta a valer por completo, e as rotas com mascaramento
passam a entregar ao destino real com os campos mascarados. Antes de subir, confira
quais rotas têm mascaramento configurado e confirme que a entrega ao destino real é o
desejado — e não se surpreenda se destinos que estavam "sem tráfego" voltarem a receber.
Descartar o evento bruto por rota. As regras de roteamento ganharam a opção Descartar o evento bruto, que remove o payload original do fornecedor da entrega daquela rota preservando o evento OCSF. Vem desligada. É a maior economia isolada para um SIEM cobrado por volume — mantenha desligada na rota do data lake. Veja Roteamento.
Poda do payload bruto nos mapeamentos padrão. Os mapeamentos de fábrica passaram a
remover campos nulos e, no caso do Sophos Detection, as subárvores de rawData que já
foram extraídas para o evento normalizado. Se você depende do payload original íntegro
para perícia, revise o bloco raw_reduction do mapeamento antes de subir. Veja
Especificação da DSL.
Havia um defeito em que salvar um mapeamento pela interface apagava silenciosamente o
bloco raw_reduction dele. Se você editou algum mapeamento e notou o payload crescer,
verifique se a poda ainda está lá — ela pode ter sido perdida. O defeito está corrigido:
o bloco agora sobrevive a qualquer edição.
Chave de supressão passou a ser validada. A chave de supressão de uma rota agora só
aceita as mesmas características usadas na condição (fornecedor, severidade, tipo de
evento…). Campos do log como src_ip são recusados com erro — antes eram aceitos em
silêncio e faziam todo o tráfego cair numa assinatura só, descartando praticamente tudo.
Se alguma rota sua tem chave de supressão configurada, revise-a. Veja
Roteamento.
Correções operacionais (informativo — nada a fazer):
- A latência média por destino passou a ter dados, pela primeira vez. A série nunca chegava a ser gravada — o valor registrado era sempre zero, e zeros são descartados —, então o cartão em Roteia → Destinos ficava permanentemente vazio, em qualquer instalação. Agora ele mostra o tempo real de entrega do lote ao destino (todos os pedaços e as novas tentativas), em segundos. O histórico anterior à atualização continua vazio — isso não é defeito: só existem pontos a partir do momento em que você sobe esta versão.
- Os coletores não entram mais em crash-loop de RedBeat (lock, limite de laço e registro idempotente do scheduler corrigidos). Ver também Observabilidade para acompanhar a saúde do Beat.
- O soft-timeout de coleta não envenena mais o pool de conexões do banco
(dispose do pool + inicialização adiantada evitam
UnboundLocalError). - Um
SESSION_SECURE_COOKIEvazio não derruba mais o boot; o ancoramento de caminho do recurso OCSF foi corrigido. - IDs de service account (shim) são sanitizados — sem mais violação de FK em auditoria/mapping.
- A validação OCSF volta a rodar na imagem compilada.
Performance: a medição de volume da ingestão passou a ser em lote
(InVolumeAccumulator), reduzindo a latência de I/O no Redis do hot-path.
Novos defaults de mapping. Esta versão seeda definições padrão para Wazuh e para CrowdStrike, Entra ID, Okta e CloudTrail. Elas só preenchem definições vazias — mappings que você já customizou não são tocados (ver O que acontece com os dados).
Próximos passos
- Upgrade para Enterprise — trocar de edição (Community → Enterprise), não de versão.
- Deploy com Docker Compose — operação da stack single-host.
- Deploy com Kubernetes (Helm) — rollout, HPA e rollback no cluster.
- Configuração — todas as variáveis de ambiente.