Benchmark Argon2id — Edge Function
Objetivo
Medir o desempenho real do Argon2id dentro do isolate Deno das Supabase Edge Functions para calibrar os parâmetros de produção (memory cost, time cost, parallelism).
Contexto
- Runtime: Deno isolate com 256 MB de memória e 2s de CPU time por invocação
- Scaling: horizontal automático — cada login simultâneo roda em isolate separado
- Biblioteca:
npm:hash-wasm@4.11.0(WASM puro, compatível com Deno) - Variante: Argon2id (resistente a side-channel + GPU)
Resultados (25 de março de 2026)
Tabela consolidada (14 configurações, 5 runs cada)
| # | Config | m (MB) | t | p | Avg (ms) | Min (ms) | Max (ms) | Veredicto |
|---|---|---|---|---|---|---|---|---|
| 1 | OWASP mínimo | 19 | 2 | 1 | 47 | 43 | 52 | 🟢 VIÁVEL |
| 2 | OWASP alt | 45 | 1 | 1 | 90 | 84 | 96 | 🟢 VIÁVEL |
| 3 | OWASP alt + t2 | 45 | 2 | 1 | 132 | 127 | 142 | 🟢 VIÁVEL |
| 4 | 50MB t2 | 50 | 2 | 1 | 153 | 147 | 161 | 🟢 VIÁVEL |
| 5 | 50MB t3 | 50 | 3 | 1 | 205 | 201 | 209 | 🟢 VIÁVEL |
| 6 | 64MB t2 | 64 | 2 | 1 | 189 | 186 | 193 | 🟢 VIÁVEL |
| 7 | 64MB t3 | 64 | 3 | 1 | 229 | 225 | 237 | 🟢 VIÁVEL |
| 8 | 64MB t4 | 64 | 4 | 1 | 343 | 333 | 368 | 🟢 VIÁVEL |
| 9 | 80MB t3 | 80 | 3 | 1 | 274 | 269 | 279 | 🟢 VIÁVEL |
| 10 | 100MB t2 | 100 | 2 | 1 | 306 | 297 | 325 | 🟢 VIÁVEL |
| 11 | 128MB t2 | 128 | 2 | 1 | 378 | 374 | 385 | 🟢 VIÁVEL |
| 12 | 64MB t5 | 64 | 5 | 1 | — | — | — | 🔴 CRASH |
| 13 | 100MB t3 | 100 | 3 | 1 | — | — | — | 🔴 CRASH |
| 14 | 128MB t3 | 128 | 3 | 1 | — | — | — | 🔴 CRASH |
Teto real do isolate
| Dimensão | Limite encontrado |
|---|---|
| Memória máxima viável | 128 MB (50% da RAM do isolate) |
| Iterações máximas a 64MB | 4 (t=5 crashou) |
| Iterações máximas a 128MB | 2 (t=3 crashou) |
| Produto m×t máximo seguro | ~260.000 KB·iter |
Configuração de produção escolhida
m = 131.072 KB (128 MB) | t = 2 | p = 1
Tempo médio: 378ms | 19% do CPU budget
Resistência: 6,7× OWASP mínimoConfigurações testáveis
p=1porque isolates Deno são efetivamente single-thread;p>1gasta CPU sem paralelismo real.
Critérios de avaliação
| Classificação | Critério |
|---|---|
| 🟢 VIÁVEL | avg_ms < 800 e todas as runs com sucesso |
| 🟡 MARGINAL | avg_ms entre 800 e 1500, todas com sucesso |
| 🔴 INVIÁVEL | avg_ms > 1500 ou qualquer run com falha |
Regra: escolher a configuração com maior m que seja VIÁVEL.
Como executar
Via script local (recomendado)
bash
# Windows CMD
set SUPABASE_URL=https://mjvuzsizjlcalyfmbquy.supabase.co
set CRON_SECRET=<valor do Supabase Secrets>
node scripts/benchmark-argon2.mjsO script:
- Chama a Edge Function diretamente no Supabase (bypassa Cloudflare Worker)
- Autentica via header
X-Cron-Secret - Imprime tabela resumida no terminal
- Salva JSON completo em
scripts/resultados/benchmark-argon2_<timestamp>.json
Flags CLI
| Flag | Exemplo | Descrição |
|---|---|---|
--m=<KB> | --m=131072 | Memory cost em KB |
--t=<N> | --t=2 | Time cost (iterações) |
--p=<N> | --p=1 | Parallelism (default: 1) |
--runs=<N> | --runs=5 | Quantidade de runs (default: 3) |
--all | --all | Roda todas as 7 configs padrão |
--help | --help | Mostra ajuda |
Exemplos de uso
bash
# Testar a config de produção
node scripts/benchmark-argon2.mjs --m=131072 --t=2
# Testar com mais runs para maior precisão
node scripts/benchmark-argon2.mjs --m=131072 --t=2 --runs=10
# Rodar todas as 7 configs padrão
node scripts/benchmark-argon2.mjs --allSegurança
- Admin logado: autenticação via cookie
olp_auth+requireRole('administrador') - Script local: autenticação via header
X-Cron-Secret(mesmo padrão dos cron jobs) - Sandbox/CI: autenticação via
Authorization: Bearer <SERVICE_ROLE_KEY> - Endpoint não é público — sempre requer uma das autenticações
Proposta de Cache (Upstash Redis)
Para evitar re-computar Argon2id em restaurações de sessão:
- Upstash Redis Free Tier: 10.000 cmd/dia, 256MB, $0/mês
- Cache armazena session ID opaco (nunca senhas/hashes)
- Cache HIT: ~50ms | Cache MISS: ~435ms (hash completo)
- Detalhes:
docs/security/PASSWORD_HASHING_ARCHITECTURE.md
Arquivo da Edge Function
supabase/functions/benchmark-argon2/index.ts