O single sign-on é um padrão consolidado há mais de vinte anos, mas SAML continua sendo o item que trava um contrato ou obriga a ligar para o time de vendas. Como a autenticação corporativa virou um upsell premium, quem construiu esse mundo e quem nos avisou, qual é o tamanho real desse fosso competitivo e do que ele é feito, e a força que hoje drena metade dele em silêncio.
A monitorização só corre durante um desastre. Por isso construímos um banco de ensaio que envia um sinal real para cada regra de alerta e só passa quando a notificação chega fisicamente a um relé de captura. A primeira execução encontrou o nosso alerta principal de taxa de erros morto, e depois algo pior: uma definição de retenção tinha marcado em silêncio os nossos registos para expirarem de imediato, deixando toda uma classe de alertas a avaliar sobre o nada.
Cem megabytes de capturas de tela foram para o Cloudflare R2, atrás de uma base de CDN que a app deduz em tempo de execução do nome de host. No navegador tudo funcionava, mas o tráfego da origem não mudou: as páginas que um rastreador vê são pré-renderizadas em 127.0.0.1, onde um nome de host não diz nada. A solução: um marcador que o HTML leva para fora do build e que o edge preenche por requisição, imposta por um sistema de arquivos somente leitura.
O provisionamento just-in-time estava ativado por padrão, de modo que um provedor de identidade federado podia criar contas no tenant de um cliente apenas afirmando que alguém existia. Desativar esse padrão é uma mudança de uma única palavra. Desativá-lo sem mudar silenciosamente o comportamento de cada conexão já armazenada, nenhuma das quais jamais escreveu a coluna, é o verdadeiro problema, e o truque que o resolveu também explica por que um padrão é superfície de API.
Um backend-for-frontend tira os tokens OAuth do navegador e não lhe deixa nada além de um cookie opaco. Servir muitos inquilinos a partir de um único BFF é sobretudo um problema de encanamento, até que chega o logout back-channel: um POST de servidor para servidor sem cookie, sem sessão e sem navegador, onde a única coisa que identifica o inquilino é um claim dentro de um token que você ainda não verificou.
Adicionamos ao nosso cluster Kubernetes um webhook de admissão que verifica assinaturas, para que nenhuma imagem sem assinatura pudesse jamais rodar. Horas depois, um Deployment tinha 2.242 ReplicaSets, um novo a cada três segundos e nenhum pod disponível. Os logs do webhook mostravam que ele admitia cada uma das requisições. O dano veio da única palavra em "mutating admission webhook" que tínhamos deixado de ler.
Um usuário recorrente via "Carregando…" por exatamente dez segundos antes de o login aparecer, sempre. O número redondo era a pista: nossa biblioteca de SSO abria um iframe oculto de silent-renew contra um host de autenticação que servia X-Frame-Options: DENY e frame-ancestors 'none', então o frame nunca carregava, nunca dava erro, e a biblioteca esperava todo o seu timeout. Defesa contra clickjacking e silent renew de OIDC, cada um correto, travaram na costura entre eles.
Encriptámos todos os e-mails em repouso e a caixa de pesquisa do admin deixou silenciosamente de autocompletar: sem erro, sem log. Um blind index restaura a procura exata sobre texto cifrado, mas o trabalho do HMAC é destruir a ordenação de que a pesquisa por prefixo precisa. Eis o design que trouxe o type-ahead de volta (indexar cada prefixo como um valor próprio) e as três armadilhas que mostraram que a encriptação pesquisável é um problema de sistemas, não de criptografia.
Migramos a assinatura de JWT de RS256 para ES256 e cada token que emitimos era criptograficamente válido, e mesmo assim rejeitado. Três vezes, por três motivos diferentes: DER onde o JWS quer R‖S bruto, preenchimento de inteiros que falha em um token a cada 128, e um dialeto de base64 que mudou debaixo dos nossos pés. Veja como ler os bytes estragados e apontar a camada culpada apenas pelo comprimento da assinatura.
Os dois documentos que um serviço lê para validar um dos nossos JWTs — o documento de discovery e o JWKS — são as coisas mais requisitadas e menos secretas que servimos, e cada busca costumava percorrer todo o caminho de volta até a origem. Colocá-los em cache no Cloudflare foi a parte fácil. A parte difícil é que um cache de chave pública desatualizado jamais pode rejeitar um token válido — e aqui está a ordem segura para rotação que torna seguro um JWKS agressivamente colocado em cache.
O plano LITE do Duende custa $5,750/yr, mas limita a 2 client apps e não entrega SAML nenhum. No momento em que você precisa de SSO corporativo ou de um terceiro app, já está no STANDARD, a $12,500. Uma análise do que o Duende realmente custa a um produto de verdade, e do imposto sobre número de clients que ninguém te avisa.
Uma única chave privada assina todos os tokens que o nosso servidor de autenticação emite, e ela se mudou duas vezes ao longo da vida: nasceu dentro do processo, foi exilada para um cofre do qual não consegue sair e depois reencarnou como um tipo de chave completamente diferente, menor e mais rápido. Cada mudança aconteceu num emissor em produção, com tokens em trânsito.
Seu SP validou a assinatura da asserção, fixou o certificado e autenticou o usuário. Todas as verificações passaram. Mesmo assim, reproduzi um login que capturei uma hora atrás. O truque não foi quebrar a assinatura. Foi apagar um campo que a assinatura nunca cobriu.
Desafiamos o segundo fator na página de login e nunca o verificamos de novo no token endpoint. Então uma senha válida mais uma URL de retorno editada à mão passou direto pela MFA. A correção, e a regra que ela nos ensinou: MFA é uma propriedade da sessão que você emite, não uma etapa na tela de login.
O SCIM é uma API CRUD padronizada cujo verbo mais importante é o que desativa a conta de um ex-funcionário. Os fornecedores cobram $125 por mês por conexão, ou o escondem no plano enterprise ao lado do SSO. Eis o que uma conexão SCIM realmente custa para operar, e por que cobrar pelo desprovisionamento é cobrar pela segurança.
O Azure Table Storage e o DynamoDB não têm marcadores de exclusão, então uma linha apagada simplesmente some, o que significa que seu backup incremental nunca chega a ver a exclusão. Restaure esse backup e o usuário que você desligou está de volta, com a senha que você já tinha rotacionado. Eis por que exclusões precisam ser cidadãs de primeira classe, e a tabela que as torna assim.
Nosso rate limiter e o contador de bloqueio de conta usavam o IP do cliente como chave. Atrás do nginx, esse IP vinha de um header que o cliente podia definir, então um header rotativo dava a cada request um IP novo e todo controle por IP caía. O spoof de uma linha, e a correção que é mais chata do que parece no Kubernetes.
O Azure Table Storage te dá uma partition key, uma row key e quase nada mais. Sem joins, sem índices secundários que mereçam o nome, sem incremento. Mesmo assim, rodamos um sistema de autenticação multi-tenant em cima dele. Os padrões que fazem isso funcionar, e o que você abre mão em relação ao SQL.
Um endpoint de redefinição de senha não autenticado e sem limite de taxa por e-mail não é só problema seu. Aponte-o para a caixa de entrada de outra pessoa e você transformou o formulário de redefinição dela em um canhão de spam, cobrado na conta da sua reputação de remetente. A correção, sem revelar quais e-mails têm conta.
A maioria dos fornecedores de autenticação cerca SSO, SCIM, MFA e logs de auditoria atrás de um plano Enterprise. Nós colocamos tudo isso no plano de $0. Aqui está a economia unitária que torna sustentável dar recursos de graça: o muro nunca foram os recursos, e sim usuários ativos e suporte.
O login único significa confiar no provedor de identidade. Confiamos nele em uma coisa a mais: resolvíamos os usuários federados recorrentes pelo e-mail da asserção, de modo que qualquer conexão podia afirmar o endereço de outra pessoa e cair na conta dela. A correção não foi mais validação. Foi mudar a chave de junção de identidade, do e-mail para um subject próprio de cada provedor que a parte que afirma não consegue falsificar.
O Azure Container Apps prometia que deixássemos de pagar por um cluster de autenticação ocioso. Calculamos o custo da migração e a descartamos, não por preço nem por cold starts, mas porque falta ao serverless o único número de que uma backplane de autenticação com eleição de líder realmente precisa.
O "imposto de funcionalidade" como uma fatura real. Três cenários de comprador (primeiro contrato enterprise, um punhado de clientes, SSO como requisito básico) calculados frente às tarifas públicas de cada fornecedor. Mais a sobretaxa silenciosa que ninguém avisa: ficar sem clientes OAuth no meio da integração.
Um cluster de três réplicas vivia em desacordo consigo mesmo. A causa estava no nosso próprio código: a rotina de descoberta de pares tinha um bloco catch que desativava a descoberta quando o multicast falhava, e em Kubernetes gerenciado o multicast sempre falha. Eis por que apagamos o gossip por completo e elegemos um líder com um blob lease no lugar, e por que uma associação que você pode abrir no Storage Explorer vence uma associação que você precisa inferir.
Login é um fim de semana. A conta chega depois: verificação de assinatura, desprovisionamento SCIM, MFA, logs de auditoria, rotação de chaves, responsabilidade por vazamentos e plantão para um sistema de nível zero. Um comparativo honesto entre construir e comprar, incluindo quando construir é a escolha certa.
OIDC ou SAML? Você raramente pode escolher. O que é cada protocolo, quando cada um vence, as armadilhas da assinatura XML que tornam o SAML perigoso de implementar à mão e por que um produto B2B acaba precisando dos dois.
O sistema de suporte da Authagonal: mensagens em tempo real sem recarregar, tradução por IA transparente nos dois sentidos, fixada desde a primeira mensagem do cliente, e uma conversa que continua totalmente traduzida até por e-mail. Simples, bonito e de fato capaz.
Dois dos nossos tenants eram, silenciosamente, o mesmo tenant: mesmo banco de dados, mesma chave de assinatura de tokens, nomes diferentes. A causa foi um helper de uma linha que higienizava slugs removendo hífens, transformando um identificador único em um identificador não único. Aqui está como uma transformação de string com perda virou um sequestro entre tenants, e por que nós encontramos isso antes de você.
Vendemos autenticação, por isso o nosso teste mais importante é um que se torna num cliente: uma única execução do Playwright que inscreve um tenant, configura todas as funcionalidades, aponta uma app real para ele, autentica um utilizador real com os claims certos, e depois copia, restaura e elimina-se a si próprio. Como o teste exaustivo de ponta a ponta conquistou a nossa confiança para entrar em produção.
O nosso console de equipe autentica-se através da própria Authagonal, com o Entra SSO e o SCIM a tratar do provisioning. Ser o seu próprio cliente faz emergir os casos extremos que nenhuma suíte de testes pensa em escrever. Eis os que importaram.
O seu estado do Terraform é um mapa completo da sua cloud mais um monte de segredos, e por omissão vive atrás de um endpoint público. Eis como inicializámos o estado remoto a partir do zero, o colocámos atrás de um endpoint privado e lhe chegámos através de um conector zero-trust em vez de pagar o imposto da gateway de VPN, sem nunca nos trancarmos do lado de fora.
"Todo mundo redefine a senha" é uma escolha de migração, não uma lei da física. Como levar os hashes de senha existentes dos seus usuários numa troca de provedor de identidade para que a virada seja invisível, e o único caso em que você realmente não consegue.
O setor da autenticação cobra pela permissão, não pelo custo. Tranca o SSO, o MFA e o aprovisionamento atrás de níveis e tarifas por ligação, por funcionalidades cuja disponibilização não custa praticamente nada. Esta é a distinção que as páginas de preços esperam que você nunca trace.
Migrando do Duende IdentityServer auto-hospedado para auth gerenciada: o que de fato migra da configuração SQL e do ASP.NET Identity, e o custo operacional que você deixa de carregar.
Um olhar prático sobre o que uma migração do Auth0 realmente envolve: o que é fácil, o que é complicado e a única coisa que o Auth0 genuinamente não vai te dar.