Saltar para o conteúdo
BeryxTechBeryxTech
Voltar às respostas para RFP

Documentação do BeryX

Varredura de engenharia: notebooks, jobs, pipelines e DDL no Databricks e no Snowflake

A qualidade dos dados depende do código que os produz. Numa conexão Databricks ou Snowflake, o BeryX pode ler também os notebooks, os jobs, os pipelines, os modelos ML e o DDL de views, tasks, streams e procedures, e procurar neles práticas de risco: credenciais escritas no código, SELECT *, jobs agendados sem retry, timeout ou alerta, notebooks que escrevem tabelas sem job nenhum, escrita na camada Gold a partir da Bronze, tasks suspensas, streams stale e warehouses sem auto-suspend.

Cada heurística que encontra alguma coisa abre um problema do tipo «Engenharia», com a lista dos ativos afetados. Um workspace com 300 notebooks com SELECT * tem um problema de prática, e não 300.

A varredura é opt-in por conexão e só lê. No Databricks faz apenas pedidos GET às APIs oficiais; no Snowflake só corre SHOW e SELECT de catálogo. O código lido não fica guardado: os problemas levam o tipo de achado, o nome do ativo e a linha, e o valor de uma credencial nunca é mostrado nem gravado.

O que lê

A varredura usa as credenciais da própria conexão. Cada coleção é lida à parte: se o token ou o papel não tiver acesso a uma delas, essa coleção fica de fora, a varredura continua e o painel mostra-a em «Cobertura parcial».

Databricks

Com o host e o token da conexão, só pedidos GET, pelo mesmo cliente HTTP só de leitura e com a mesma guarda anti-SSRF dos outros conectores:

API O que traz
Workspace API (/api/2.0/workspace/list e /workspace/export, formato SOURCE) Os notebooks e o código de cada um
Jobs API 2.1 (/api/2.1/jobs/list e /jobs/runs/list) Agendamento, retries, timeouts, alertas de falha, notebooks de cada task e o estado do último run
Pipelines (/api/2.0/pipelines) Estado e última atualização dos pipelines DLT e Lakeflow, e os notebooks de cada um
MLflow Model Registry (/api/2.0/mlflow/registered-models/search) A data da versão mais recente de cada modelo

O token precisa de leitura nas pastas do workspace, nos jobs, nos pipelines e no Model Registry que queres analisar. O que não conseguir ler fica em «Cobertura parcial».

Snowflake

Com o utilizador e o papel da conexão, só comandos de catálogo. Antes de chegar ao driver, cada comando passa por uma guarda que recusa tudo o que não seja um único SHOW, SELECT ou DESCRIBE:

Comando O que traz
SHOW WAREHOUSES Tamanho e auto-suspend de cada warehouse
SHOW TASKS IN DATABASE Estado, agendamento, SQL e data da última suspensão
SHOW STREAMS IN DATABASE Se o stream está stale
SHOW MATERIALIZED VIEWS IN DATABASE A definição de cada materialized view
INFORMATION_SCHEMA.PROCEDURES O corpo de cada procedure
INFORMATION_SCHEMA.VIEWS, com GET_DDL quando a definição vem vazia A definição de cada view

O papel só vê os objetos sobre os quais tem algum privilégio. Nunca há SELECT sobre dados de tabelas.

O que procura

Um problema por heurística e por conexão, com até 50 ativos listados (a contagem é a total):

Heurística Severidade Fonte O que deteta
hardcoded_secret crítica ambas Credenciais escritas no código (token Databricks, chave de acesso AWS, chave privada, token GitHub ou Slack, chave de API de LLM, password numa connection string ou num literal). Mostra o tipo e a linha, nunca o valor. Placeholders e leituras de cofres (dbutils.secrets, variáveis de ambiente) não contam
gold_direct_write aviso ambas Um notebook, uma view ou outro objeto SQL escreve (ou define) uma tabela Gold a ler diretamente da Bronze, sem passar pela Silver. A camada sai do nome do schema ou da tabela (gold, mart, bronze, raw, landing…)
select_star info ambas SELECT * em notebooks e no SQL de views, procedures e tasks: uma coluna nova, removida ou renomeada a montante muda o que chega a jusante sem ninguém dar por isso
job_no_retry aviso Databricks Job agendado e ativo com alguma task sem max_retries
job_no_timeout aviso Databricks Job agendado e ativo sem timeout_seconds no job nem em todas as tasks
job_no_alert aviso Databricks Job agendado e ativo sem notificação on_failure, nem no job nem nas tasks
job_failing aviso Databricks O último run do job terminou em falha
pipeline_failing aviso Databricks Pipeline DLT ou Lakeflow com o estado ou a última atualização em falha
orphan_notebook info Databricks Notebook que escreve tabelas e que nenhum job nem pipeline executa. Só é avaliado quando os jobs e os pipelines foram listados até ao fim
task_suspended aviso Snowflake Task suspensa há mais de 30 dias
stream_stale aviso Snowflake Stream stale: perdeu o offset e há alterações que já não se consomem
model_stale aviso Databricks Modelo ML cuja versão mais recente tem mais de 90 dias
warehouse_no_autosuspend aviso Snowflake Warehouse sem auto-suspend ou com mais de 60 minutos

A cada varredura, um problema que persiste é atualizado (um «reconhecido» continua reconhecido), um que desaparece passa a resolvido e um novo é criado. Desativar a varredura resolve os problemas de engenharia abertos da conexão.

A mesma leitura dos notebooks propõe também regras candidatas: as asserções escritas no código (assert, validações com raise, dropna, dropDuplicates) passam a sugestões de regra para as tabelas que o BeryX já conhece, com o trecho anonimizado como evidência. Aparecem em Sugestões com a origem «Minerada em notebooks».

Ativar e pedir na app

  1. Em Conexões, o cartão de uma conexão Databricks ou Snowflake tem a linha «Varredura de engenharia», com o estado (ativada ou desativada) e o número de achados abertos. Carrega em Abrir.
  2. No painel, um administrador carrega em Ativar varredura.
  3. Com a varredura ativada, carrega em Pedir varredura. Se quiseres, marca antes Juntar um resumo por IA (ver O que sai para a IA).
  4. A varredura corre em segundo plano. O painel volta a ler o estado até ela terminar e mostra os achados abertos por heurística, o que foi lido (notebooks, jobs, views…) e o que ficou de fora.
  5. Ver os achados de engenharia em Problemas abre /problemas?type=engineering, com o filtro «Engenharia (notebooks, jobs, DDL)» já aplicado. Cada achado do painel também leva ao seu problema.

Uma API ou um comando recusado só deixa essa coleção de fora. Uma varredura que falhe, por exemplo sem ligação à fonte, não deixa registo no painel: testa a conexão e pede de novo.

Pela API

Três endpoints na conexão:

Método e caminho Para quê Quem
GET /api/v1/connections/{id}/engineering Estado: enabled, supported, a última varredura (last_scan, com inventário, notas, telemetria e resumo) e os problemas abertos (issues) Qualquer papel do workspace, também com um token de API
PATCH /api/v1/connections/{id}/engineering Ativar ou desativar: {"enabled": true} Administradores
POST /api/v1/connections/{id}/engineering/scan Pedir a varredura: {"llm_summary": false} Administradores e membros
# Estado (um token dvk_* de leitura chega)
curl -s "$DATAVAULT_API_URL/api/v1/connections/$CONNECTION_ID/engineering" \
  -H "Authorization: Bearer $DATAVAULT_TOKEN"

# Ativar e pedir a varredura (sessão de um administrador)
curl -s -X PATCH "$DATAVAULT_API_URL/api/v1/connections/$CONNECTION_ID/engineering" \
  -H "Authorization: Bearer $SESSION" -H "Content-Type: application/json" -d '{"enabled": true}'
curl -s -X POST "$DATAVAULT_API_URL/api/v1/connections/$CONNECTION_ID/engineering/scan" \
  -H "Authorization: Bearer $SESSION" -H "Content-Type: application/json" -d '{"llm_summary": false}'
  • Os tokens de API dvk_* são de leitura: servem para o GET. O PATCH e o POST fazem-se na app ou com a sessão de um utilizador.
  • O POST responde 409 com a varredura desativada ou dentro de uma janela de blackout da conexão («Boa vizinhança»). O PATCH responde 400 ao ativar numa conexão que não seja Databricks nem Snowflake.
  • Em produção, o POST põe a varredura na fila e responde {"status": "queued"}. Sem fila (instalação de desenvolvimento), corre logo e responde {"status": "completed", …} com os achados.
  • Ativar e desativar ficam na auditoria do workspace.

O que é só leitura e o que fica guardado

  • Na fonte: só pedidos GET (Databricks) e só SHOW/SELECT/DESCRIBE de catálogo (Snowflake). Nada é criado, alterado ou executado na fonte.
  • No BeryX: o código lido é analisado em memória e descartado no fim da varredura. Os problemas guardam o nome de cada ativo (caminho do notebook, nome do job, schema.objeto) e um detalhe curto («SELECT * na linha 12», «token Databricks (linha 4)»). Um nome com aspeto de credencial também é substituído antes de ser gravado.
  • Telemetria: o número de pedidos, os bytes lidos e a duração ficam no registo da varredura, ao lado dos limites usados.

O que sai para a IA

Só quando pedes Juntar um resumo por IA (llm_summary: true), e só se houver achados.

  • O que recebe: a fonte (Databricks ou Snowflake), as contagens do inventário e, para no máximo 15 heurísticas, o nome, a severidade, o título, a contagem e até cinco exemplos (tipo, nome e detalhe do ativo). Tudo passa antes pela remoção de credenciais e de emails.
  • O que nunca recebe: o código, o conteúdo dos notebooks e o valor de uma credencial.
  • Pastas pessoais: no Databricks, o caminho de um notebook pessoal tem o email do dono (/Users/<email>/…). Segue como /Users/<utilizador>/…, e qualquer outro email como <email>.
  • Classe de dados: metadata_only. A tarefa chama-se «Varredura de engenharia» na Política de IA do workspace: com a IA desligada não há resumo, e os modelos permitidos, a chave própria e as rotas BYOK valem também para ela. Por omissão vai para o Claude Haiku da Anthropic.
  • Custo: conta no orçamento de IA do workspace, como as outras tarefas.
  • Sem fornecedor disponível, com o orçamento esgotado ou com a IA desligada, a varredura corre na mesma e o painel diz porque não há resumo. O resumo aparece com o selo «Conteúdo gerado por IA».

Quem pode fazer o quê

Ação Administrador Membro Leitor
Ver o estado e os achados sim sim sim
Pedir a varredura sim sim não
Ativar ou desativar sim não não

Não há limite por plano: a varredura está em todos os planos e não conta na quota de scans. O resumo por IA conta no orçamento de IA do plano.

Limites

Cada varredura tem tetos, para não pesar na fonte nem prender o worker. A conexão pode baixar ou subir cada um com engineering_limits no config enviado pela API ao criar a conexão, nunca acima do teto. A app não tem campo para isto.

Limite Por omissão Teto
max_notebooks 200 1000
max_notebook_bytes 200 000 1 000 000
max_jobs 200 1000
max_objects 500 2000
max_requests 400 2000
timeout_s 120 600
  • Um limite atingido aparece em «Cobertura parcial» e deixa a coleção incompleta. Com os jobs ou os pipelines incompletos, a heurística orphan_notebook não é avaliada.
  • Ao chegar ao timeout_s ou ao max_requests, a varredura para e guarda o que já leu. Um pedido pendurado que passe do timeout_s mais 60 segundos faz falhar a varredura sem guardar nada.
  • O SELECT *, os segredos e a camada Gold/Bronze leem-se por padrões no texto, sem executar o código: um nome montado em tempo de execução escapa, e um falso positivo é possível.
  • A camada sai só dos nomes. Um lakehouse sem bronze, silver ou gold (ou equivalentes) nos nomes não tem achados gold_direct_write.