Todo mundo que já integrou login "na mão" sabe onde dói: OAuth2 mal configurado, tokens que vazam, e um IdP de terceiros que cobra por assento ou some com uma feature no próximo release. Cansamos disso e construímos o Curupira.

Por que diabos construir o próprio IdP
Autenticação é daquelas coisas que ninguém quer reinventar até precisar. Nosso caso era multi-tenant: várias aplicações, cada uma com seus usuários, papéis e regras. As opções prontas ou eram caras por assento, ou nos prendiam a decisões que não controlávamos. Construir o próprio IdP é assumir uma responsabilidade séria, mas nos deu o que faltava: controle total sobre chaves, tokens e política de segurança. O Curupira é um Identity Provider OAuth2 + OpenID Connect, pronto para produção, com issuer padrão em auth.dwcorp.com.br e licença MIT.
Rust não foi escolha de hype
Escrever um IdP em Rust parece exibicionismo até você lembrar o que um IdP faz: manipula segredos, valida tokens e roda no caminho crítico de toda requisição autenticada. Aqui a garantia de memória e a ausência de surpresas em runtime pagam a conta. A stack é Rust + Cargo, com PostgreSQL via SQLx — o que significa queries checadas em tempo de compilação e migrations versionadas. Se a query quebra, quebra no build, não às três da manhã em produção.
PKCE obrigatório e zero atalhos de segurança
A escolha que mais define o Curupira: PKCE é obrigatório. Não é opcional, não tem flag para desligar. Fluxo Authorization Code com PKCE S256 (RFC 7636) para todo mundo, cliente público ou não. Somamos a isso senhas com Argon2id, proteção CSRF, e endpoints de token e introspecção protegidos por API key. O projeto segue a RFC 9700, a BCP de segurança de OAuth2 — ou seja, as boas práticas atuais, não o que era aceitável em 2015. A ideia é simples: tornar o caminho seguro o único caminho.
Multi-tenant de verdade: uma chave RSA por aplicação
Multi-tenant costuma ser um adjetivo de marketing. No Curupira é arquitetura: cada aplicação tem seu próprio par de chaves RSA. Os JWTs são assinados em RS256, com rotação de chaves. Isso significa que comprometer ou rotacionar a chave de uma aplicação não contamina as outras. Em cima disso roda um RBAC com papéis específicos por aplicação e grupos de papéis, para você modelar permissões sem transformar cada tenant num caso especial. Discovery OIDC, ID tokens, UserInfo, introspecção e logout estão todos ali.
Compatível com FusionAuth, com log em três camadas
Uma decisão pragmática: o Curupira foi desenhado para ser compatível com o FusionAuth. Isso reduz atrito para quem já vem desse mundo e nos dá um vocabulário conhecido em vez de inventar o nosso. Observabilidade também não ficou de fora — são três camadas de log: tentativas de login, event logs e audit logs. Quando algo dá errado numa autenticação, dá para reconstruir o que aconteceu. E, a partir da v0.8, há um dashboard administrativo feito em Nuxt.js (Vue) com @nuxt/ui, porque gerenciar tenant e chave no grito de comando cansa rápido.
O que já roda e o que ainda vem
Sejamos honestos: o Curupira é um produto em evolução. As fases 0 e 1 — infraestrutura e gestão de tenants — estão prontas. As fases 2 a 5 estão no mapa: gestão de aplicações, usuários e papéis, logging e monitoramento, MFA, verificação de e-mail e webhooks. É um roadmap por fases justamente porque preferimos entregar cada camada bem-feita a empurrar tudo de uma vez e rezar.
Autenticação é chata quando funciona e catastrófica quando não. Construir o Curupira foi apostar que valia a pena ter esse pedaço crítico sob nosso controle — em Rust, com PKCE obrigatório e uma chave por tenant. Até agora, a aposta está de pé.



