Modos de Carga

O Tatuzim implementa tres modos de entrega, cada um otimizado pra um nivel de confianca e tipo de conteudo. Apenas csr_cert esta implementado no MVP; selado e push estao no roadmap.

Visao Geral

Modo Confianca Quem inicia Quem cifra Uso tipico
csr_cert Alta Agent (pull) step-ca (sem segredo cifrado) Cert TLS — chave privada gerada localmente
selado Alta Agent (pull) Publisher (envelope) Plugins, secrets — confidencial por destinatario
push Media Server (push) Publisher (assinatura) Listas de bloqueio, configs publicas

Modo `csr_cert` (implementado)

Quando usar: o agente precisa de um certificado e a chave privada NUNCA pode trafegar (ex: cert TLS pra Traefik servindo HTTPS no proprio VPS).

Fluxo

1. Admin: tatuzim carga create --tipo csr_cert --nome traefik-cert --destino vps-01
        (registra a carga + entrega pendente)

2. Agent (loop run):
   GET /v1/manifest → ve [{ id=E1, tipo=csr_cert, nome=traefik-cert }]
   
   Para E1:
     - Gera keypair ECDSA P-256 LOCAL
     - Cria CSR com CN=vps-01
     - POST /v1/certs/issue { csr_pem } via mTLS
     - Server orquestra step-ca → cert
     - Recebe { cert_pem, ca_pem }
     - Escreve out/traefik-cert.crt + out/traefik-cert.key
     - POST /v1/events entrega_instalada
     - Executa hook post-csr-cert

Garantias

  • Chave privada nunca sai do agent — server jamais ve nem armazena
  • Server e step-ca veem apenas o CSR (publico)
  • Idempotente: agent marca entrega em processed.json apos sucesso
  • Audit: cada passo gera evento

Limitacao MVP

O CN do CSR e sempre o hostname do agent. Pra emitir cert com outro CN (dev.cdn.borlot.com.br), precisa de mecanismo dedicado (sub-fase futura ou direto via step-ca + outro provisioner).

Modo `selado` (roadmap v0.2)

Quando usar: voce quer entregar conteudo confidencial criado fora do agent (ex: plugin compilado, secret estatico).

Conceito: Envelope Encryption

Voce (publisher):
  1. Gera DEK (Data Encryption Key) random
  2. Cifra plaintext com DEK → ciphertext_blob
  3. Para cada destinatario:
     - Pega pubkey_X25519 do agent (do enroll)
     - ECDH(DEK, agent_pubkey) → wrapped_dek_per_recipient
  4. Sobe { ciphertext_blob, [wrapped_dek_per_agent...] } pro server

Server:
  - Armazena o blob (no Cofre, planejado)
  - Marca entregas pendentes por destinatario

Agent (loop):
  - Ve carga selado no manifest
  - GET /v1/blobs/<id> → recebe seu wrapped_dek + ciphertext
  - X25519 ECDH com sua privkey → DEK
  - ChaCha20-Poly1305 decrypt(DEK, ciphertext) → plaintext
  - Instala

Garantias

  • Confidencialidade per-destinatario: agent comprometido nao decripta carga dos outros
  • Authenticity: publisher assina pacote inteiro
  • No-trust-server: server nao tem como decriptar (so move blobs)

Pre-requisitos pra implementacao

  • Agent envia pubkey X25519 no enroll (alem do cert)
  • Server precisa de storage adequado pros blobs (Cofre)
  • Tabela cargas ja tem cofre_blob_prefix reservado pra isso
  • Crate chacha20poly1305 ja no workspace

Modo `push` (roadmap v0.3)

Quando usar: dados nao confidenciais que voce quer distribuir rapido pra todos os agentes (listas de bloqueio, regras de WAF, datasets compartilhados).

Conceito

Server inicia a entrega em vez de esperar o agent puxar:

Admin: tatuzim carga create --tipo push --nome block-list --destino agents-com-role-web

Server:
  - Identifica destinatarios (todos com role=web)
  - Pra cada agent ativo:
    - Long-polling open OR proximo poll dele
    - Server entrega payload assinado (sem cifra por dest, pq nao e confidencial)

Agent:
  - Recebe payload (via response do long-poll OU push da pubsub futura)
  - Valida assinatura do publisher
  - Aplica/instala
  - Reporta evento

Por que existir push se voce pode pull frequente?

Pull frequente (cada 5s) consome banda e CPU pra checks que retornam vazio. Push:

  • Latency baixa pra distribuicao urgente (lista de bloqueio que precisa propagar AGORA)
  • Banda otima (so trafega quando ha conteudo)

Trade-off: complexidade — conexao persistente ou polling rapido continuo.

Comparacao das garantias

Garantia csr_cert selado push
Confidencialidade end-to-end ✓ (key local) ✓ (envelope) ✗ (publico)
Autenticidade do conteudo ✓ (cert do step-ca) ✓ (assinatura publisher) ✓ (assinatura publisher)
Server pode ler conteudo N/A (e cert publico) ✓ (mas e publico mesmo)
Idempotencia
Audit log

Quando usar qual

Tem chave privada/secret?
   │
   ├─ Sim, e cliente quer gerar local (cert TLS, ECDSA pra signing)
   │      → csr_cert
   │
   ├─ Sim, e voce quer DISTRIBUIR (plugin com secret embed, .env)
   │      → selado
   │
   └─ Nao, e conteudo publico
          ├─ Atualizacao frequente, baixa latencia desejada (block-list)
          │      → push
          └─ Atualizacao esparsa, ok esperar proximo poll
                 → selado (sem confidencialidade efetiva, mas usa infra existente)

Implementacao por modo

Camada csr_cert selado push
tatuzim_core::types::TipoCarga CsrCert Selado Push
Schema (cargas/entregas) ✓ (campos ja reservados)
API endpoints /v1/manifest, /v1/certs/issue /v1/blobs/<id> (pendente) /v1/push/<agent_id> (pendente)
Agent processor process_csr_cert process_selado (pendente) process_push (pendente)
Crypto step-ca (CSR) ChaCha20-Poly1305 + X25519 ECDH Ed25519 signature

Referencias

By Borlot.com.br on 23/05/2026