Configuração
O servidor é configurado via variáveis de ambiente. Todas são opcionais — os defaults permitem rodar em modo desenvolvimento sem configurar nada.
Variáveis de ambiente
Servidor
| Variável | Tipo | Default | Descrição |
|---|---|---|---|
PORT | int | 8080 | Porta de escuta |
HOST | string | 0.0.0.0 | Endereço de bind |
CORS_ORIGINS | string | * | Origens permitidas (separadas por vírgula) |
Armazenamento
| Variável | Tipo | Default | Descrição |
|---|---|---|---|
STORAGE_BACKEND | string | memory | memory, sqlite ou postgres |
DATABASE_URL | string | — | Caminho do SQLite ou URI do Postgres |
Autenticação
| Variável | Tipo | Default | Descrição |
|---|---|---|---|
AUTH_SECRET | string | — | Segredo HMAC-SHA256 para tokens. Se omitido, auth fica desabilitado |
ACCESS_TOKEN_LIFETIME | int (segundos) | 900 | TTL do access token (clamped: 60–3600s) |
REFRESH_TOKEN_LIFETIME | int (segundos) | 604800 | TTL do refresh token (7 dias) |
REFRESH_FAMILY_MAX_LIFETIME | int (segundos) | 2592000 | Lifetime absoluto da família de refresh (30 dias) |
TOKEN_STORE_PATH | string | — | Caminho do arquivo JSON para persistir tokens. Se omitido, usa store in-memory |
Rate Limiting
| Variável | Tipo | Default | Descrição |
|---|---|---|---|
RATE_LIMIT | 1 ou true | false | Habilita rate limiting |
RATE_LIMIT_READ | int | 120 | Máximo de leituras por minuto por IP |
RATE_LIMIT_WRITE | int | 60 | Máximo de escritas por minuto por IP |
RATE_LIMIT_GENERATE | int | 20 | Máximo de gerações por minuto por IP |
Segurança
| Variável | Tipo | Default | Descrição |
|---|---|---|---|
ALLOWED_HOSTS | string | — | Hosts permitidos para SSRF guard (separados por vírgula) |
ENCRYPTION_KEY | string (base64) | — | Chave AES-256-GCM para criptografia de conexões e assinatura de relatórios |
ENCRYPTION_KEY_PREV | string (base64) | — | Chave anterior para rotação transparente |
MAX_OUTPUT_SIZE | int (bytes) | 209715200 | Tamanho máximo do output (200 MB, clamped: 1 KB–2 GB) |
Export Policy
| Variável | Tipo | Default | Descrição |
|---|---|---|---|
EXPORT_ALLOWED_IDENTITIES | string | — | Emails ou domínios permitidos para exportação verificada (separados por vírgula). Ex: user@example.com,acme.com. Vazio = todos permitidos |
EXPORT_PROTECTED_FORMATS | string | sulfite,pdf | Formatos que exigem verificação OTP (separados por vírgula) |
EXPORT_REQUIRE_ALL | 1 ou true | false | Se true, todos os formatos exigem verificação OTP |
EXPORT_OTP_EXPIRATION | int (segundos) | 300 | Tempo de expiração do código OTP (5 minutos) |
EXPORT_OTP_MAX_ATTEMPTS | int | 3 | Tentativas máximas antes de invalidar o OTP |
EXPORT_OTP_LENGTH | int | 15 | Comprimento do código OTP alfanumérico |
Edit Policy
| Variável | Tipo | Default | Descrição |
|---|---|---|---|
EDIT_POLICY_ENABLED | 1 ou true | false | Habilita a política de edição com OTP |
EDIT_ALLOWED_IDENTITIES | string | — | Emails ou domínios autorizados a editar/salvar, separados por vírgula. Vazio = todos permitidos |
EDIT_TOKEN_SECRET | string | — | Segredo HMAC para assinar tokens de edição e salvamento. Se omitido, um segredo efêmero é gerado por processo (tokens expiram ao reiniciar) |
EDIT_TOKEN_EXPIRATION | int (segundos) | 3600 | TTL do token de edição (1 hora) |
SAVE_TOKEN_EXPIRATION | int (segundos) | 300 | TTL do token de salvamento (5 minutos) |
EDIT_OTP_EXPIRATION | int (segundos) | 300 | Expiração do código OTP |
EDIT_OTP_MAX_ATTEMPTS | int | 3 | Tentativas máximas antes de invalidar o OTP |
EDIT_OTP_LENGTH | int | 6 | Comprimento do código OTP numérico |
Email
O servidor suporta dois providers de email (para share notifications, OTP de exportação e OTP de edição):
| Variável | Provider | Descrição |
|---|---|---|
RESEND_API_TOKEN | Resend | API token do Resend |
RESEND_FROM_EMAIL | Resend | Endereço de envio verificado |
RESEND_FROM_NAME | Resend | Nome do remetente (default: Sulfite) |
MAILERSEND_API_TOKEN | MailerSend | API token do MailerSend |
MAILERSEND_FROM_EMAIL | MailerSend | Endereço de envio verificado |
MAILERSEND_FROM_NAME | MailerSend | Nome do remetente (default: Sulfite) |
Se nenhum provider for configurado, o servidor usa LogEmailProvider — emails são logados no stdout mas não enviados.
Exemplos de configuração
Desenvolvimento local
bash
# Sem auth, sem persistência — tudo em memória
dart run bin/sulfite_server.dartProdução com SQLite
bash
export AUTH_SECRET="meu-segredo-longo-e-aleatorio"
export STORAGE_BACKEND=sqlite
export DATABASE_URL=./data/reports.db
export CORS_ORIGINS="https://meuapp.com,https://admin.meuapp.com"
export RATE_LIMIT=true
export TOKEN_STORE_PATH=./data/tokens.json
dart run bin/sulfite_server.dartProdução com PostgreSQL e criptografia
bash
export AUTH_SECRET="segredo-de-producao"
export STORAGE_BACKEND=postgres
export DATABASE_URL="postgres://user:pass@host:5432/sulfite"
export ENCRYPTION_KEY="base64-encoded-32-byte-key"
export ALLOWED_HOSTS="api.externa.com,supabase.co"
export CORS_ORIGINS="https://app.meudominio.com"
export RATE_LIMIT=true
export RATE_LIMIT_GENERATE=10
export MAX_OUTPUT_SIZE=104857600 # 100 MB
dart run bin/sulfite_server.dartDocker
dockerfile
FROM dart:stable AS build
WORKDIR /app
COPY packages/sulfite_server/ .
RUN dart pub get
RUN dart compile exe bin/sulfite_server.dart -o server
FROM scratch
COPY --from=build /runtime/ /
COPY --from=build /app/server /app/server
EXPOSE 8080
CMD ["/app/server"]Fluxo de inicialização
O servidor inicializa os componentes nesta ordem:
- ServerConfig — carrega variáveis de ambiente
- ReportRepository — cria backend de armazenamento (SQLite, Postgres ou memória)
- ConnectionRegistry — registro de conexões (opcionalmente com criptografia AES-256-GCM)
- SulfiteEngine — instância do motor de renderização
- DataSourceResolvers —
RestDataSourceResolver,PostgresDataSourceResolver,PostgRestDataSourceResolver - SsrfGuard — proteção SSRF (se
ALLOWED_HOSTSconfigurado) - JobQueue — fila de geração assíncrona
- RateLimiter — rate limiting por IP (se
RATE_LIMIT=true) - TokenStore — store de refresh tokens (persistente ou in-memory)
- ReportSigner — assinatura de relatórios (se
ENCRYPTION_KEYconfigurado) - SulfiteServer — monta o app HTTP com middleware pipeline e handlers
Pipeline de middleware
Cada request passa por esta cadeia (nesta ordem):
→ CORS middleware Valida origens, envia headers CORS
→ Security headers X-Content-Type-Options, X-Frame-Options, Cache-Control
→ Error middleware Captura exceções, sanitiza logs
→ Request logger Loga método, path, status, duração
→ Auth middleware Valida Bearer/X-API-Key, anexa AuthToken ao request
→ Rate limiter Limita requests por IP (se habilitado)
→ Handler Processa a request