> ## Documentation Index
> Fetch the complete documentation index at: https://docs.cativa.digital/llms.txt
> Use this file to discover all available pages before exploring further.

# Login federado (IdP da empresa)

> Deixe os membros entrarem na comunidade Cativa com o IdP da própria empresa (Google Workspace, Microsoft Entra, Okta, Keycloak ou um OIDC custom). Aqui a Cativa é o Relying Party.

Este guia é o **inverso** de [Login com a Cativa](/pt-BR/guides/sign-in-with-cativa).

* Em *Login com a Cativa*, a **Cativa é o IdP**: um app de terceiro autentica o usuário usando a conta da comunidade.
* Aqui, a **empresa é o IdP**: os membros entram na comunidade Cativa usando o sistema de login que a empresa já tem. A Cativa age como **Relying Party** e federa para o IdP do cliente.

Use isto quando a comunidade pertence a uma organização que já tem um diretório de identidade (Google Workspace, Microsoft Entra/Azure AD, Okta, Auth0, Keycloak, ou qualquer provedor OIDC) e os membros não devem criar uma senha separada.

<Info>
  Quer testar sem ter um IdP real? O repo [`cativa-sso`](https://github.com/cativalab/cativa-sso) traz um IdP OIDC **mock** pronto pra rodar na pasta `cliente-idp` (Node + Express): discovery, JWKS RS256, `authorize`/`token`/`userinfo`. Suba ele atrás de um túnel público e registre como provedor pra exercitar o fluxo ponta a ponta.
</Info>

## Como funciona

```mermaid theme={null}
sequenceDiagram
    autonumber
    actor U as Membro (browser)
    participant Cativa as Cativa (Relying Party)
    participant IdP as IdP da empresa
    participant FE as Frontend da comunidade

    U->>Cativa: "Entrar com a conta da empresa"<br/>/sso/external/{customer}/{slug}/authorize
    Cativa->>IdP: 302 /authorize<br/>client_id, redirect_uri, state
    U->>IdP: Autentica (login da empresa)
    IdP-->>Cativa: 302 /sso/external/{customer}/callback?code=&state=
    Cativa->>IdP: POST /token (troca o code)
    IdP-->>Cativa: id_token
    Cativa->>IdP: GET /jwks (valida a assinatura)
    Note over Cativa: valida state, extrai email,<br/>vincula ou auto-provisiona o usuário
    Cativa->>FE: 302 já logado na comunidade
```

A Cativa valida a assinatura do `id_token` (via JWKS do provedor), confere o `audience` (o seu `client_id`) e exige a claim `email`. No primeiro login, se **auto-provisionamento** estiver ligado, o usuário é criado na comunidade a partir dos dados do IdP.

## Pré-requisitos

1. **Um app OAuth/OIDC no seu IdP** — crie um client no provedor da empresa e anote `client_id` e `client_secret`.
2. **A URL de callback da Cativa, registrada no seu IdP** como redirect URI autorizada. Você não precisa montá-la na mão: ao abrir o formulário de Identity Provider no admin da Cativa (próxima seção), ele mostra a **URL de callback exata, com o seu slug já preenchido**, e um botão **Copiar**. Cole esse valor no client do seu IdP. O formato é:

   ```
   https://apis.cativalab.digital/tenant/api/v2/sso/external/{customerName}/callback
   ```

   `{customerName}` é o slug da sua comunidade — o subdomínio público da Cativa (`https://{customerName}.cativa.digital`). É fixo por tenant, e o admin que está configurando já o conhece (é a comunidade dele). Na dúvida, copie a URL que o formulário mostra em vez de digitar o slug você mesmo.
3. **Acesso de admin** à comunidade Cativa para cadastrar o provedor.

## Cadastrar o Identity Provider

No admin da comunidade, em **Integrações → SSO → Provedores → Novo provedor**, escolha o preset do seu IdP (Google, Microsoft, Okta, Auth0, Keycloak) ou **Custom (OIDC)** e preencha:

<Steps>
  <Step title="Discovery">
    Cole a **Metadata URL** (o `.well-known/openid-configuration` do seu IdP) e clique em **Buscar configuração** — a Cativa preenche `authorize`/`token`/`userinfo`/`jwks` sozinha. (Em provedores sem discovery, informe os endpoints manualmente.)
  </Step>

  <Step title="Credenciais">
    Informe `Client ID` e `Client Secret` do client que você criou no IdP, e os `Scopes` (no mínimo `openid email profile`).
  </Step>

  <Step title="Provisionamento">
    Ligue **Auto-provisionar** para criar o usuário no primeiro login, e escolha a **Role padrão** (Usuário ou Admin). Sem auto-provisionar, só usuários já existentes (e vinculados) conseguem entrar.
  </Step>

  <Step title="Slug">
    Defina um **slug** (ex.: `empresa`) — ele entra na URL de início do login federado.
  </Step>
</Steps>

<Note>
  Mantenha **apenas um** provedor habilitado durante os testes. O callback identifica o provedor por um cookie setado no início; com vários provedores habilitados e o cookie ausente, a identificação fica ambígua.
</Note>

## Disparar o login

Aponte o botão "Entrar com a conta da empresa" para:

```
https://apis.cativalab.digital/tenant/api/v2/sso/external/{customerName}/{slug}/authorize
```

A Cativa redireciona para o IdP da empresa, recebe o `code` no callback, valida o `id_token`, vincula/auto-provisiona o usuário e redireciona o browser de volta para a comunidade **já autenticado**.

## O que o IdP precisa devolver

* Um `id_token` assinado, validável pelo `jwks` do provedor (a Cativa busca a chave pública do discovery/JWKS).
* A claim **`email`** é obrigatória — é a chave de identidade. Sem ela o login é recusado.
* `given_name` / `family_name` / `picture` são usados (quando presentes) ao auto-provisionar o usuário.

## Erros comuns

<AccordionGroup>
  <Accordion title="`Estado inválido ou expirado` no callback">
    O cookie anti-CSRF (`sso_state`) não voltou. Garanta que o IdP redirecionou para a **mesma** URL de callback registrada (`.../tenant/api/v2/sso/external/{customerName}/callback`, com o prefixo completo) e que o fluxo foi concluído dentro de 10 minutos.
  </Accordion>

  <Accordion title="`O provedor não retornou um email válido`">
    O `id_token` veio sem a claim `email`. Ajuste os scopes/claims no client do seu IdP para incluir `email` (e `email_verified` quando aplicável).
  </Accordion>

  <Accordion title="`Provedor de identidade não identificado`">
    Há mais de um provedor habilitado e o cookie de identificação se perdeu. Deixe só um habilitado, ou inicie sempre pela URL `/sso/external/{customerName}/{slug}/authorize` (com o `slug` correto).
  </Accordion>

  <Accordion title="`Token de identidade inválido`">
    A assinatura do `id_token` não validou, ou o `audience` não bate. Confira que o `Client ID` cadastrado é o mesmo `aud` que o IdP emite, e que a Metadata URL aponta para o JWKS certo.
  </Accordion>
</AccordionGroup>

## Próximos passos

<CardGroup cols={2}>
  <Card title="Login com a Cativa" icon="arrow-right-to-bracket" href="/pt-BR/guides/sign-in-with-cativa">
    O fluxo inverso: a Cativa como IdP para apps de terceiro.
  </Card>

  <Card title="IdP de exemplo (GitHub)" icon="github" href="https://github.com/cativalab/cativa-sso">
    A pasta `cliente-idp` é um IdP OIDC mock pronto pra rodar, para testar este fluxo.
  </Card>
</CardGroup>
