Autenticação
Como a sessão chega à API (cookie host-only ou Bearer) e o que ainda está em reconstrução.
O login ainda está em reconstrução: nenhuma rota emite sessão hoje e toda rota protegida responde 401. Esta página descreve o que já está no código (NOVA-118), não o desenho do login.
Estado atual
- Os endpoints antigos de login, sessão e refresh foram removidos.
- Toda rota protegida passa por
AuthenticateSession, que pede a umSessionResolverpara transformar o token da sessão em sessão. Em produção, o resolver ligado não resolve nada, então toda rota protegida responde 401. - Rotas públicas continuam funcionando:
/health,/ready,/docse/openapi.json. - Cabeçalhos como
x-tenant-id,x-user-idex-systemnunca estabelecem identidade nem autoridade. - Os testes da API autenticam com um resolver falso (
FakeSessionResolver), que apresenta o token como Bearer ou como cookie.
De onde vem o token da sessão
A API aceita o token de duas fontes. O contrato OpenAPI declara os dois esquemas, Bearer e SessionCookie, como
alternativas em toda rota protegida.
| Fonte | Para quem |
|---|---|
Cookie __Host-monalisa_session | O navegador: o cookie é HttpOnly, então o site nunca guarda o token |
Authorization: Bearer <token> | Os demais clientes |
O Bearer vence. Regras de leitura:
- O esquema
Beareré reconhecido sem diferenciar maiúsculas; token vazio ou com mais de uma parte recebe 401 antes de qualquer consulta. - Um
Authorizationcom outro esquema (por exemplo, Basic acrescentado por um proxy) não é fonte de sessão: é ignorado, e o cookie continua autenticando. - Se a requisição manda Bearer e cookie com tokens diferentes, recebe 401: os dois nomeiam sessões diferentes.
- Uma credencial grande demais recebe 401. Tokens nunca aparecem em mensagens de erro, detalhes ou logs.
O cookie
Por padrão o cookie é host-only: __Host-monalisa_session, com HttpOnly; Secure; SameSite=Lax; Path=/ e sem
Domain. O prefixo __Host- faz o navegador recusar qualquer cópia com Domain ou com Path mais estreito, então um
subdomínio vizinho não consegue plantar um cookie que esconda o verdadeiro. O site e a API ficam sob o mesmo site
registrável, então o fetch com credenciais do site já leva o cookie host-only da API.
- Duplicatas. Um cabeçalho
Cookieque traz o nome do cookie de sessão mais de uma vez recebe 401, porque uma cópia plantada venceria em silêncio. SESSION_COOKIE_DOMAIN(opcional). Só para um consumidor do lado do servidor confirmado num host vizinho (como SSR que repassa o cookie). O cookie passa a se chamar__Secure-monalisa_session, com esseDomain, e chega a todos os subdomínios. O valor precisa ser um host simples, em minúsculas, com pelo menos dois rótulos e que não seja um sufixo público conhecido; senão a API não sobe.- A definição do cookie (nome e atributos) existe num lugar só, e o esquema
SessionCookiedo OpenAPI tira o nome dela.
Escritas com cookie exigem origem exata
Um POST, PUT, PATCH ou DELETE autenticado pelo cookie precisa trazer um Origin (ou, sem ele, um Referer)
cuja origem esteja exatamente listada em CORS_ORIGINS. Sem isso, recebe 403 antes de a sessão ser resolvida.
- Requisições com Bearer e requisições
GET,HEADeOPTIONSnão passam por essa checagem. Uma página estranha não consegue mandarAuthorization, porque o preflight de CORS dela não recebeAccess-Control-Allow-Origin. - Com
CORS_ORIGINSvazio (o padrão), toda escrita autenticada por cookie recebe 403. Uma implantação em que o site e a API dividem o mesmo host também precisa listar a própria origem. - O site não deve contar com
Referrer-Policy: no-referrerpara clientes que omitemOrigin.
CORS
Ambientes que usam o cookie definem CORS_CREDENTIALS=true e listam as origens exatas do site em CORS_ORIGINS; a
mesma lista alimenta o CORS e a checagem de origem. A API não sobe com CORS_CREDENTIALS=true e CORS_ORIGINS vazio, e
recusa * ou qualquer origem que não seja exata, em qualquer ambiente. Staging ainda usa CORS_CREDENTIALS=false até o
login emitir cookies.
O que já existe no banco
O schema de identidade continua no baseline: users, user_logins (por tenant), platform_logins (operador de
plataforma, sem tenant), user_credentials, sessions, refresh_tokens, session_memberships,
session_membership_brokers e session_contexts. Nenhuma rota grava sessões hoje. O primeiro operador de plataforma é
criado pelo bootstrap, mas ainda não tem como fazer login.
Ver Identity para as tabelas.