chore: initial project skeleton
Acauã: Network Detection & Threat Hunting, heuristic analysis over a rolling 7-day window using deterministic math (time series, graph theory, information theory) instead of opaque ML models. Third product in the Ciberfauna ecosystem, alongside Guará and Sabiá. Follows the ecosystem's established conventions: OpenWolf project memory, bilingual PT-BR/EN docs and UI, Gitea Actions CI/CD on the same self-hosted runners, Conventional Commits, SemVer, logo and productName handling, MIT OR Apache-2.0 licensing. Architecture decision (made with the project owner after a dedicated consultation, not the original blueprint's suggested stack): Rust throughout, not Python/FastAPI/React. Most of the statistics (Bowley skew, MADM, Shannon entropy, PCR, Z-score, novel-edge detection, pivot chains) reduces to SQL over an embedded DuckDB/Parquet store; only the spectral analysis and graph centrality need host-language code, and both have workable Rust crates. Documented in full, including six corrections to the original blueprint's math (Rayleigh/Schuster instead of a degenerate Lomb-Scargle over bare timestamps, an explicit sentinel for Bowley skew's Q3=Q1 case, Jensen-Shannon instead of unbounded KL, a dedicated long-connection detector, JA4 vs. JA4+ licensing caution, deterministic per-alert evidence), in docs/architecture.md. Skeleton only: crates/acaua-core has the four detection pillars, fusion, storage, zeek log parsing and the updater as typed stubs that compile and return a clear "skeleton" status rather than real detection logic — that is separate, future work. crates/acaua-cli has serve/analyze/doctor/update. apps/gui is a minimal Tauri shell. Also already includes the one-click desktop self-update mechanism shared with Guará and Sabiá (AppImage/.deb/Windows installer), even with no release published yet, for consistency across the ecosystem. No Gitea repository exists for this project yet; this is a local-only commit. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VAyr8d7HuAdUGB6aA5xmDD
This commit is contained in:
commit
1b974bb90d
95 files changed
+12016
No files matched your search
@@ -0,0 +1,177 @@
|
||||
# Arquitetura
|
||||
|
||||
[English](../architecture.md) · **Português**
|
||||
|
||||
O Acauã é um único produto Rust: um daemon/CLI, um núcleo compartilhado, uma UI
|
||||
web embutida e um shell Tauri. O runtime distribuído não tem Python nem banco
|
||||
externo. Este documento registra as decisões estruturais e as seis correções
|
||||
aplicadas ao blueprint original.
|
||||
|
||||
## Stack
|
||||
|
||||
| Camada | Escolha | Por quê |
|
||||
|---|---|---|
|
||||
| Núcleo, CLI e daemon | Rust 2021 | Uma toolchain, segurança de memória, sem dependência de runtime |
|
||||
| API HTTP | Axum + Tokio + Tower HTTP | Superfície async pequena e fácil de embutir |
|
||||
| UI | HTML/CSS/JS vanilla | Sem etapa de build de frontend, assets embutidos no binário |
|
||||
| Desktop | Tauri 2 | Janela nativa sobre a mesma UI |
|
||||
| Armazenamento analítico | DuckDB + Parquet (feature opcional `duckdb`) | Embutido, colunar, local-first |
|
||||
| Validação científica | Python só em `research/` | astropy/scipy/networkx para fixtures, nunca distribuído |
|
||||
|
||||
O workspace tem dois crates: `acaua-core` e `acaua-cli`. A GUI fica em
|
||||
`apps/gui`, **fora** do workspace Cargo, como no Guará e no Sabiá. A spec citou
|
||||
`version.workspace = true` para o manifesto do desktop; manter a GUI fora do
|
||||
workspace torna isso impossível, então o `check.sh` impõe igualdade de SemVer
|
||||
entre `Cargo.toml`, `acaua-cli/Cargo.toml`, o manifesto do desktop e
|
||||
`tauri.conf.json`. É um desvio deliberado, não um esquecimento.
|
||||
|
||||
## Componentes
|
||||
|
||||
```
|
||||
Logs Zeek ──► acaua-core::zeek ──► eventos normalizados ──► armazenamento
|
||||
│
|
||||
├──► pilar1 (beaconing)
|
||||
├──► pilar2 (sessões persistentes)
|
||||
├──► pilar3 (anomalias de protocolo)
|
||||
└──► pilar4 (fusão) ──► alertas + evidência
|
||||
│
|
||||
acaua-cli ──► API axum ──► UI embutida ◄── shell Tauri ────────────┘
|
||||
```
|
||||
|
||||
- `zeek`: parser limitado e confinamento de caminho. Nunca segue link simbólico
|
||||
para fora da raiz do dataset.
|
||||
- `storage`: escritor DuckDB/Parquet com TTL de sete dias. Desligado por padrão
|
||||
para o esqueleto não exigir build C++.
|
||||
- `pillar1`–`pillar4`: funções puras sobre eventos normalizados. Devolvem
|
||||
pontuação e evidência, nunca só um float.
|
||||
- `fusion`: combinação limitada e em ordem fixa. Precisa ser simétrica e
|
||||
reproduzível.
|
||||
- `doctor`: checagens do ambiente local; sem chamadas de rede exceto a checagem
|
||||
explícita de atualização.
|
||||
- `update`: cliente de Gitea Releases só para a CLI.
|
||||
|
||||
## As seis correções
|
||||
|
||||
### 1. Rayleigh/Schuster, não Lomb–Scargle puro
|
||||
|
||||
Timestamps de eventos são um processo pontual unidimensional: não existe um `y`
|
||||
para ajustar. O periodograma primário é, portanto, Rayleigh/Schuster:
|
||||
|
||||
```text
|
||||
P(f) = |sum_k exp(2*pi*i*f*t_k)|^2 / N
|
||||
```
|
||||
|
||||
O Lomb–Scargle generalizado só é usado quando existe um `y` real (por exemplo,
|
||||
bytes por bucket). Isso evita inventar uma variável dependente e mantém a
|
||||
distribuição nula honesta.
|
||||
|
||||
### 2. Bowley com sentinela explícito
|
||||
|
||||
O coeficiente de Bowley usa quartis. Quando `Q3 == Q1`, o denominador é zero; a
|
||||
implementação devolve um sentinela documentado (`0.0` com a flag de evidência
|
||||
`degenerate_quartiles`) em vez de `NaN`, infinito ou panic. O sentinela faz parte
|
||||
do registro do alerta, não é fallback silencioso.
|
||||
|
||||
### 3. Jensen–Shannon, não KL puro
|
||||
|
||||
KL diverge quando a distribuição de referência tem zero onde a observada não
|
||||
tem. A fusão usa Jensen–Shannon, que é simétrica, limitada e definida para bins
|
||||
com probabilidade zero com um piso de suavização documentado. Isso torna a
|
||||
pontuação comparável entre pilares e segura para histogramas esparsos.
|
||||
|
||||
### 4. Sessões persistentes têm detector próprio
|
||||
|
||||
Uma conexão aberta por horas nunca produz um intervalo curto, então um detector
|
||||
de beaconing pode ignorá-la. O pilar 2 pontua duração, lacunas ociosas e fluxos
|
||||
longos repetidos diretamente. Os dois pilares podem disparar; a fusão trata isso
|
||||
como evidências separadas, não como contagem dupla do mesmo sinal.
|
||||
|
||||
### 5. Cautela com a licença JA4
|
||||
|
||||
A impressão digital JA4 de cliente TLS pode ser usada. JA4S, JA4H, JA4X, JA4SSH
|
||||
e JA4L têm licença não-OSI e **não** são habilitadas por padrão. Qualquer uso
|
||||
futuro exige decisão explícita de licenciamento e opt-in documentado. O conjunto
|
||||
padrão precisa continuar redistribuível sob MIT/Apache-2.0.
|
||||
|
||||
### 6. Determinismo e evidência JSON por alerta
|
||||
|
||||
Todo alerta carrega um registro JSON: hash do dataset, versão do código, pilar,
|
||||
entradas, valores intermediários, sentinelas, pesos e pontuação final. As
|
||||
reduções rodam em ordem fixa; iteração de hash map ou agendamento de threads não
|
||||
pode mudar uma pontuação. Com a mesma entrada e versão, a evidência precisa ser
|
||||
byte a byte idêntica.
|
||||
|
||||
## Fluxo de dados
|
||||
|
||||
1. `acaua analyze <dir>` valida o diretório, lê logs suportados e normaliza
|
||||
eventos. Neste esqueleto ele valida e devolve um relatório stub.
|
||||
2. Eventos normalizados vão para o armazenamento local (quando a feature
|
||||
`duckdb` está ligada) com TTL de sete dias.
|
||||
3. Cada pilar roda sobre uma janela determinística e devolve candidatos com
|
||||
evidência.
|
||||
4. A fusão combina candidatos, aplica limiares e grava alertas.
|
||||
5. `serve` expõe a API e a UI embutida; o shell Tauri abre a mesma UI contra um
|
||||
daemon local ou remoto.
|
||||
|
||||
## API
|
||||
|
||||
| Método | Caminho | Finalidade |
|
||||
|---|---|---|
|
||||
| GET | `/api/health` | Liveness e versão |
|
||||
| GET | `/api/status` | Uptime, diretório de dados, estado dos pilares |
|
||||
| GET | `/api/alerts` | Alertas paginados com evidência |
|
||||
| POST | `/api/analyze` | Analisar um caminho de dataset |
|
||||
| POST | `/api/update` | Checar atualização da CLI |
|
||||
| GET | `/logo.png` | Asset de marca embutido |
|
||||
| GET | `/*` | Fallback da UI embutida |
|
||||
|
||||
O `serve` escuta em `127.0.0.1:8787` por padrão. Não há camada de autenticação
|
||||
no esqueleto; expor em interface de rede exige proxy reverso com autenticação.
|
||||
|
||||
## Armazenamento
|
||||
|
||||
DuckDB é dependência **opcional** (`features = ["duckdb"]`, `bundled`). O
|
||||
esqueleto padrão não compila o backend C++. Quando ligado, o schema é de eventos
|
||||
normalizados append-only mais uma tabela de alertas, com exportação Parquet e
|
||||
retenção de sete dias. O arquivo do banco fica sob o diretório de dados
|
||||
configurado e nunca fora dele.
|
||||
|
||||
## Atualizações
|
||||
|
||||
`update.rs` consulta a API de Gitea Releases do repositório `acaua`, escolhe o
|
||||
asset da plataforma atual, baixa por HTTPS com `curl`, verifica SHA-256 e
|
||||
substitui o binário da CLI. Ele se recusa a atualizar automaticamente uma GUI em
|
||||
execução; o desktop só informa que existe versão nova. Isso espelha o updater do
|
||||
Sabiá e evita um segundo mecanismo de atualização.
|
||||
|
||||
O plugin updater do Tauri e seu fluxo de manifesto e assinatura não são usados
|
||||
de propósito: adicionariam um segundo caminho de assinatura e distribuição, e o
|
||||
desktop não deve se auto-atualizar. O caminho único da CLI é mais fácil de
|
||||
auditar e mantém os assets de release em tarballs mais SHA-256.
|
||||
|
||||
## Alternativas rejeitadas
|
||||
|
||||
Um blueprint anterior propunha um serviço Python e um banco colunar externo. Os
|
||||
dois são rejeitados. Um serviço Python adicionaria um segundo runtime, custo de
|
||||
empacotamento e uma fronteira de rede dentro de uma ferramenta local-first; um
|
||||
banco externo adicionaria servidor e custo operacional para datasets que cabem em
|
||||
um armazenamento colunar embutido. O produto é 100% Rust, com Python confinado a
|
||||
`research/`.
|
||||
|
||||
## Implantação
|
||||
|
||||
- **Nativa:** `cargo build --release -p acaua-cli`, depois `acaua serve`.
|
||||
- **Desktop:** bundles Tauri para Linux e Windows, construídos no CI.
|
||||
- **Docker:** imagem enxuta de runtime para laboratório; veja [docker.md](docker.md).
|
||||
|
||||
## Comportamento em falha
|
||||
|
||||
Entrada malformada é ignorada com diagnóstico contado e limitado. Log ausente não
|
||||
é fatal. Store corrompido é reportado pelo `doctor` e nunca recriado por cima de
|
||||
dados existentes. Atualização falha mantém o binário atual.
|
||||
|
||||
## Versionamento e compatibilidade
|
||||
|
||||
SemVer 2.0.0. O JSON de evidência carrega versão de schema. Qualquer mudança em
|
||||
pontuação ou no formato da evidência é quebra para versões menores `0.x` e
|
||||
precisa constar no changelog.
|
||||
Reference in new issue
Block a user