Endpoints de SSO
Grupo /sso/* + rotas de teste/validação em /platform/organizations/{id}/identity-providers/{id}/…. Suporta OIDC (produção) e SAML (em preview).
A configuração do provedor é feita via endpoints de identity providers. Os endpoints desta página executam o fluxo de login/logout.
Tabela de endpoints
| Método | Caminho | Auth | Descrição |
|---|---|---|---|
| GET | /sso/oidc/{provider_id}/login | Pública | Inicia fluxo OIDC. Retorna URL do IdP. |
| POST | /sso/discovery | Pública | Descobre o provedor configurado para um email/domínio. |
| GET | /sso/oidc/callback | Pública (validada por state) | Callback após autenticação no IdP. |
| GET | /sso/saml/sp-config | Pública | Config do Service Provider (para usar no IdP). |
| GET | /sso/saml/metadata | Pública | XML do metadata SP para importar no IdP. |
| POST | /sso/saml/acs | — | Atualmente retorna 501 Not Implemented. |
| POST | /sso/logout | — | Limpa cookie de sessão e redireciona. |
| POST | /platform/organizations/{organization_id}/identity-providers/{provider_id}/test | Sessão | Dispara um fluxo OIDC de teste. |
| POST | /platform/organizations/{organization_id}/identity-providers/{provider_id}/validate | Sessão | Valida a config (discovery + token test) sem rodar o fluxo completo. |
Fluxo OIDC (usuário final)
GET /sso/oidc/{provider_id}/login
Inicia o login. Retorna (JSON) a URL para onde o frontend deve redirecionar.
Query params:
redirect_path— caminho absoluto (começa com/) para onde voltar após autenticar. Default: raiz.
Response 200:
{
"authorization_url": "https://idp.acme.com/oauth2/v1/authorize?client_id=…&state=…",
"state": "opaque-token"
}
O frontend redireciona para authorization_url. O state é gravado em Redis (TTL configurável via NATIVE_WAZUH_SSO_STATE_TTL_SECONDS, padrão 600 s) para proteger contra CSRF no callback.
POST /sso/discovery
Dado um email ou domínio, diz qual identity provider está configurado. Usado pela tela de login para decidir se mostra "Continuar com Okta", "Continuar com Azure AD", etc.
Request body (SsoDiscoveryRequest):
{ "email": "alice@acme.com" }
Response 200 (SsoDiscoveryResponse):
{
"provider_id": "idp_...",
"name": "Okta corporativo",
"kind": "oidc",
"login_url": "/api/v1/sso/oidc/idp_.../login"
}
Quando não há provedor vinculado ao domínio, retorna { "provider_id": null } — o frontend cai no login tradicional.
GET /sso/oidc/callback
Endpoint que o IdP chama de volta após autenticação. Não chame manualmente — é invocado pelo fluxo OAuth2/OIDC do próprio IdP.
Query params (enviados pelo IdP):
provider_id— provider alvo (parte doredirect_uriregistrado no IdP).code— código de autorização.state— token para validar CSRF.
Comportamento:
- Valida
statecontra o que foi guardado em Redis. - Troca
codepor tokens no IdP (endpointtoken_endpointdo discovery). - Lê o
userinfoouid_tokenpara extrair email/claims. - Cria ou liga o usuário à organização do provider.
- Abre uma sessão (cookie).
- Redireciona para
NATIVE_WAZUH_PUBLIC_BASE_URL+redirect_pathoriginal.
Response: 302 Found com Set-Cookie: ruleforge_session=….
POST /sso/logout
Limpa o cookie de sessão e redireciona para a home pública.
Response: 302 Found para NATIVE_WAZUH_PUBLIC_BASE_URL.
Atualmente não dispara SLO (Single Logout) no IdP — só limpa a sessão local. SLO é tracked para versões futuras.
SAML (preview)
SAML está em preview. Os endpoints abaixo existem para que os IdPs possam ser configurados, mas o processamento do SAMLResponse (ACS) ainda não está implementado.
GET /sso/saml/sp-config
Response 200 (SamlServiceProviderConfig):
{
"entity_id": "https://ruleforge.example.com/sso/saml",
"acs_url": "https://ruleforge.example.com/api/v1/sso/saml/acs",
"slo_url": "https://ruleforge.example.com/api/v1/sso/logout",
"name_id_format": "urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress"
}
GET /sso/saml/metadata
Response 200 — Content-Type: application/samlmetadata+xml:
<?xml version="1.0" encoding="UTF-8"?>
<EntityDescriptor xmlns="urn:oasis:names:tc:SAML:2.0:metadata"
entityID="https://ruleforge.example.com/sso/saml">
<SPSSODescriptor AuthnRequestsSigned="false" WantAssertionsSigned="false"
protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol">
<NameIDFormat>urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress</NameIDFormat>
<AssertionConsumerService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"
Location="https://ruleforge.example.com/api/v1/sso/saml/acs"
index="1" isDefault="true" />
<SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect"
Location="https://ruleforge.example.com/api/v1/sso/logout" />
</SPSSODescriptor>
</EntityDescriptor>
Importe esse XML no IdP SAML para registrar o RuleForge como SP.
POST /sso/saml/acs
Response 501 — SAML continua em preview. O endpoint ACS ainda nao esta disponivel para uso em producao.
Teste e validação (admin)
POST /platform/organizations/{organization_id}/identity-providers/{provider_id}/test
Dispara um fluxo OIDC de teste sem afetar sessões reais — útil para debugar a configuração.
Query params: redirect_path (opcional).
Response 200: retorna a URL do IdP + um state de teste.
POST /platform/organizations/{organization_id}/identity-providers/{provider_id}/validate
Faz as seguintes checagens sem UI:
- Resolve o
discovery_url. - Verifica que
authorization_endpoint,token_endpointejwks_urirespondem. - Confirma que o
client_idé aceito (opcional, depende do IdP).
Response 200:
{
"valid": true,
"issuer": "https://acme.okta.com",
"authorization_endpoint": "https://acme.okta.com/oauth2/v1/authorize",
"token_endpoint": "https://acme.okta.com/oauth2/v1/token",
"jwks_uri": "https://acme.okta.com/oauth2/v1/keys",
"warnings": [],
"errors": []
}
Quando valid=false, a lista de errors explica o que falhou.
Estruturas compartilhadas
SsoDiscoveryRequest / SsoDiscoveryResponse
// request
{ "email": "string" }
// response
{
"provider_id": "string|null",
"name": "string|null",
"kind": "oidc|saml|null",
"login_url": "string|null"
}
SamlServiceProviderConfig
{
"entity_id": "string",
"acs_url": "string",
"slo_url": "string",
"name_id_format": "string"
}