Checklist de implementação: SSO via SAML num SaaS que já tem login próprio

Escrito por

em

O contrato enterprise trava na cláusula de autenticação: o cliente quer que os funcionários entrem pelo provedor de identidade corporativo e o produto só sabe validar e-mail e senha na própria tabela de usuários. A tentação é resolver isso como um recurso de tela de login. Não é. SSO via SAML mexe no modelo de dados, no ciclo de vida da conta, na política de sessão e no offboarding — e a maior parte dos incidentes pós-lançamento vem de decisões tomadas antes de qualquer XML ser assinado.

O roteiro abaixo cobre a implementação em um SaaS multi-tenant que já roda em produção com autenticação própria. A ordem importa: cada bloco assume o anterior resolvido.

O modelo de dados precisa mudar antes do primeiro XML

Autenticação local costuma guardar identidade e credencial na mesma linha. O e-mail identifica o usuário, o hash da senha o autentica, e o sistema trata os dois como a mesma coisa. SAML quebra essa fusão: quem autentica é o provedor de identidade, quem identifica é um atributo que o provedor envia — e esse atributo pode não ser o e-mail.

Três estruturas precisam existir antes de qualquer coisa:

  • Conexão de identidade por organização, não por usuário. Cada tenant tem no máximo uma conexão ativa, contendo entity ID do provedor, URL de SSO, certificado público de assinatura e o mapa de atributos.
  • Identificador externo estável no usuário, separado do e-mail. O NameID persistente ou o objectGUID do diretório sobrevive a troca de sobrenome, mudança de domínio e reorganização interna. O e-mail não sobrevive a nenhuma das três.
  • Método de autenticação por usuário, com valores como senha, saml ou ambos. Sem esse campo não há como fazer a migração gradual descrita adiante.

Guardar o certificado do provedor com data de expiração explícita, e não só o PEM cru, poupa o incidente mais previsível dessa integração: o certificado do cliente vence, todo mundo da conta perde acesso ao mesmo tempo e o suporte descobre pelo chamado. Um job diário que compara a data de expiração com a data atual e dispara alerta com trinta e sete dias de antecedência custa uma tarde e evita a ligação de sábado.

Descoberta de provedor: o passo que degrada a experiência quando é feito errado

Com login local, o usuário digita e-mail e senha na mesma tela. Com SSO, o sistema precisa descobrir para qual provedor redirecionar antes de pedir credencial nenhuma — e essa descoberta acontece com a única informação disponível: o e-mail digitado.

O padrão que funciona é o formulário em dois passos. A primeira tela pede apenas o e-mail. O backend extrai o domínio, consulta a tabela de domínios verificados por organização e decide: se há conexão SAML ativa, redireciona para o provedor; se não há, mostra o campo de senha. O usuário de conta pessoal continua com a experiência de sempre; o usuário corporativo nunca vê um campo de senha que não usa mais.

Verificar o domínio é obrigatório e não é burocracia. Sem prova de posse — registro TXT no DNS ou arquivo servido em caminho conhecido — qualquer conta pode reivindicar um domínio alheio e sequestrar o fluxo de login de outra empresa. A verificação precisa ser revalidada periodicamente, porque domínio expira e muda de dono.

Sobre o fluxo iniciado pelo provedor, aquele em que o usuário clica no ícone do aplicativo dentro do portal corporativo: ele é o que os clientes pedem e o que a equipe de segurança deveria resistir a entregar primeiro. Sem RelayState validado e sem correlação com uma requisição de origem, a aplicação recebe uma asserção não solicitada e precisa confiar nela sem contexto. Se for entregue, que seja depois do fluxo iniciado pelo provedor de serviço estar estável, com lista estrita de destinos permitidos no RelayState.

Validar a asserção não é só conferir a assinatura. Antes de criar sessão, checar em sequência: assinatura contra o certificado daquela organização específica; Destination igual à URL de callback real; Audience igual ao entity ID do produto; NotBefore e NotOnOrAfter dentro da janela com tolerância de relógio de poucos minutos; InResponseTo correspondendo a uma requisição registrada; e o ID da asserção ainda não consumido, guardado em cache de uso único até o fim da validade. Pular a última checagem transforma uma asserção capturada em replay válido.

Provisionamento: JIT resolve a entrada, SCIM resolve a saída

Provisionamento just-in-time cria ou atualiza o usuário no momento em que a asserção chega. É simples de implementar, não exige que o cliente configure nada além da conexão e cobre o caso comum de funcionário novo que precisa acessar hoje.

O problema do JIT é o inverso: ele não sabe nada sobre quem saiu. Um funcionário desligado no diretório corporativo continua com usuário ativo no produto até alguém lembrar de removê-lo. Para produtos que guardam dado sensível, isso é achado de auditoria garantido.

Critério JIT via SAML SCIM
Esforço de implementação Baixo — aproveita o fluxo de login Alto — API REST completa de usuários e grupos
Criação de conta No primeiro acesso Antes do primeiro acesso
Desligamento Não detecta Desativa em minutos
Sincronia de grupos e papéis Só o que vem na asserção, a cada login Contínua, incluindo remoção de grupo
Exige configuração do cliente Mínima Token, endpoint e mapeamento no diretório

A escolha prática: entregar JIT primeiro e tratar SCIM como item de roadmap com gatilho comercial claro — o primeiro cliente que colocar desprovisionamento automático em requisito de contrato. Enquanto SCIM não existe, o mitigante honesto é sessão curta para contas SAML, com revalidação contra o provedor a cada poucas horas em vez de token de trinta dias. Não é equivalente a desprovisionamento, mas reduz a janela de exposição de semanas para horas.

Sobre mapear papéis a partir de grupos do diretório: funciona, e é o que o cliente vai pedir. O cuidado é definir precedência explícita. Se o papel vem do grupo, um administrador que perde o grupo deve perder o papel no login seguinte — inclusive o último administrador da conta. Deixar uma conta sem nenhum administrador por causa de mudança de grupo é o tipo de bug que só aparece em produção. Reservar ao menos um papel de administrador imune ao mapeamento resolve.

A senha que já existe é o maior risco do projeto

Ligar SAML é fácil. Desligar o que existia é onde o projeto trava. Uma organização com centenas de usuários ativos tem sessões abertas, tokens de API emitidos, convites pendentes, integrações que autenticam com credencial de serviço e pelo menos uma pessoa que entra por link salvo direto no formulário de senha.

O caminho que funciona tem três estágios controlados por configuração da organização, não por deploy:

  • SSO opcional. Os dois métodos convivem. Serve para a organização validar o mapeamento de atributos com usuários reais antes de comprometer o acesso de todo mundo.
  • SSO obrigatório com exceções. O login por senha é bloqueado para os usuários do domínio verificado, com lista curta de exceções nominais — tipicamente contas de serviço e o administrador que configurou a conexão.
  • SSO exclusivo. Nenhuma exceção. Só entra aqui a organização que já validou o estágio anterior por algumas semanas.

Duas armadilhas específicas. A primeira: ao tornar o SSO obrigatório, as sessões já ativas continuam válidas — o usuário só descobre o problema quando a sessão expira, possivelmente semanas depois, e o suporte recebe o chamado descolado da mudança. Invalidar as sessões existentes no momento da troca de estágio é mais gentil do que parece. A segunda: tokens de API pessoais emitidos antes da migração sobrevivem ao bloqueio de senha e são, na prática, uma porta paralela. Ou eles são revogados junto, ou o cliente que pediu SSO obrigatório recebeu menos do que acha que comprou.

Convites pendentes precisam de tratamento próprio. Um convite emitido antes da conexão existir leva a um formulário de definição de senha que não faz mais sentido. Reescrever o destino do convite no momento em que a conexão é ativada evita o suporte previsível de segunda-feira.

Checklist de corte

O que precisa estar verificado antes de liberar a conexão para a primeira organização real, em ordem de execução:

  • Certificado do provedor armazenado com data de expiração e alerta agendado.
  • Suporte a dois certificados simultâneos na mesma conexão, para o cliente rotacionar sem janela de indisponibilidade.
  • Domínio verificado por DNS, com revalidação periódica agendada.
  • Validação completa da asserção, incluindo cache de uso único do ID.
  • Tolerância de relógio configurada e monitorada — divergência de horário é a causa mais comum de falha intermitente que não reproduz em teste.
  • Tela de erro que diz qual validação falhou, em linguagem que o administrador do cliente entende, sem expor conteúdo da asserção.
  • Log de auditoria com organização, identificador externo, provedor, resultado e motivo da falha — retido pelo prazo que o contrato exige.
  • Caminho de recuperação documentado para quando o provedor do cliente cai: quem pode reativar login por senha, com qual aprovação e em quanto tempo.
  • Teste de carga no endpoint de callback. Ele recebe rajada no início do expediente, quando a empresa inteira chega ao mesmo tempo.

O último item da lista é o que costuma faltar. Uma conexão SAML transfere a disponibilidade do login para um sistema que não é o seu, operado por um time que você não conhece, com janela de manutenção que ninguém avisa. O plano de contingência não é opcional — e precisa estar escrito antes do primeiro cliente depender dele, porque escrever procedimento de emergência durante a emergência é como esse projeto vira post-mortem.

Comentários

Deixe um comentário

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *