Authagonal

Documentação

Tudo o que você precisa para começar com a Authagonal — desde criar seu primeiro locatário até configurar SSO, SCIM e personalização de marca.

Primeiros Passos

Authagonal fornece a cada locatário um servidor OIDC totalmente em conformidade com os padrões. Cada locatário recebe sua própria URL de emissor, documento de discovery e endpoints de token — sem infraestrutura compartilhada entre locatários. Você pode ir do zero a um fluxo de login funcionando em menos de 5 minutos.

Crie um Tenant

Cadastre-se em authagonal.io e escolha um slug para seu tenant. O slug se torna seu domínio emissor: {slug}.authagonal.io. Após criar sua conta, verifique seu endereço de e-mail para ativar o tenant.

Authagonal signup page showing tenant slug input and email verification

Escolha um slug único para seu tenant durante o cadastro

Registre um Cliente

Navegue até Clients na barra lateral do portal e clique em Novo Client. Insira um clientId e clientName para seu aplicativo. Em seguida, na aba URIs do cliente, adicione pelo menos uma URI de redirecionamento; é para onde os usuários são enviados após a autenticação. Por exemplo: https://app.example.com/callback. Novos clientes exigem um client secret por padrão; por isso, para um app de navegador sem backend, desative Exigir Secret na aba Geral.

New client form with Client ID and Client Name fields

Registre um novo cliente OAuth no portal

Desenvolvimento Local

Use http://localhost:3000/callback como URI de redirecionamento para desenvolvimento local. Authagonal permite URIs de redirecionamento sem HTTPS para origens localhost.

Seu Primeiro Login

A maneira mais rápida de integrar é com oidc-client-ts, uma biblioteca leve de cliente OIDC para aplicações JavaScript e TypeScript.

oidc-client-ts integration
import { UserManager } from 'oidc-client-ts';

const mgr = new UserManager({
  authority: 'https://acme.authagonal.io',
  client_id: 'my-app',
  redirect_uri: 'https://app.example.com/callback',
  response_type: 'code',
  scope: 'openid profile email',
});

// Redirect to login
mgr.signinRedirect();

// On callback page
const user = await mgr.signinRedirectCallback();
console.log(user.profile); // { sub, email, name, ... }

Se você preferir uma abordagem mínima sem biblioteca, pode usar o fluxo padrão de authorization code do OAuth 2.0 com fetch simples:

Minimal fetch-based flow
// 1. Redirect the user to the authorization endpoint
const authorizeUrl = new URL('https://acme.authagonal.io/connect/authorize');
authorizeUrl.searchParams.set('client_id', 'my-app');
authorizeUrl.searchParams.set('redirect_uri', 'https://app.example.com/callback');
authorizeUrl.searchParams.set('response_type', 'code');
authorizeUrl.searchParams.set('scope', 'openid profile email');
authorizeUrl.searchParams.set('code_challenge', codeChallenge);
authorizeUrl.searchParams.set('code_challenge_method', 'S256');
window.location.href = authorizeUrl.toString();

// 2. On the callback page, exchange the code for tokens
const res = await fetch('https://acme.authagonal.io/connect/token', {
  method: 'POST',
  headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
  body: new URLSearchParams({
    grant_type: 'authorization_code',
    code: new URLSearchParams(window.location.search).get('code')!,
    redirect_uri: 'https://app.example.com/callback',
    client_id: 'my-app',
    code_verifier: codeVerifier,
  }),
});

const tokens = await res.json();
// tokens.id_token, tokens.access_token (refresh_token only when offline_access is requested and allowed)
Authagonal login page with email and password fields, branded with tenant logo

A página de login padrão do seu locatário

Modo Sandbox

Teste sua integração primeiro em um ambiente sandbox. Crie um em Ambientes no portal: cada sandbox recebe sua própria URL ({env}-{slug}.authagonal.io, por exemplo test1-acme.authagonal.io) e pode ser redefinido para vazio a qualquer momento sem afetar os usuários do live.

Painel

O painel do portal oferece uma visão geral em tempo real do seu locatário. Ele apresenta as métricas mais importantes — crescimento de usuários, atividade de autenticação e navegação rápida para todos os recursos do portal.

Visão Geral

No topo do painel, você verá uma mensagem de boas-vindas e um link Abrir página de início de sessão para o login hospedado do seu locatário. Abaixo dos cartões de estatísticas, um medidor de Utilizadores ativos mensais acompanha o uso em relação ao limite do seu plano e leva às opções de plano assim que você ultrapassa 80%. Um gráfico de Atividade de início de sessão e um feed de Atividade recente com as entradas de auditoria mais recentes completam a página.

Full dashboard view showing the welcome banner, stat cards, monthly active users meter, and sign-in activity chart

A tela inicial do painel com cartões de estatísticas e atividade de login

Métricas de Atividade

Seis cartões de estatísticas resumem o seu locatário de relance:

  • Utilizadores ativos: o número total de usuários no seu locatário
  • Inícios de sessão (24h): logins bem-sucedidos nas últimas 24 horas
  • MFA ativado: a porcentagem de usuários com MFA inscrito, com as contagens de inscritos e do total
  • Tentativas falhadas (24h): logins com falha nas últimas 24 horas, como credenciais incorretas, contas bloqueadas ou rejeições de política
  • Sincronização SCIM: atividade de provisionamento de IdPs conectados, exibida como Inativo ou como uma contagem de operações
  • Gasto mensal: o gasto até agora neste mês, com uma projeção para o fim do mês

Os cartões de 24 horas comparam as últimas 24 horas com as 24 horas anteriores. O gráfico de Atividade de início de sessão mostra os logins bem-sucedidos e com falha por dia ao longo de 14, 30 ou 90 dias. O painel é atualizado a cada minuto.

Six stat cards showing active users, sign-ins, MFA enrolment, failed attempts, SCIM sync, and monthly spend

Cartões de estatísticas resumindo as últimas 24 horas

Navegação Rápida

Abaixo das métricas, cartões de navegação levam diretamente a Clients, SSO, Utilizadores, SCIM, Identidade Visual, Definições, Faturação, Domínios e Registo de Auditoria. Cada cartão mostra uma breve descrição para que novos membros da equipe possam se orientar rapidamente.

Clientes

Clientes OAuth representam os aplicativos que autenticam usuários através do seu locatário. Cada cliente tem sua própria configuração de URIs de redirecionamento, escopos, tipos de concessão, tempos de vida de token e política de MFA.

Lista de Clientes

A página de Clientes exibe uma tabela de todos os clientes registrados. Cada linha mostra o clientId, nome de exibição, tipos de concessão permitidos como badges coloridos e se o PKCE está habilitado. Clique em qualquer linha para abrir o editor de configuração completo.

Clients table showing clientId, name, grant type badges, and PKCE status for each registered application

Lista de clientes com badges de tipo de concessão e indicadores de PKCE

Criando um Cliente

Clique em Novo Client para registrar um novo aplicativo. Você precisa fornecer dois campos:

  • clientId — um identificador único para o cliente (ex: my-spa)
  • clientName — um nome de exibição legível
New client form with Client ID and Client Name input fields

Registre um novo cliente OAuth

Excluindo um Cliente

Para excluir um cliente, clique no ícone de lixeira na linha dele na tabela de clientes e digite o ID do cliente para confirmar. O cliente é removido permanentemente e deixa de poder autenticar usuários ou renovar tokens. Os tokens de acesso já emitidos não são revogados e continuam válidos até expirarem.

Referência de Configuração do Cliente

Cada cliente possui um conjunto abrangente de opções de configuração organizadas em cinco abas: Geral, URIs, Scopes & Grants, Tokens e Segurança.

Configurações Gerais

ConfiguraçãoDescriçãoPadrão
clientNameNome de exibição mostrado nas telas de consentimento e no portal–
requirePkceExigir Proof Key for Code Exchange em fluxos de authorization codeAtivado
requireClientSecretExigir um client secret para requisições de token (desabilite para clientes públicos como SPAs)Ativado
allowOfflineAccessPermitir que o cliente solicite refresh tokens via o escopo offline_accessDesativado
alwaysIncludeUserClaimsInIdTokenIncluir claims de perfil, e-mail, função e grupo no token de ID mesmo quando os scopes correspondentes não foram solicitadosDesativado
includeGroupsInTokensIncluir os nomes dos grupos SCIM do usuário como uma claim groups, nos tokens emitidos quando o scope groups é solicitadoDesativado

Segurança PKCE

Desabilitar PKCE reduz a segurança para fluxos de authorization code. Desabilite isso apenas para clientes legados que não suportam PKCE. Todos os aplicativos modernos devem manter o PKCE habilitado.

URIs

Os campos de URI usam entrada por tags — digite um valor e pressione Enter ou vírgula para adicioná-lo. Clique no X de qualquer tag para removê-la.

ConfiguraçãoDescrição
redirectUrisURLs de callback permitidas após a autenticação. Devem corresponder exatamente ao parâmetro redirect_uri nas requisições de autorização.
postLogoutRedirectUrisURLs permitidas para redirecionamento após o logout.
allowedCorsOriginsOrigens permitidas para requisições cross-origin aos endpoints de token e UserInfo.
URI configuration section showing tag inputs for redirect URIs, post-logout URIs, and CORS origins

Campos de entrada por tags para configurar URIs

Escopos e Tipos de Concessão

ConfiguraçãoOpções
allowedScopesopenid profile email offline_access phone roles groups
allowedGrantTypesauthorization_code client_credentials refresh_token urn:ietf:params:oauth:grant-type:device_code urn:ietf:params:oauth:grant-type:token-exchange

Tempos de Vida de Token

ConfiguraçãoDescriçãoPadrão
accessTokenLifetimeSecondsQuanto tempo os access tokens são válidos1800 (30 min)
identityTokenLifetimeSecondsQuanto tempo os tokens de ID são válidos300 (5 min)
authorizationCodeLifetimeSecondsQuanto tempo os authorization codes são válidos para troca300 (5 min)
absoluteRefreshTokenLifetimeSecondsTempo de vida máximo de um refresh token independente de atividade2592000 (30 dias)
slidingRefreshTokenLifetimeSecondsA expiração do refresh token é redefinida a cada uso, até o tempo de vida absoluto1296000 (15 dias)
Token lifetime configuration fields with numeric inputs for each lifetime setting

Configure tempos de vida de token por cliente

URIs de logout

Clientes podem registrar URIs de logout tanto back-channel quanto front-channel. Ambas são opcionais — configure as que correspondam à forma como seu aplicativo limpa sua sessão.

ConfiguraçãoDescrição
backChannelLogoutUriPOST servidor-a-servidor com um token de logout assinado. Confiável mesmo quando o navegador está offline.
frontChannelLogoutUriCarregada em um iframe oculto durante o logout para que o navegador limpe cookies e armazenamento local.
frontChannelLogoutSessionRequiredQuando ativo, a URL de logout recebe os parâmetros iss e sid para que seu app correlacione o logout com a sessão específica.

Use os dois juntos

Back-channel garante que o servidor seja notificado; front-channel limpa o navegador. A maioria dos apps se beneficia de configurar ambos.

Política de MFA

Cada cliente tem sua própria política de MFA, definida na aba <strong>Segurança</strong> do cliente. O dropdown de política de MFA oferece três opções:

PolíticaComportamento
DesativadoMFA nunca é solicitado para este cliente
AtivadoUsuários podem opcionalmente se inscrever no MFA; serão solicitados se inscritos
ObrigatórioTodos os usuários devem completar o MFA para se autenticar através deste cliente
MFA policy dropdown showing Disabled, Enabled, and Required options on the client configuration page

Política de MFA por cliente

SSO Empresarial

O SSO Empresarial permite que seus clientes tragam seu próprio provedor de identidade. Authagonal suporta federação SAML 2.0 e OIDC com roteamento baseado em domínio, para que os usuários sejam automaticamente direcionados ao IdP correto com base no endereço de e-mail.

SSO domain routing flow: shows how email domains are matched to SAML or OIDC identity providers

Roteamento SSO baseado em domínio

Conexões SAML 2.0

Para criar uma conexão SAML, navegue até a página SSO e selecione a aba SAML. Forneça o seguinte:

CampoDescrição
connectionNameUm nome legível para esta conexão (ex: "Acme Corp Okta")
entityIdO ID de entidade do seu SP. Registre exatamente este valor no seu IdP como identificador (Entity ID) da aplicação; as asserções devem nomeá-lo como Audience
metadataLocationURL do documento XML de metadados SAML do IdP
metadataXmlXML de metadados do IdP colado, para IdPs sem URL de metadados (Google Workspace) ou cuja URL não é acessível pela internet. Forneça este campo ou metadataLocation, não ambos
nameIdFormatFormato NameID opcional solicitado ao IdP. Omita para o padrão emailAddress, ou defina "none" para omitir NameIDPolicy por completo (recomendado para ADFS)
allowedDomainsDomínios de e-mail roteados para esta conexão (ex: acme.com). Definidos pela API; o portal os mostra no cartão da conexão e na aba Encaminhamento de Domínios

Quando você salva a conexão, Authagonal busca o documento de metadados e importa o certificado de assinatura do IdP, a URL do endpoint SSO e o formato do identificador de nome. Os metadados são atualizados periodicamente para capturar rotações de certificado.

SAML connection creation form with fields for connection name, SP entity ID, and IdP metadata

Crie uma conexão SSO SAML 2.0

Conexões OIDC

Para criar uma conexão de federação OIDC, selecione a aba OIDC e forneça:

CampoDescrição
connectionNameUm nome legível para esta conexão
metadataLocationA URL de discovery do OpenID Connect (ex: https://login.microsoftonline.com/{tenant}/v2.0/.well-known/openid-configuration)
clientIdO client ID registrado no IdP externo para esta federação
clientSecretO client secret para o registro no IdP externo
allowedDomainsDomínios de e-mail roteados para esta conexão (ex: acme.com). Definidos pela API; o portal os mostra no cartão da conexão e na aba Encaminhamento de Domínios
OIDC connection creation form with fields for connection name, discovery URL, client ID, and client secret

Crie uma conexão de federação OIDC

Roteamento de Domínio

O roteamento de domínio redireciona automaticamente os usuários para o provedor de identidade correto com base no domínio de e-mail. Quando um usuário insere seu e-mail na página de login, Authagonal verifica se a parte do domínio (ex: acme.com) corresponde aos allowedDomains de alguma conexão SSO. Se corresponder, o usuário é redirecionado de forma transparente para o IdP da sua organização.

Domínio de E-mailProvedor SSOProtocolo
acme.comAcme Corp OktaSAML 2.0
contoso.comContoso Azure ADOIDC
example.orgExample OneLoginSAML 2.0
Domain routing table showing email domains mapped to SSO connections with protocol type

O roteamento de domínio mapeia domínios de e-mail para provedores de identidade

Fluxo Iniciado pelo SP

O fluxo iniciado pelo SP é o padrão — os usuários começam na sua página de login e são roteados para o IdP correto automaticamente. Os usuários também podem ser direcionados diretamente a uma conexão específica via /saml/{connectionId}/login ou /oidc/{connectionId}/login.

Provisionamento JIT

Quando um usuário faz login via SSO pela primeira vez e ainda não existe no seu locatário, Authagonal pode criar sua conta automaticamente (provisionamento Just-In-Time). O provisionamento JIT fica desativado por padrão: ative-o por conexão marcando Ativar provisionamento JIT ao criar a conexão.

Quando o provisionamento JIT está desabilitado, apenas usuários que foram pré-provisionados — via SCIM, pela página de Usuários do portal ou pela API — podem fazer login através dessa conexão. Usuários desconhecidos recebem um erro access_denied e são orientados a contatar seu administrador.

Configuração por Conexão

O provisionamento JIT é controlado por conexão SSO, não em todo o tenant. Você pode ter uma conexão que permite JIT (ex: para uma organização parceira que gerencia seus próprios usuários) e outra que exige pré-provisionamento (ex: para um cliente empresarial usando sincronização SCIM).

Teste Antes da Implantação

Teste conexões SSO com o modo sandbox antes de implantá-las para usuários em produção. Isso permite verificar a configuração do IdP, mapeamento de atributos e roteamento de domínio sem afetar fluxos de autenticação em produção.

Conexões com Escopo de Organização

Uma conexão também pode pertencer a uma organização dentro do seu tenant, em vez de ao tenant inteiro. Ela só é oferecida depois que essa organização já foi resolvida: por um domínio personalizado fixado a ela, por um parâmetro organization no link de login ou por um cliente registrado para aquela única organização. Nunca aparece em uma página de login de todo o tenant. A verificação segue essa ordem, da maior para a menor prioridade.

Entrar Cria a Associação

Um usuário que entra por uma conexão com escopo de organização se torna automaticamente membro dessa organização, do mesmo jeito que o provisionamento JIT cria a conta dele. Não há uma etapa de convite separada.

A Unicidade de Domínio Vale por Escopo

Um domínio de e-mail pode ser reivindicado uma vez em todo o tenant e, de forma independente, mais uma vez dentro de cada organização: acme.com pode ser roteado para uma conexão de todo o tenant e também, quando uma organização já está selecionada, para a conexão própria dessa organização. O que ele não pode é pertencer a duas conexões no mesmo escopo; o Authagonal rejeita isso quando você salva a conexão.

Usuários

A página de Usuários permite gerenciar todos os usuários finais do seu locatário. Você pode buscar usuários, visualizar seus detalhes, convidar novos usuários e ver como cada usuário foi provisionado.

A barra de busca encontra um ID de usuário ou e-mail exato, ou um prefixo do e-mail, do nome ou do sobrenome, e os filtros Todos, Ativos e Inativos restringem a lista por status. A busca tem debounce de 300ms, então os resultados são atualizados conforme você digita sem sobrecarregar a API. Os resultados são paginados em 50 usuários por página; use os controles de navegação na parte inferior da tabela para navegar entre as páginas.

Tabela de Usuários

A tabela de usuários exibe as seguintes colunas para cada usuário:

ColunaDescrição
UtilizadorO nome do usuário (ou o e-mail quando nenhum nome está definido), com o e-mail logo abaixo e um badge Não verificado até que o e-mail seja confirmado
StatusActive ou Inactive — indica se a conta está habilitada
OrigemSCIM ou Local — como o usuário foi criado
FunçõesAs funções atribuídas ao usuário
MFAEnabled quando a autenticação multifator está inscrita; caso contrário, um traço
Criado emA data em que a conta do usuário foi criada
User list table with columns for user, status, source, roles, MFA, and created date

A lista de usuários com barra de busca e paginação

Convidando Usuários

Clique em Convidar utilizador para convidar alguém para o seu locatário. A pessoa recebe um e-mail para definir a própria senha. O formulário recebe:

CampoDescrição
emailO endereço de e-mail do usuário (deve ser único dentro do locatário)
firstNameO primeiro nome do usuário
lastNameO sobrenome do usuário
localeIdioma preferido. Define o idioma da interface e dos e-mails do usuário; opcional, recorre ao inglês.
organizationIdOrganização opcional à qual adicionar o usuário, com as funções dele nela. Exibido quando o seu locatário tem organizações
Invite user form with email, first name, last name, and Language fields

Convide um novo usuário

Usuários Provisionados por SCIM

Usuários criados via SCIM são marcados com um badge "SCIM" na coluna Origem. Seu ciclo de vida (criação, atualizações e desativação) é gerenciado pelo provedor de identidade de origem.

Idioma preferido

Cada usuário tem um idioma preferido que controla tanto a sua interface hospedada quanto os e-mails transacionais que o Authagonal lhe envia (verificação, redefinição de senha, boas-vindas e mais). Você pode defini-lo ao convidar um usuário e alterá-lo a qualquer momento na página de detalhes do usuário. Se um usuário não tiver um idioma preferido definido, o Authagonal recorre ao inglês. O seletor oferece todos os idiomas suportados: inglês, chinês (simplificado), alemão, francês, espanhol, vietnamita, português, japonês, árabe, hindi e africâner.

User detail edit form with profile fields including a preferred Language selector

Defina o idioma preferido de um usuário na página de detalhes

Detalhes do usuário

Clique em qualquer linha da lista de usuários para abrir sua página de detalhes. A partir daí você pode editar dados do perfil, gerenciar funções, redefinir MFA, revisar atributos personalizados e excluir o usuário.

User detail page showing profile fields, status, assigned roles, and custom attributes

Perfil

Edite e-mail, nome/sobrenome, telefone, empresa, idioma, ID externo e a flag de ativo do usuário. Alterar o e-mail ou a flag de e-mail confirmado exige um administrador ou proprietário. Alterações de e-mail devem permanecer únicas no locatário; a API retorna email_already_in_use se já estiver em uso.

Funções

Atribua e remova funções definidas na página Funções. As funções atribuídas são emitidas como a claim roles nos tokens ID e de acesso quando o cliente solicita o scope roles.

Autenticação multifator

Veja todas as credenciais MFA registradas para o usuário (aplicativo autenticador (TOTP), WebAuthn/passkeys e códigos de recuperação), cada uma com timestamps de registro e último uso. Remova credenciais individuais ou redefina toda a MFA; ambas as ações exigem um administrador ou proprietário. Redefinir força o usuário a se registrar novamente no próximo login.

Atributos personalizados

Dados arbitrários chave/valor anexados ao usuário. As chaves devem ser únicas. Os atributos são expostos via API de perfil de usuário e SCIM, e podem ser mapeados para claims do token de acesso configurando os userClaims de um scope personalizado.

Organização

A organização à qual este usuário pertence. É um identificador seu, em texto livre, emitido como a claim org_id nos tokens do usuário e em /connect/userinfo sob o escopo profile. O Authagonal nunca deriva esse valor: ele é definido pelo seu aplicativo de provisionamento, pela credencial SCIM que criou o usuário, ou manualmente aqui.

O link ao lado do campo lista todos que compartilham esse valor, e o mesmo filtro está disponível na API como GET /api/v1/users?organizationId=. Use-o para responder quem pertence a um determinado cliente final sem paginar o diretório inteiro.

Excluir usuário

Remove permanentemente o usuário e todas as suas credenciais MFA. Digite o e-mail do usuário para confirmar — não há como desfazer.

Grupos

Grupos permitem organizar usuários e incluir membros de grupo em tokens. Grupos podem ser criados manualmente no portal ou provisionados automaticamente via SCIM a partir de um provedor de identidade externo.

Lista de Grupos

Os grupos são listados na aba Grupos da página SCIM, com as seguintes informações:

ColunaDescrição
Nome do GrupoO nome de exibição do grupo
MembrosO número de usuários atualmente no grupo
OrigemSCIM ou Manual — como o grupo foi criado
Criado emA data em que o grupo foi criado
Groups list table showing group name, member count, source badge, granted roles, and created date

Lista de grupos com indicadores de origem

Criando um Grupo

Clique em Novo grupo e insira um Nome de exibição para o grupo. Nomes de grupos devem ser descritivos e únicos dentro do seu locatário (ex: "Engenharia", "Admins de Faturamento", "Testadores Beta").

Detalhes do Grupo e Membros

Clique em qualquer grupo para abrir a visualização detalhada. Aqui você pode ver todos os membros atuais e gerenciar a associação:

  • Adicionar membros: pesquise um usuário por e-mail ou nome e adicione-o ao grupo.
  • Remover membros: clique no botão de remover ao lado de qualquer membro e confirme. Quaisquer funções concedidas por meio do grupo são revogadas.
Group detail view showing the member list, a user search to add members, and the roles the group grants

Gerencie membros do grupo na visualização detalhada

Grupos em Tokens

Quando Grupos nos Tokens está habilitado em um cliente e o scope groups é solicitado, os tokens emitidos incluem uma claim groups listando os nomes de exibição dos grupos do usuário:

groups claim
{
  "sub": "user-123",
  "email": "[email protected]",
  "groups": ["Engineering", "Beta Testers"]
}

Habilitar por Cliente

A configuração Grupos nos Tokens é definida em cada cliente individualmente, na aba Geral do cliente. O cliente também precisa permitir o scope groups.

Funções

Funções suportam controle de acesso baseado em funções (RBAC) no seu aplicativo. Defina funções no Authagonal, atribua-as a usuários e use a claim roles em tokens para aplicar autorização na lógica do seu aplicativo.

Gerenciando Funções

A página de Funções exibe uma tabela de todas as funções definidas com edição inline. Cada função possui:

ColunaDescrição
NomeUm identificador único para a função (ex: "admin", "editor", "viewer")
DescriçãoUma descrição legível do que a função concede
Criado emA data em que a função foi criada

Criando uma Função

Clique em Nova função e forneça um nome e descrição. Nomes de funções devem ser concisos e seguir uma convenção de nomenclatura consistente no seu aplicativo (ex: minúsculas com hífens: billing-admin).

Edição Inline

Funções suportam edição inline diretamente na tabela. Clique no ícone de lápis em qualquer função para entrar no modo de edição — os campos de nome e descrição se tornam editáveis. Modifique os valores e clique no ícone de confirmação para salvar. As alterações entram em vigor imediatamente.

Excluindo uma Função

Clique no ícone de exclusão em qualquer função para removê-la. Você será solicitado a confirmar antes que a função seja permanentemente excluída. Remover uma função não invalida retroativamente tokens existentes — a função estará ausente dos novos tokens emitidos após a exclusão.

Roles table with inline editing active, showing editable name and description fields with save and cancel icons

Edição inline de funções na tabela de funções

Funções em Tokens

Funções atribuídas a um usuário são incluídas como uma claim roles nos tokens de ID e de acesso quando o cliente solicita o scope roles. Seu aplicativo pode ler esta claim para tomar decisões de autorização:

roles claim in ID token
{
  "sub": "user-123",
  "email": "[email protected]",
  "roles": ["admin", "billing-admin"]
}

Provisionamento SCIM

SCIM 2.0 (System for Cross-domain Identity Management) permite provisionamento automático de usuários e grupos a partir de provedores de identidade empresariais como Okta, Azure AD, OneLogin e JumpCloud. Quando configurado, contas de usuários e associações de grupos são automaticamente sincronizadas do IdP de origem para seu locatário Authagonal.

SCIM provisioning flow: shows user lifecycle events flowing from enterprise IdP through Authagonal SCIM API to your app via TCC webhooks

Sincronização de ciclo de vida de usuário SCIM com provisionamento em sistemas de destino

Etapas de Configuração

Siga estas etapas para habilitar o provisionamento SCIM para um cliente:

  1. Selecione o aplicativo cliente — Escolha o cliente OAuth ao qual o provisionamento SCIM será associado.
  2. Gere um token SCIM — Forneça uma descrição e um período de expiração em dias, depois gere o token.
  3. Copie o token imediatamente — O valor bruto do token é exibido apenas uma vez. Copie-o antes de fechar o diálogo.
  4. Configure seu IdP — Nas configurações SCIM do seu provedor de identidade, insira a URL base e o token bearer.
  5. Teste a sincronização de usuários — Acione uma sincronização de teste do seu IdP e verifique se os usuários aparecem no portal Authagonal.

URL Base SCIM

Configure seu provedor de identidade com a seguinte URL base:

SCIM Base URL
https://{slug}.authagonal.io/scim/v2

Substitua {slug} pelo slug do seu locatário.

SCIM configuration page showing client selector, token generation form, and base URL

Página de configuração SCIM com geração de token

Gerenciamento de Tokens

Tokens SCIM autenticam requisições de provisionamento do seu IdP. Você pode gerenciar múltiplos tokens por cliente:

CampoDescrição
DescriçãoUm rótulo para identificar o token (ex: "Okta Production SCIM")
ExpiraçãoTempo de vida do token em dias (1 a 3650, padrão 365).
StatusTokens ativos estão em uso. Tokens revogados exibem um badge Revoked e não podem mais autenticar requisições.

Para revogar um token, clique no botão Revogar ao lado dele. Tokens revogados permanecem visíveis na lista para fins de auditoria, mas imediatamente param de aceitar requisições.

SCIM token list showing active and revoked tokens with description, expiry date, and revoke button

Gerenciamento de tokens com indicadores de tokens ativos e revogados

Copie o Token Imediatamente

O token SCIM bruto é exibido apenas uma vez quando criado. Copie-o imediatamente — ele não pode ser recuperado depois. Se você perder o token, precisará gerar um novo e atualizar a configuração do seu IdP.

Testando Conectividade

Verifique se sua integração SCIM está funcionando consultando o endpoint ServiceProviderConfig:

Test SCIM connectivity
curl -H "Authorization: Bearer YOUR_TOKEN" \
  https://acme.authagonal.io/scim/v2/ServiceProviderConfig

Uma resposta bem-sucedida retorna um documento JSON descrevendo os recursos SCIM suportados: PATCH e filtragem são suportados, enquanto operações em lote, alteração de senha, ordenação e ETags não são.

Idioma preferido

O atributo SCIM preferredLanguage (com recurso a locale) é mapeado para o idioma armazenado do usuário. Usuários SSO provisionados via SCIM recebem automaticamente e-mails localizados no idioma que o IdP envia.

O que uma credencial enxerga

Uma credencial SCIM só enxerga os usuários e grupos que ela mesma provisionou. Ler, atualizar ou excluir um usuário criado por outro conector responde 404, a listagem retorna apenas os próprios, e a associação de um grupo só pode nomear usuários provisionados pelo mesmo conector. Contas criadas de qualquer outra forma, por um administrador, por cadastro self-service ou por provisionamento just-in-time via SSO, são completamente invisíveis para o SCIM.

Essa fronteira é por cliente, não por token. Duas credenciais emitidas no mesmo cliente são uma única identidade com dois segredos, e cada uma pode modificar o que a outra criou. Dê um cliente a cada conector que não confie nos demais. O externalId tem o mesmo escopo, então dois conectores podem usar ext-001 para pessoas diferentes sem colidir.

Desprovisionamento

DELETE /scim/v2/Users/{id} desativa a conta e a marca como excluída. O registro é mantido, como a RFC 7644 permite, mas responde 404 a toda operação subsequente e é omitido das listagens. As inscrições de MFA e as associações a grupos do usuário são removidas, o mapeamento de externalId é liberado e todos os tokens emitidos são revogados, de modo que o acesso termina imediatamente, e não na próxima expiração de token.

Se a mesma pessoa for recontratada e recriada depois, ela recebe um novo id de usuário. Identificadores nunca são reciclados: o id é o subject de todos os tokens que você já emitiu, então reutilizá-lo daria silenciosamente ao novo contratado o histórico do titular anterior em cada aplicação que confia nele.

Marcando usuários sincronizados com uma organização

O SCIM não dá ao conector nenhuma forma de dizer qual dos seus clientes finais ele está sincronizando. O SCIM básico não define nenhum atributo de organização, então uma criação de usuário comum informa o nome e o e-mail da pessoa e nada sobre a quem ela pertence. Se vários clientes finais provisionam no seu locatário, os usuários deles chegam indistinguíveis.

Quem responde a isso é a credencial, não a requisição. Ao criar um token SCIM, escolha uma das organizações do seu locatário em Organização (o seletor aparece quando o seu locatário tem organizações). Todo usuário provisionado por esse token se torna membro ativo dessa organização e a carrega como a claim org_id nos seus tokens a partir daí. Emita uma credencial por cliente final no mesmo cliente, e os usuários sincronizados deles saem corretamente atribuídos sem precisar de um registro de cliente para cada um. Deixe o campo em branco e os usuários ficam sem marcação.

Marcação não é isolamento

A propriedade é aplicada por cliente, não por token. Duas credenciais no mesmo cliente são uma única identidade com dois segredos: cada uma pode ler, renomear, desativar e excluir os usuários que a outra criou. Isso não é problema quando você mesmo detém todas as credenciais. Se a equipe de TI de cada cliente final detém a sua, dê um cliente a cada uma e defina a organização na credencial delas também.

A marcação é aplicada quando o usuário é criado e nunca em uma atualização posterior, então uma sincronização incremental de rotina não consegue mover silenciosamente uma conta existente. Se você também executa um aplicativo de provisionamento, a marcação explícita da credencial prevalece: uma resposta /try só preenche uma organização que ainda está vazia.

Esquemas suportados

Implementamos os esquemas centrais User e Group do SCIM 2.0 (RFC 7643). Os atributos de usuário suportados são userName, name.givenName, name.familyName, displayName, emails, active, externalId e preferredLanguage / locale.

A extensão de usuário corporativo não é implementada, então department, manager, employeeNumber, costCenter, division e organization são aceitos e ignorados em vez de armazenados, tanto em create quanto em replace e PATCH. Entra e Okta mapeiam alguns deles por padrão, então você não precisa removê-los do seu mapeamento de atributos. Para atribuir um usuário a um dos seus clientes finais, defina a organização na credencial SCIM: o atributo corporativo organization é afirmado pelo provedor de identidade do seu cliente final e, deliberadamente, não vira o org_id dele.

Scopes OAuth

Os scopes permitem que clientes solicitem partes específicas dos dados ou permissões de um usuário. O Authagonal suporta tanto scopes padrão OIDC quanto scopes personalizados que você define para suas APIs.

Scopes integrados

ScopeDescrição
openidObrigatório para qualquer fluxo OpenID Connect. Emite um token de identidade.
profileRetorna claims de perfil padrão (name, given_name, family_name, locale, org_name).
emailRetorna o e-mail do usuário e o status de verificação.
phoneRetorna o número de telefone do usuário (phone_number).
offline_accessEmite um refresh token junto com o token de acesso.
rolesLibera a claim roles do usuário. Sem este scope, as funções não são emitidas.
groupsLibera a claim groups do usuário (associação a grupos SCIM). Sem este scope, os grupos não são emitidos.

Scopes personalizados

Defina seus próprios scopes na página Scopes. Cada scope descreve uma permissão ou recurso que um cliente pode solicitar (por exemplo, billing.read, orders.write).

Custom scope creation form with name, display name, description and User Claims fields
CampoDescrição
nameO identificador de scope enviado nas requisições de token (ex: billing.read).
displayNameRótulo legível mostrado na tela de consentimento.
descriptionExplicação mais longa mostrada sob o nome de exibição no consentimento.
userClaimsClaims adicionais adicionadas ao token de acesso e ao token de ID quando este scope é concedido.
showInDiscoveryDocumentSe ativo, o scope aparece em /.well-known/openid-configuration.
emphasizeDestaca o scope como sensível na tela de consentimento.
requiredImpede que o usuário desmarque o scope durante o consentimento.
groupGrupo de consentimento: scopes que compartilham um título aparecem juntos na tela de consentimento sob uma única caixa de seleção. Apenas apresentação.
allowedRolesFunções que um usuário precisa ter para receber este scope. Vazio permite todos; um usuário sem nenhuma dessas funções tem o scope removido do token em vez de ser recusado.

Integração de consentimento

Clientes com RequireConsent: true solicitam consentimento na primeira requisição. Excluir um scope não revoga tokens já emitidos — revogue-os explicitamente se necessário.

Claims personalizados nos tokens

Claims personalizados têm duas metades. A fonte são dados por usuário: cada AuthUser tem um dicionário customAttributes que você pode preencher via Portal (Usuários → usuário → Atributos personalizados), via SCIM ou via um hook de provisionamento TCC. A liberação é por scope: a lista userClaims de cada scope nomeia as chaves permitidas a sair do servidor.

Quando um cliente solicita scopes, o Authagonal percorre os scopes concedidos, une suas listas userClaims e emite apenas essas chaves dos customAttributes do usuário. Chaves desconhecidas são silenciosamente descartadas — um cliente não pode ler um atributo adivinhando o nome. Claims OIDC padrão (sub, email, name, etc.) seguem a especificação e não estão sujeitos à lista de permissões.

Example: project-scope claims on an access token
# 1. On the user (Portal → Users → {user} → Custom Attributes)
department = "engineering"
employee_id = "E-1042"
seat_tier = "enterprise"

# 2. On a custom scope (Portal → Scopes → projects.read)
name        = "projects.read"
userClaims  = ["department", "seat_tier"]   # <-- whitelist

# 3. Client requests scope=openid projects.read
# Decoded access token (relevant fields only):
{
  "sub": "u-9b…",
  "scope": "openid projects.read",
  "department": "engineering",
  "seat_tier":  "enterprise"
  // employee_id is NOT emitted; it's not in the whitelist for any granted scope.
}

Claims de federação preenchem lacunas por sessão

Quando um usuário entra via um IdP de origem (SAML/OIDC SSO), claims por sessão chegando do IdP, por exemplo um atributo department mapeado de uma asserção SAML, fluem pela mesma lista de permissões de scope, mas apenas preenchem lacunas: em uma colisão de chave, prevalece o valor persistido em customAttributes. São emitidos nos tokens desta sessão (e sobrevivem a rotações de refresh) sem serem gravados de volta no registro do usuário.

Atribuindo scopes a clientes

Adicione scopes permitidos na aba Clientes → Scopes e Grants. Um cliente só pode solicitar scopes que lhe foram concedidos; scopes desconhecidos são rejeitados com invalid_scope.

Marca

Personalize a aparência das páginas de login do seu tenant. As configurações de marca permitem combinar a experiência de autenticação com a identidade visual do seu produto — desde logotipos e cores até substituições avançadas de CSS.

Aparência

ConfiguraçãoDescrição
appNameO nome do aplicativo exibido no cabeçalho da página de login (quando nenhum logotipo está definido) e nos e-mails transacionais
logoUrlURL para a imagem do seu logotipo. Exibida no topo da página de login. Tamanho recomendado: 200x60px ou proporção semelhante.
primaryColorA cor primária da marca usada para botões, links e estados de foco. Defina via seletor de cores ou entrada hexadecimal. Uma visualização em tempo real é atualizada conforme você altera o valor.
customCssUrlURL para um arquivo CSS carregado após os estilos padrão. Ele deve ser servido a partir da mesma origem que a página de login; uma URL em qualquer outra origem é ignorada.
Branding appearance settings with app name input, logo URL field, color picker with hex input, and custom CSS URL field

Configurações de aparência com visualização de cores em tempo real

Informações de Contato

ConfiguraçãoDescrição
supportEmailUm endereço de e-mail de suporte exibido nas páginas de login. Os usuários veem isso quando precisam de ajuda com sua conta.

Opções da Página de Login

Controle quais elementos aparecem na página de login do seu tenant:

OpçãoDescriçãoPadrão
showForgotPasswordExibir o link "Esqueci a senha?" no formulário de loginAtivado
showRegistrationExibir o link "Cadastre-se" para registro de usuário por autoatendimentoAtivado
poweredByExibir o badge "Powered by Authagonal" na parte inferior da página de loginAtivado
A customized login page showing a branded logo, custom primary color on the sign-in button, and support email in the footer

Exemplo de página de login com marca personalizada aplicada

CSS personalizado

Para controle total sobre a aparência da página de login, forneça a URL de um arquivo CSS nas configurações de marca. O arquivo é carregado após os estilos padrão, então suas regras têm prioridade. A URL deve estar na mesma origem que a página de login; folhas de estilo de outras origens não são carregadas.

Propriedades personalizadas CSS

A página de login suporta propriedades personalizadas CSS (variáveis) para substituições comuns. Defina-as no seu arquivo CSS para alterar cores, fontes e forma sem escrever seletores complexos.
/* your-custom-styles.css */
:root {
--auth-bg: #1a1a2e;
--auth-card-bg: #16213e;
--auth-heading: #e0e0e0;
--auth-radius: 12px;
--auth-font: 'Inter', sans-serif;
}
VariávelDescriçãoPadrão
--auth-bgCor de fundo da página#f3f4f6
--auth-card-bgFundo do cartão de loginwhite
--auth-headingCor do texto do cabeçalho#111827
--auth-radiusRaio da borda do cartão0.5rem
--auth-fontFamília da fonteinherit

Modo escuro

O app de login inclui temas claro, escuro e do sistema. A configuração Modo escuro na página Identidade Visual escolhe o padrão: desativado, auto (segue a preferência do sistema; é o padrão) ou forçado. Os usuários ainda podem escolher em um seletor na página de login; a escolha persiste entre sessões. Quando em system, a SPA acompanha prefers-color-scheme em tempo real.

Valores claros são declarados em :root; substituições escuras ficam restritas a .dark. O branding do locatário via customCssUrl sempre prevalece — suas cores permanecem independentemente do tema do usuário.

Seletores de elementos

Para controle mais granular, mire elementos específicos usando atributos data-auth. Esses seletores são estáveis entre atualizações — não serão quebrados quando mudarmos os nomes de classe internos.
SeletorElemento
[data-auth="page"]Container de fundo de página inteira
[data-auth="header"]Área do logo e nome do app
[data-auth="logo"]Imagem do logo
[data-auth="app-name"]Título do nome do app (quando nenhum logo está definido)
[data-auth="content"]Área de conteúdo principal (formulários, mensagens)
[data-auth="login-form"]Elemento do formulário de login
[data-auth="email-field"]Container de entrada de e-mail
[data-auth="password-field"]Container de entrada de senha
[data-auth="submit-button"]Botão de entrar
[data-auth="languages"]Barra seletora de idioma

Configurações

Configure políticas de segurança, webhooks e configurações de ambiente em todo o tenant. Estas configurações se aplicam globalmente a todos os clientes, a menos que sejam substituídas no nível do cliente.

Política de Senha

Defina os requisitos de complexidade de senha para todos os usuários do seu locatário, em Utilizadores → Configurações:

ConfiguraçãoIntervaloPadrão
minPasswordLength6 – 1288
requireUppercaseAtivado / DesativadoAtivado
requireLowercaseAtivado / DesativadoAtivado
requireDigitAtivado / DesativadoAtivado
requireSpecialCharAtivado / DesativadoAtivado
Password policy settings showing minimum length slider and toggle switches for character requirements

Configuração de política de senha

Política de MFA

A política de MFA do tenant, definida em Utilizadores → Configurações, define o comportamento padrão de autenticação multifator. Clientes individuais podem substituir esta configuração.

PolíticaComportamento
DisabledMFA não está disponível. Usuários não podem se inscrever no MFA.
EnabledMFA é opcional. Usuários podem optar por se inscrever e serão solicitados no login se inscritos.
RequiredMFA é obrigatório. Todos os usuários devem se inscrever no MFA e completar um segundo fator a cada login.

Sessão e Bloqueio

Controle a duração da sessão e o comportamento de bloqueio de conta:

ConfiguraçãoIntervaloPadrão
sessionLifetimeMinutes5 – 43.200 (30 dias)60
maxFailedAttempts1 – 1005
lockoutDurationMinutes1 – 1.440 (24 horas)10
Session and lockout settings with numeric inputs for session lifetime, max failed attempts, and lockout duration

Configuração de sessão e bloqueio

Webhooks

Webhooks permitem reagir a eventos de autenticação em tempo real. Dois eventos (onUserAuthenticated, onTokenIssued) são aplicáveis — por padrão disparam de forma assíncrona e não bloqueiam o usuário, mas você pode ativar a aplicação por evento para que uma resposta não 2xx ou um corpo {"allow": false} rejeite a ação. Os demais eventos são notificações — sempre fire-and-forget, nunca bloqueiam.

EventoTipoDescrição
onUserAuthenticatedAplicávelDisparado após um login bem-sucedido. Por padrão fire-and-forget, então a latência do login não é afetada. Ative <code>webhookEnforceUserAuthenticated</code> para torná-lo bloqueante — uma resposta não 2xx ou um corpo <code>{"allow": false}</code> rejeitará então o login.
onTokenIssuedAplicávelDisparado antes da emissão de tokens (authorization_code, refresh_token, client_credentials). Por padrão fire-and-forget. Ative <code>webhookEnforceTokenIssued</code> para torná-lo bloqueante — uma resposta não 2xx ou um corpo <code>{"allow": false}</code> impedirá então a emissão.
onUserCreatedNotificaçãoNotificação disparar e esquecer quando um novo usuário se registra ou é provisionado via SCIM.
onUserUpdatedNotificaçãoNotificação fire-and-forget quando um registro de usuário é atualizado (alterações de perfil, de papel, atualizações SCIM).
onUserDeletedNotificaçãoNotificação fire-and-forget quando um usuário é excluído, seja via Portal/SCIM ou pela política de retenção.
onLoginFailedNotificaçãoNotificação disparar e esquecer quando uma tentativa de login falha por credenciais inválidas, bloqueio ou rejeição de política.

Configurações adicionais de webhook:

ConfiguraçãoIntervaloPadrãoDescrição
webhookTimeoutSeconds1 – 305Tempo máximo para aguardar a resposta de um webhook de aplicação antes do timeout
webhookFailOpenAtivado / DesativadoAtivadoQuando habilitado, se um webhook de aplicação estiver inacessível ou expirar, a operação é permitida prosseguir
Webhook configuration section showing URL inputs for each event type, timeout slider, and fail-open toggle

Configuração de eventos de webhook

Disponibilidade de Webhooks de Aplicação

Webhooks de aplicação podem bloquear fluxos de autenticação. Se seu endpoint de webhook ficar indisponível e webhookFailOpen estiver desabilitado, nenhum usuário poderá fazer login. Use o modo fail-open, a menos que você tenha requisitos rígidos de conformidade que exijam bloqueio em caso de falha do webhook.

Verificar webhooks

Assim que qualquer URL de webhook é configurada, o Authagonal gera um segredo de assinatura por tenant (um valor whsec_… exibido somente leitura em Configurações → Webhooks). Cada entrega de saída traz um cabeçalho X-Authagonal-Signature: t=<unix>,v1=<hex>, onde v1 é HMAC-SHA256(secret, "{t}.{body}") calculado sobre o corpo bruto da requisição. Recalcule-o no seu endpoint e compare em tempo constante para confirmar que a requisição realmente veio do Authagonal e não foi adulterada — e rejeite entregas cujo t seja antigo demais para bloquear repetições.

Verificar um webhook (Node.js)
import crypto from 'node:crypto';

// rawBody MUST be the exact bytes Authagonal sent: verify before any JSON re-serialization.
function verifyAuthagonalWebhook(signatureHeader, rawBody, signingSecret) {
  const parts = Object.fromEntries(signatureHeader.split(',').map((p) => p.split('=')));
  const { t, v1 } = parts;

  // Replay protection: reject deliveries older than 5 minutes.
  if (Math.abs(Date.now() / 1000 - Number(t)) > 300) return false;

  const expected = crypto
    .createHmac('sha256', signingSecret)
    .update(`${t}.${rawBody}`)
    .digest('hex');

  return v1.length === expected.length &&
    crypto.timingSafeEqual(Buffer.from(v1), Buffer.from(expected));
}

Rotacionar o segredo de assinatura

Use Regenerar ao lado do segredo de assinatura para rotacioná-lo — por exemplo, após uma suspeita de vazamento. O segredo anterior é invalidado imediatamente, portanto atualize seu verificador com o novo valor, ou as entregas em andamento começarão a falhar na verificação de assinatura.

Janela de Manutenção

Defina uma janela de manutenção preferida para operações disruptivas, como mover os dados do seu locatário entre shards de armazenamento. Escolha uma hora UTC (0–23); o portal também exibe o horário equivalente no seu fuso horário local por conveniência.

Cadastro e acesso

Quem pode se tornar usuário no seu locatário, e sob quais condições essa pessoa pode entrar.

ConfiguraçãoPadrãoDescrição
Cadastro públicoAtivadoSe qualquer pessoa pode se registrar sozinha. Desativar oculta a página de registro e rejeita a API de registro, o que importa: ocultar apenas o link deixaria o endpoint aberto. Use quando você mesmo provisiona os usuários via SCIM, pela API ou por convites.
Exigir verificação de e-mail para entrarAtivadoUm endereço não confirmado não consegue entrar. Desative se o seu próprio aplicativo é que controla o acesso pela verificação; de qualquer modo, a claim email_verified continua viajando no token, então você mantém o sinal.
Registro dinâmico de clientesDesativadoPermite que um cliente se registre em tempo de execução conforme a RFC 7591, que é o que um agente de IA ou um conector MCP precisa antes de poder iniciar um fluxo. Desativado por padrão, e ativá-lo abre a porta apenas para o seu locatário. Os registros continuam com limite de taxa, exigindo PKCE e exigindo consentimento de qualquer forma.
Política de MFA do portalDesabilitadoMúltiplos fatores para a sua própria equipe ao entrar no portal, definido independentemente da política dos seus usuários finais. Desabilitado, oferecido no login ou obrigatório.
Máximo de usuáriosNenhumPor padrão, não há limite para o total de usuários, e nenhum plano define um. Enquanto o endereço de e-mail do proprietário do locatário não estiver verificado, aplica-se um limite temporário de 5 usuários; ele é removido definitivamente assim que o endereço é verificado.

Retenção de usuários inativos

Opcionalmente desative e depois exclua contas que ficaram sem uso, para que um diretório não acumule identidades dormentes para sempre. Ambos ficam desativados a menos que você os configure, e a exclusão é permanente.

ConfiguraçãoPadrãoDescrição
Desativar após (dias de inatividade)NuncaDesativa uma conta que não faz login há esse tempo. O registro é mantido e pode ser reativado.
Excluir após (dias de inatividade)NuncaExclui a conta permanentemente. Não há como desfazer, então configure a janela de aviso e o webhook abaixo antes de ativar isto.
Dias de aviso7Com quantos dias de antecedência de uma desativação ou exclusão o webhook de aviso dispara, dando a você tempo de intervir.
Webhook de retenção-Para onde esses avisos e as ações executadas são enviados, para que você possa avisar a pessoa ou manter a conta aberta.

Exportação de auditoria e backups remotos

Duas formas de tirar os seus dados de forma agendada, em vez de sob demanda. A exportação de auditoria envia cada dia completo de eventos de auditoria para uma URL que você indicar, assinada para que você verifique que veio de nós, servindo para alimentar um SIEM ou um arquivo de conformidade. Os backups remotos enviam cópias dos seus backups diários e semanais para um destino que você controla, sem autenticação, com autenticação básica ou com um bearer token. A exportação de auditoria é configurada na aba Exportar da página Registo de Auditoria, e os backups remotos na página Backups; ambos ficam sob a sua guarda, independentes dos backups que nós mantemos.

Ambientes Sandbox

A página Ambientes gerencia os ambientes sandbox: ambientes nomeados e isolados, com seus próprios usuários, clientes, chaves de assinatura, inscrições de MFA e concessões, cada um acessível em uma URL separada. Identidade visual, plano e faturamento são compartilhados com o live. Use-os para testar alterações de configuração, integrações SSO e endpoints de webhook sem afetar usuários em produção. Você pode criar até 5 por padrão, e os usuários ativos dos sandboxes contam para o seu MAU.

AçãoDescrição
Adicionar ambienteCria um novo ambiente. O nome tem de 1 a 20 letras minúsculas e dígitos, e "live" é reservado. O ambiente começa vazio: nada é copiado do live.
AtualizarApaga os dados do ambiente e o redefine para vazio.
EliminarExclui permanentemente o ambiente sandbox e todos os seus dados.

Cada ambiente pode ser acessado em {name}-{slug}.authagonal.io.

Environments page listing sandbox environments with their URLs and Refresh and Delete actions

Controles do ambiente sandbox

Faturamento

Gerencie sua assinatura e faturamento pela página de Faturamento do portal. Esta página oferece uma visão geral do seu plano atual e fornece acesso ao portal de faturamento do Stripe para gerenciar métodos de pagamento, faturas e alterações de plano.

Informações da Assinatura

A página de faturamento exibe os detalhes da sua assinatura atual de forma resumida. Você verá um badge de status indicando o estado da sua assinatura — active, trialing, past_due, canceled ou unpaid — junto com o nome do plano, o período de faturamento atual (datas de início e fim) e se sua assinatura está configurada para cancelar no final do período atual.

Gerenciar Assinatura

Clique no botão Gerenciar Assinatura para abrir o portal de faturamento do Stripe em uma nova janela. De lá, você pode atualizar seus métodos de pagamento, visualizar e baixar faturas, alterar seu plano ou cancelar sua assinatura.

Se nenhuma assinatura existir ainda, um call-to-action Configurar Faturamento é exibido, que o guia na seleção de um plano e inserção dos dados de pagamento.

Billing page showing subscription status, plan name, billing period, and Manage Subscription button

A página de faturamento exibe os detalhes da assinatura atual e fornece acesso ao Stripe

Segurança de Pagamento

Todo o faturamento é processado pelo Stripe. Suas informações de pagamento nunca são armazenadas nos servidores do Authagonal.

Domínios Personalizados

Sirva suas páginas de autenticação a partir do seu próprio domínio (ex: auth.seudominio.com) em vez do padrão {slug}.authagonal.io. Domínios personalizados proporcionam aos seus usuários uma experiência de autenticação contínua e com sua marca.

Adicionando um Domínio

Insira o hostname que deseja usar no formulário de adição de domínio (ex: auth.seudominio.com). Após adicionado, o domínio aparecerá na sua lista de domínios com o status pending_verification.

Verificação de DNS

Crie os dois registros CNAME que o portal mostra para o domínio, ambos apontando para {slug}.authagonal.io: um no próprio hostname, que serve o tráfego e pode passar por proxy, e outro em _authagonal-challenge. seguido do hostname, que comprova a propriedade e deve ser somente DNS (sem proxy). Quando os registros estiverem configurados, clique em Verificar DNS para verificar. Domínios pendentes também são verificados novamente de forma automática.

CNAME records
auth.yourdomain.com.                        CNAME  acme.authagonal.io.
_authagonal-challenge.auth.yourdomain.com.  CNAME  acme.authagonal.io.

Propagação de DNS

A propagação de DNS pode levar até 48 horas. Se a verificação falhar, aguarde e tente novamente.

Certificados TLS

Quando seu domínio for verificado, você precisará de um certificado TLS para que os usuários possam se conectar com segurança via HTTPS. Authagonal suporta duas opções:

Automático (cert-manager) — Authagonal provisiona e renova certificados TLS automaticamente usando cert-manager. Esta é a opção recomendada para a maioria dos usuários. Nenhuma configuração adicional é necessária.

Traga o Seu (BYO) — Faça upload do seu próprio certificado e chave privada em formato PEM. Esta opção é útil se sua organização exige certificados de uma autoridade certificadora específica. A expiração do certificado é monitorada para que você possa renová-lo antes de expirar.

Status do Domínio

Cada domínio exibe um badge de status indicando seu estado atual: pending_verification (DNS ainda não confirmado), verified (DNS confirmado, TLS pendente) ou active (totalmente operacional).

Domain list showing domains with status badges and verification controls

A lista de domínios exibe cada domínio personalizado e seu status atual

BYO certificate upload form with certificate and private key PEM fields

Faça upload do seu próprio certificado TLS e chave privada em formato PEM

Renovação de Certificado BYO

Mantenha seu certificado BYO renovado. Certificados expirados causarão avisos de segurança no navegador para seus usuários.

Organizações

Uma organização é um cliente dentro de um tenant. O tenant continua sendo o limite de isolamento: um prefixo de tabela e uma chave de assinatura, com cada host do tenant sendo o seu próprio issuer. Uma organização particiona a identidade dentro dele, de modo que um único tenant pode atender várias organizações clientes sem precisar de um tenant por cliente.

As organizações ficam ao lado dos domínios personalizados (um domínio pode ser fixado a uma) e dos apps de provisionamento (um app de provisionamento pode marcar um novo usuário com uma organização). Veja o guia Apps Multicliente para o padrão completo de "um tenant, vários clientes com marca própria" para o qual este recurso existe.

Modelo e ids

Toda organização tem um id estável e imutável (no formato org_<32 hex>), emitido como a claim de token org_id, e um slug imutável e único no tenant, emitido como org_slug e aceito pelo parâmetro de authorize organization. Ids e slugs compartilham um único espaço de busca: um slug igual ao id de outra organização é recusado como colisão, exatamente como um slug duplicado comum.

CampoMutávelDescrição
idNãoA claim org_id. Gerado como org_ + um GUID. O sublinhado não é válido em um slug, então um id novo nunca pode colidir com um slug.
slugNãoA claim org_slug e o que o parâmetro organization aceita. Imutável porque uma relying party o fixa no código.
nameSimA claim <code>org_name</code>. Editável livremente.
metadataSimPares chave/valor livres, controlados pelo tenant. Nunca emitidos em um token, a menos que o conjunto de claims de um scope libere um deles explicitamente.
brandingJsonSimObjeto JSON mesclado campo a campo sobre a marca do tenant. Veja Substituição de marca abaixo.
domainsSomente pelos endpoints de domínioOs domínios de e-mail que a organização reivindicou, cada um com o registro DNS que o comprova. Alterados somente pelos endpoints de domínio abaixo, nunca por uma atualização.

Associações

Uma associação é a junção muitos-para-muitos entre um usuário e uma organização: uma linha por par (organização, usuário). Um usuário pode ter várias; é a linha de associação, e não a antiga tag de organização por usuário, que autoriza entrar como uma organização.

StatusConcede tokens?
invitedConvidado, mas ainda não aceitou. Não autoriza a emissão de tokens.
activeUm membro em situação regular. O único status que autoriza a emissão de tokens.
suspendedAssociação retirada sem excluir o registro. Não autoriza a emissão de tokens.

Os roles de uma associação vêm do catálogo de funções já existente no tenant e são unidos na claim roles, mas somente quando a organização foi selecionada explicitamente pela requisição (veja Seleção de organização no token) e somente a partir de uma linha de associação ativa. Uma função mantida em uma organização nunca chega a um token emitido para outra.

Convidando para uma organização

POST /api/v1/users/invite aceita organizationId e organizationRoles opcionais. Uma única chamada cria a conta com uma associação invited e envia um e-mail de convite com a marca da organização. O link abre no domínio personalizado fixado da organização, quando ela tem um. Quando a pessoa aceita, a associação passa a active. Indicar uma organização exige um owner ou admin.

Provisionamento SCIM em uma organização

Um token SCIM pode ser vinculado a uma organização (organizationId em POST /api/v1/scim/tokens, ou o seletor de Organização ao criar um token). O id deve indicar uma organização do tenant. Todo usuário que esse token cria se torna um membro active e carrega a organização como org_id. O vínculo vale apenas na criação e decide a associação, não o acesso: dois tokens no mesmo cliente continuam vendo os usuários um do outro. Excluir um usuário, por qualquer via, remove as associações dele.

Flags de política

enabled (padrão ligado): uma organização desabilitada não emite tokens para si, verificado tanto no authorize quanto em cada refresh, de modo que desabilitar uma interrompe as sessões ativas na próxima rotação, e não apenas bloqueia novos logins.

requireMembershipForTokens (padrão ligado): define se um usuário precisa ter uma associação ativa para receber um token desta organização. Só tem efeito para uma seleção explícita (uma requisição que cita a organização, um refresh que a carrega, uma conexão com escopo de organização ou um cliente restrito a exatamente uma). Uma organização apenas herdada da tag legada da própria conta nunca é barrada por esta flag.

allowAutoMembership (padrão desligado) permite que um usuário entre sem convite quando o e-mail confirmado dele pertence a um dos domínios verificados da organização. É aplicado no authorize e em cada refresh. Veja Domínios de e-mail e associação automática abaixo.

Domínios de e-mail e associação automática

Uma organização reivindica um domínio de e-mail e prova que o controla com um registro DNS TXT. Com allowAutoMembership ligado, um usuário cujo e-mail confirmado pertence a esse domínio se torna membro na primeira vez que entra como a organização.

  1. Reivindique-o. POST /api/v1/organizations/{id}/domains com o domínio. A resposta é 201 com recordName (_authagonal-org.acme.com) e recordValue (authagonal-org-verify=<token>). O token é aleatório e exclusivo de cada reivindicação.
  2. Publique o registro. Adicione um registro TXT com esse nome e esse valor exato no DNS do domínio.
  3. Verifique-o. POST /api/v1/organizations/{id}/domains/{domain}/verify consulta o registro. Uma correspondência retorna 200 com verified: true. Uma falha retorna 409 verification_failed, nunca 200 com verified: false, para que um cliente que faz polling por sucesso não confunda uma falha com um sucesso.
  4. Remova-o. DELETE /api/v1/organizations/{id}/domains/{domain} retorna 204. As associações existentes permanecem; apenas as entradas automáticas futuras deixam de acontecer.
POST /api/v1/organizations/{id}/domains
POST /api/v1/organizations/org_7fa2c9e1.../domains
Content-Type: application/json

{ "domain": "acme.com" }

201 Created
{
  "domain": "acme.com",
  "verified": false,
  "verifiedAt": null,
  "createdAt": "2026-10-03T01:02:03Z",
  "recordName": "_authagonal-org.acme.com",
  "recordValue": "authagonal-org-verify=Qm9...base64url"
}

Recusas: 400 domain_invalid (não é um nome DNS simples), 409 domain_exists (já está nesta organização), 409 domain_taken (outra organização do tenant o possui), 404 organization_not_found e 404 domain_not_found. Um domínio pertence a no máximo uma organização por tenant, e isso é verificado novamente no momento da verificação.

A regra de associação automática

O seletor admite um usuário que não tem associação ativa quando todas as condições abaixo são verdadeiras:

  • A organização foi selecionada explicitamente: um refresh grant carregado, uma conexão com escopo de organização, o parâmetro organization (um domínio fixado o fornece) ou um cliente restrito a exatamente uma organização. A tag legada da própria conta nunca faz entrada automática.
  • A organização está habilitada e allowAutoMembership está ligado.
  • O e-mail do usuário está confirmado, porque qualquer pessoa pode se cadastrar como [email protected].
  • A parte do e-mail após o último @, em minúsculas, é exatamente igual a um dos domínios da organização que foi verificado. Não há correspondência de subdomínio: um acme.com verificado não admite [email protected]. Reivindique e verifique cada subdomínio separadamente.

O que ela grava, antes de a barreira de associação rodar: nenhuma linha vira uma nova associação active sem funções; uma linha invited é promovida a active mantendo as funções; uma linha active é deixada como está; uma linha suspended nunca é promovida.

Excluir um membro não o mantém de fora

Enquanto allowAutoMembership estiver ligado, um membro excluído que ainda se qualifica volta a entrar no próximo authorize ou refresh. Para manter de fora um usuário que se qualifica, defina a associação dele como suspended, o único estado que a regra nunca altera.

Seleção de organização no token

A organização para a qual uma requisição é resolvida é decidida em um único lugar, então a resposta é idêntica em /connect/authorize, em cada refresh e no device grant. Precedência, da maior para a menor:

#OrigemComportamento
1Grant carregado (refresh)A organização para a qual um token anterior foi emitido. Se ela não existir mais, o próprio refresh é recusado, em vez de recorrer a qualquer outra coisa.
2Conexão com escopo de organizaçãoA sessão entrou por uma conexão SAML ou OIDC que pertence a uma organização, então essa organização é selecionada. É a única origem que é comprovada, e não apenas declarada. Uma requisição que cita uma organização diferente é recusada, assim como uma conexão cuja organização não existe mais.
3organizationResolvida primeiro por slug, depois por id. Um domínio fixado chega a esta mesma ramificação: o middleware o anexa antes de a requisição ser avaliada. Indicada e não encontrada é uma recusa firme, nunca um fallback silencioso.
4Cliente restrito a exatamente uma organizaçãoSelecionada automaticamente: um aplicativo por cliente registra sua única organização uma vez e nunca envia um parâmetro. Restrito a <em>mais</em> de uma, sem nenhuma indicação, é recusado com <code>account_selection_required</code>.
5Tag de organização legada da própria contaUma única string simples, resolvida por id em uma só consulta, e não uma varredura das associações do usuário. Se ela não indicar nenhuma linha de organização real, é emitida literalmente e sem barreira, exatamente como antes de as organizações existirem. Nunca é uma seleção explícita, então nunca faz entrada automática.
6Nenhuma das anterioresNenhuma organização no token: nem a claim <code>org_id</code>, nem <code>org_slug</code>, nem <code>org_name</code>.

As associações nunca são a indicação

Um usuário com várias associações ativas e uma requisição que não cita nenhuma se comporta de forma idêntica a um usuário com zero associações: a tabela de associações nunca é consultada para escolher um padrão. A seleção cai direto na tag legada da própria conta (linha 5) e, se ela também estiver vazia, o token não carrega organização alguma. As associações só passam a importar depois que uma organização já foi citada explicitamente, que é quando requireMembershipForTokens é verificado e, se ele se aplicar, uma entrada automática é tentada.

Fixação de domínio

Um domínio personalizado pode ser fixado a uma organização, tornando esse domínio a porta de entrada própria da organização. A fixação é aplicada pelo middleware de resolução de tenant tanto em GET /connect/authorize (anexada à query string) quanto em POST /connect/par (o corpo enviado é reescrito, já que o PAR lê seus parâmetros do payload armazenado). Veja Domínios Personalizados para o mecanismo completo.

PUT /api/v1/custom-domains/{domain}/organization
PUT /api/v1/custom-domains/auth.acme.com/organization
Content-Type: application/json

{ "organizationId": "org_7fa2c9e1..." }

Um domínio fixado recusa uma requisição conflitante

Uma requisição que cita uma organização diferente da fixação é recusada diretamente com 400 access_denied, antes de qualquer página de login ser exibida. Sem isso, uma relying party poderia enviar seu próprio parâmetro organization e a fixação seria puramente decorativa.

Conexões com escopo de organização

Uma conexão SAML ou OIDC pode pertencer a uma organização. Entrar por ela seleciona essa organização e cria uma associação active quando o usuário não tem nenhuma. Uma linha invited é aceita: passa a active e mantém suas funções e o convidador, de modo que quem foi convidado e entra pelo seu IdP nunca precisa do e-mail. Um membro suspended continua suspenso e é recusado na emissão do token. Isso não depende de allowAutoMembership nem de domínios, porque a organização já foi escolhida pela conexão.

O nome da organização na página de login

A página de login mostra Entrando em {name} abaixo do nome do app. O nome vem da mesma organização da qual vem a marca da página: a organização do domínio fixado, depois a organização citada na requisição authorize, depois a única organização restrita do cliente. Fica oculto quando não há organização, ou quando o nome da organização é igual ao nome do app, para que o cabeçalho nunca diga "Acme / Entrando em Acme".

Substituição de marca

O brandingJson de uma organização é mesclado campo a campo sobre a marca do tenant na página de login: uma chave presente e não nula substitui, uma chave ausente ou nula herda, e uma chave desconhecida é ignorada. JSON malformado volta à marca do próprio tenant com um aviso registrado em log, nunca uma falha no carregamento da página.

A aba Marca edita todos os 21 campos mescláveis: aparência (appName, logoUrl, primaryColor, customCssUrl), cores dos modos claro e escuro, cores de e-mail, supportEmail, showForgotPassword, poweredBy e languages. Cada campo herda o valor do tenant, mostrado como dica, ou o substitui, com um controle Limpar que remove a chave.

showRegistration não pode ser substituído

A configuração de cadastro público do tenant já decidiu se o registro é oferecido, e o endpoint de registro aplica isso independentemente da marca. Uma organização não é a autoridade para essa decisão, então este único campo fica fora da mesclagem e não tem controle na aba Marca.

Preenchimento a partir da tag de organização legada

Antes de as organizações existirem, um usuário podia carregar uma tag de organização em texto livre, sem nenhum registro por trás. POST /api/v1/organizations/backfill migra isso para organizações e associações reais, agrupadas por cada valor legado distinto. É apenas uma simulação (dry run), a menos que o corpo seja { "dryRun": false }.

  • Limitado: varre no máximo 50.000 usuários por chamada. Uma resposta truncated significa que é preciso executá-lo de novo; usuários já migrados são ignorados na nova execução.
  • Idempotente: um valor legado distinto já migrado é reconhecido por um carimbo interno, e não pelo nome de exibição (editável) da organização, então renomear a organização resultante depois não causa uma duplicata na execução seguinte.
Exemplo de resposta (dry run)
{
  "dryRun": true,
  "organizationsCreated": 3,
  "membershipsCreated": 41,
  "usersSkipped": 0,
  "organizations": [
    { "legacyValue": "acme-corp", "slug": "acme-corp", "users": 22 }
  ],
  "truncated": false
}

Tour pela interface do portal

A página Organizações lista todas as organizações do tenant, 50 por vez com um botão Carregar mais, e oferece Nova Organização (apenas slug + nome; flags de política, domínios e marca são definidos depois) e um fluxo Preencher do campo de organização legado que executa o preenchimento acima primeiro como pré-visualização e depois com Aplicar.

Organizations list showing slug, name, and created-date columns, with New Organisation and Backfill from legacy organisation field controls

A lista de organizações mostra todas as organizações clientes do tenant com slug, nome e data de criação

A página de detalhe de cada organização tem três abas: Geral (nome, slug somente leitura, os três toggles de política, um cartão de Domínios de e-mail para adicionar, verificar e remover domínios de e-mail e copiar o registro TXT, e uma exclusão que exige digitar o slug para confirmar), Branding (todos os campos substituíveis, cada um herdando o valor do tenant ou substituindo-o) e Membros (adicionar por e-mail, com um convite oferecido quando não existe conta, alteração de status e remoção por linha, com Carregar mais).

Organization detail page's Members tab showing invited, active, and suspended member rows with per-row status control

A aba Membros lista cada associação com seu status e um controle por linha para alterá-la ou removê-la

Organization detail page's Branding tab with each overridable field showing either the tenant's inherited value or an override with a Clear control

A aba Marca substitui, campo a campo, a marca da página de login do tenant para esta organização

A página Domínios traz o seletor domínio → organização: cada cartão de domínio tem um dropdown embutido que lista as organizações do tenant mais uma opção "Tenant (nenhum)" que remove a fixação, aplicado imediatamente ao alterar. O mesmo seletor aparece ao adicionar um domínio.

Domain card showing the inline organisation selector that pins a custom domain to one organisation

O seletor de organização embutido em um cartão de domínio fixa esse domínio personalizado a uma organização

Eventos de auditoria

organization.created · organization.updated · organization.deleted · organization.member.added · organization.member.invited · organization.member.joined · organization.member.updated · organization.member.removed · organization.domain_added · organization.domain_verified · organization.domain_removed · organization.backfill · domain.organization_set

Paginação

A lista de organizações e a lista de membros usam paginação por cursor e respondem { items, nextCursor }. Passe limit (padrão 50, limitado de 1 a 200) e, depois da primeira página, o nextCursor da resposta anterior, sem alterações, como cursor. Um nextCursor nulo é a última página. O cursor é uma posição keyset opaca sobre o id da organização (ou o id do usuário, para membros), então adicionar ou remover linhas entre chamadas não pode deslocar nem repetir uma página. Um cursor que a listagem não emitiu resulta em 400 invalid_cursor.

Gerenciando organizações a partir de um assistente de IA

O MCP hospedado do portal expõe treze ferramentas de organização, todas exigindo a função de admin do tenant: listar, obter, criar, atualizar e excluir organizações; listar, adicionar, atualizar e remover membros; adicionar, verificar e remover domínios de e-mail; e listar as organizações de um usuário. Elas chamam as mesmas operações da API acima, então uma ferramenta não pode divergir da sua rota. Veja Opere seu portal a partir de um assistente de IA.

Um issuer por host

Cada host de um tenant é o seu próprio issuer OIDC. Quando o host da requisição foi resolvido pela tabela de domínios do tenant, o issuer e toda URL de endpoint anunciada pelo discovery é https://{host}, então cada domínio personalizado ativo declara o seu próprio iss e o host canônico do tenant permanece inalterado. As chaves de assinatura são por tenant, então todo host serve o mesmo conjunto de chaves. É isso que permite a um tenant atender vários clientes, cada um em seu próprio domínio com marca, fixado à sua própria organização. Veja Domínios Personalizados.

Configuração de e-mail

Configure como seu locatário envia e-mails transacionais, como os de verificação, redefinição de senha e convite. Escolha entre o remetente compartilhado padrão, um domínio personalizado verificado via Resend ou seu próprio servidor SMTP.

Email settings showing provider options (default, Resend domain, custom SMTP) and a test-send

E-mails localizados

Os e-mails transacionais são enviados no idioma preferido do destinatário. Os e-mails de verificação, redefinição de senha, conta existente, boas-vindas, convite, exclusão de conta, suporte e cobrança têm modelos em onze idiomas: inglês, alemão, francês, espanhol, português, vietnamita, chinês simplificado, japonês, árabe, hindi e africâner. Quando não existe um modelo para o idioma do destinatário, o e-mail recorre ao inglês.

O idioma é resolvido a partir da preferência armazenada do destinatário no momento do envio. Essa preferência pode vir de vários lugares:

  • Cadastro e registro — capturado do idioma que o usuário escolheu nas telas de login hospedadas.
  • A página de Usuários do portal — definida por um administrador ao criar ou editar um usuário.
  • O provisionamento SCIM: mapeado do preferredLanguage (ou locale) do IdP quando os usuários são sincronizados via SCIM.
  • A página de conta de autoatendimento — escolhida pelo próprio usuário em /login/account.

Nenhuma configuração necessária

A localização é automática e se aplica a todos os modos de provedor (padrão, domínio personalizado do Resend e SMTP). Não há nada para ativar.

Provedores de e-mail

ProvedorDescriçãoConfiguração
Authagonal (Default)E-mails enviados de [email protected] usando nossa infraestrutura Resend compartilhada.Nenhuma configuração necessária — funciona imediatamente.
Custom Domain (Resend)E-mails enviados do seu próprio domínio verificado via Resend.Registre seu domínio, adicione registros DNS, verifique a propriedade.
Custom SMTPE-mails enviados através do seu próprio servidor SMTP.Forneça host, porta, credenciais e configurações TLS do SMTP.

Identidade do remetente

O e-mail e o nome do remetente são compartilhados entre todos os modos de provedor. O e-mail do remetente é obrigatório para os provedores Domínio personalizado (Resend) e SMTP personalizado; o nome do remetente volta para o nome do aplicativo definido na identidade visual quando vazio.

CampoDescrição
emailSenderEmailO endereço From nos e-mails enviados. Deve estar em um domínio verificado no modo Domínio personalizado (Resend).
emailSenderNameNome de exibição mostrado na caixa de entrada do destinatário.

Domínio personalizado Resend

Verifique seu domínio de envio com o Resend uma vez e então use-o como endereço From para este locatário. Os registros DNS (SPF, DKIM) são mostrados no painel Domínio de envio personalizado em Definições → E-mail; o Resend os verifica quando você clica em <strong>Verificar</strong>.

SMTP personalizado

Traga seu próprio servidor SMTP — útil para relays internos, provedores não cobertos pelo Resend ou fixação regulatória.

CampoDescrição
smtpHostHostname do servidor SMTP (ex. smtp.example.com).
smtpPortPorta de conexão, padrão 587. O TLS é negociado com STARTTLS; TLS implícito na porta 465 não é suportado. Use 25 para relays internos não autenticados.
smtpUsernameUsuário de autenticação (opcional — deixe em branco para relays sem autenticação).
smtpPasswordSenha de autenticação. Armazenada criptografada no segredo de configurações do locatário.
smtpUseTlsExigir TLS. Deixe ativado, a menos que esteja usando um relay interno confiável.

Domínio de envio personalizado

Ao usar o provedor Domínio personalizado (Resend), você pode registrar seu próprio domínio para que os e-mails venham da sua marca (por exemplo, [email protected]) em vez de @authagonal.io.

  1. Vá para Definições → E-mail e selecione o provedor Domínio personalizado (Resend).
  2. Digite o nome do seu domínio e clique em Registrar domínio.
  3. Adicione os registros DNS exibidos (DKIM, SPF e return path) ao DNS do seu domínio.
  4. Clique em Verificar — assim que o DNS propagar (normalmente 1–10 minutos), o status do domínio mudará para verificado.

Propagação de DNS

Mudanças de DNS podem levar até 48 horas para propagar globalmente, embora a maioria dos provedores atualize em minutos. Você pode verificar quantas vezes precisar.

Testes

Use o botão Enviar e-mail de teste em Configurações → E-mail para verificar sua configuração. Um e-mail de teste será enviado ao endereço de administrador usando as configurações salvas.

Registro de Auditoria

O Registro de Auditoria fornece um registro somente leitura de todas as ações administrativas realizadas no seu locatário. Cada alteração feita pelo portal ou API é capturada com contexto completo, proporcionando um rastro completo para conformidade e resolução de problemas.

Colunas do Registro

ColunaDescrição
Data/HoraA data e hora em que a ação ocorreu
AtorO endereço de e-mail do administrador que realizou a ação, ou "system" para ações automatizadas
AçãoO tipo de ação realizada (ex: Client Created, Settings Updated)
EntidadeO alvo da ação no formato tipo:id (ex: client:my-app)
DetalheContexto adicional sobre a alteração

Ações Rastreadas

As seguintes ações administrativas são registradas no registro de auditoria:

CategoriaAções
ClientesClient Created, Client Updated, Client Deleted
Conexões SSOSAML Connection Created, SAML Connection Deleted, OIDC Connection Created, OIDC Connection Deleted
UsuáriosUser Created, User Updated
ConfiguraçõesSettings Updated, Branding Updated
DomíniosDomain Added, Domain Verified, Domain Deleted
SCIMSCIM Token Created, SCIM Token Revoked
FunçõesRole Created, Role Updated, Role Deleted
GruposGroup Created, Group Deleted
EquipeTeam Member Invited, Team Member Removed
Audit log table showing timestamped administrative actions with actor, action, entity, and detail columns

O registro de auditoria fornece um registro completo de todas as ações administrativas

Retenção

Registros de auditoria são retidos por 365 dias e não podem ser modificados ou excluídos. Para mantê-los por mais tempo, ative a exportação automática na aba Exportar da página Registo de Auditoria.

Backups

O Authagonal faz backup automático dos dados do seu locatário a cada hora. Os backups incluem todos os usuários, grupos, funções, clientes, conexões SSO, tokens SCIM, marca e configurações. Você pode ver o histórico de backup e baixar o backup completo mais recente na página Backups.

Backups page showing backup history with timestamps, types, and entity counts

Como os backups funcionam

  • Uma vez por dia, os incrementais de hora em hora são consolidados em um novo backup completo e, aos domingos, os backups completos diários são consolidados em um backup semanal. São mantidos sete backups diários e quatro semanais.
  • Backups incrementais são executados a cada hora, capturando apenas as linhas que mudaram desde o último backup.
  • Os backups são armazenados no Azure Blob Storage com a mesma identidade gerenciada usada pelo seu locatário.
  • Registros excluídos são rastreados via tombstones e incluídos em backups para completude de auditoria.

Baixando backups

Clique em "Baixar mais recente" para obter um arquivo ZIP contendo o backup completo mais recente mesclado com todos os backups incrementais subsequentes. Cada tabela é exportada como um arquivo JSONL (um objeto JSON por linha).

Formato de backup

Os backups são exportados como JSONL (JSON Lines) — uma entidade por linha por tabela. Esse formato é fácil de analisar, comparar e importar em outros sistemas.

Apps de Provisionamento

Os apps de provisionamento são serviços seus, chamados pelo Authagonal sempre que um usuário é criado, para que possam configurar uma conta, atribuir uma licença, decidir a qual organização o usuário pertence ou recusar o cadastro por completo.

Como Funciona

Quando um usuário é criado, o Authagonal chama a URL de callback do seu app de provisionamento usando o padrão TCC (Try/Confirm/Cancel). Todos os apps precisam aceitar na fase Try antes que qualquer um deles seja confirmado, de modo que vários sistemas downstream possam concordar, ou um possa vetar, sem deixar para trás contas criadas pela metade.

FaseEndpointFinalidade
/tryPOST {callbackUrl}/tryVerifica se o app pode processar o usuário. Retorne 200 para aceitar ou 4xx para rejeitar.
/confirmPOST {callbackUrl}/confirmConfirma a operação após todos os apps aceitarem a fase /try.
/cancelPOST {callbackUrl}/cancelReverte a operação se outro app falhar durante a fase /try.

Quando o provisionamento é executado

O provisionamento é executado em todo caminho que cria um usuário, não apenas no cadastro self-service. Combinações de app e usuário já provisionadas são ignoradas, então um app vê cada usuário uma única vez.

Caminho de criaçãoQuando dispara
POST /api/auth/registerRegistro self-service
Callback do SAML ACSPrimeiro login SSO de um novo usuário (JIT)
Callback OIDCPrimeiro login SSO de um novo usuário (JIT)
POST /scim/v2/UsersUm conector provisiona um usuário a partir do diretório do cliente
Criação de usuário no portal e no adminUm operador cria ou convida um usuário manualmente

A requisição Try

O Authagonal envia este JSON por POST para <code>{callbackUrl}/try</code>. Campos sem valor são omitidos em vez de enviados como null.

CampoTipoDescrição
transactionIdstringIdentifica esta transação de provisionamento. O mesmo valor é enviado para /confirm e /cancel, então prepare seu trabalho com base nele e confirme ou descarte quando essa chamada chegar.
userIdstringO id do usuário no Authagonal. Este é o subject que você verá nos tokens dele.
emailstringO endereço de e-mail do usuário.
firstNamestringNome, quando o caminho de criação forneceu um.
lastNamestringSobrenome, quando o caminho de criação forneceu um.
organizationIdstringA organização em que o usuário já está, se houver. Presente apenas quando algo já atribuiu uma; em um primeiro cadastro ela está ausente, o que é a sua deixa para atribuí-la.
customAttributesobjectOs atributos personalizados armazenados do usuário. Para um usuário criado por SSO, isso inclui federated_connection, o nome da conexão que o avalizou.

Um usuário que chega por SSO é o caso comum que vale a pena prever: ele ainda não tem organização, e federated_connection informa de qual dos seus clientes ele veio.

Requisição Try para um usuário que chega por uma conexão SSO
{
  "transactionId": "8f14e45fceea167a5a36dedd4bea2543",
  "userId": "0f6b1c8e-3d2a-4f51-9e77-2c1a4b5d6e7f",
  "email": "[email protected]",
  "firstName": "Ada",
  "lastName": "Lovelace",
  "customAttributes": {
    "federated_connection": "acme-okta"
  }
}

A resposta Try

Seu app responde com 200 e um corpo JSON. O corpo não é apenas uma confirmação de recebimento: é assim que um app downstream atribui a organização e os atributos que acabam nos tokens do usuário.

CampoTipoDescrição
approvedbooleanSe este app aceita o usuário. Assume true quando omitido. False rejeita o cadastro e a nova conta é excluída.
reasonstringPor que o usuário foi rejeitado. Exibido a quem chamou o caminho de criação.
organizationIdstringA organização à qual este usuário pertence. Armazenada no usuário e emitida como a claim org_id nos tokens dele. Aplicada apenas se o usuário ainda não tiver uma, então o primeiro app a responder vence e os apps seguintes veem essa atribuição.
customAttributesobjectAtributos a mesclar no usuário, chave por chave. Emitidos nos tokens através da configuração UserClaims de um scope.
emailVerifiedbooleanSeu app garante que verificou este endereço, por exemplo pelo resgate de um convite enviado a ele. O Authagonal marca a conta como confirmada e pula o próprio e-mail de verificação.
Resposta Try atribuindo uma organização
{
  "approved": true,
  "organizationId": "org_acme",
  "customAttributes": { "org_role": "member" }
}

É daqui que vem o org_id

A tag de organização da conta, e portanto a claim org_id quando uma requisição não nomeia nenhuma organização, é exatamente o que o seu app de provisionamento retornou como organizationId. Quando é o id de uma organização do tenant, os tokens carregam org_id, org_slug e org_name dessa organização, e uma organização desativada recusa o login. Qualquer outro valor é emitido literalmente como org_id, sem regra de unicidade e sem exigência de formato. Retornar um id de organização não cria uma associação. Você também pode defini-lo diretamente com PUT /api/v1/users/{userId}, e filtrar por ele com GET /api/v1/users?organizationId=.

Marcando usuários com a organização certa

Decida a organização aqui, em um único lugar, em vez de em cada caminho de criação. Um usuário SSO carrega federated_connection, que identifica a conexão que o autenticou e, portanto, o cliente, e continua correto quando um mesmo cliente federa vários domínios de e-mail. Um usuário convidado não tem conexão, então identifique-o pelo convite que você emitiu. Os dois caminhos chegam a /try antes de o usuário existir, então uma única lógica cobre ambos e não há duas regras para divergirem.

Resolvendo a organização no callback Try
// POST {callbackUrl}/try
app.post('/provisioning/try', async (req, res) => {
  const { email, customAttributes } = req.body;

  // An SSO user carries the connection that vouched for them. That is the
  // customer, and it stays right when one customer has several domains.
  const connection = customAttributes?.federated_connection;

  const org = connection
    ? await orgByConnection(connection)
    : await orgByPendingInvite(email);

  if (!org) return res.json({ approved: false, reason: 'No organization for this user' });

  // Stamped on the user and emitted as org_id on every token from now on.
  res.json({ approved: true, organizationId: org.id });
});

A rejeição exclui a conta

Se qualquer app responder approved: false, o usuário recém-criado é excluído para que nenhuma conta provisionada pela metade fique para trás. Os caminhos de criação da API retornam 422 com o seu reason; os callbacks SAML e OIDC retornam 400. Retorne approved: true para um usuário com o qual você não tem nada a fazer.

Adicionando um App de Provisionamento

Para adicionar um app de provisionamento, forneça um Nome da aplicação, uma Callback URL, uma API Key opcional e um Timeout do Try opcional (em segundos, padrão 60, intervalo de 5 a 300; Confirm e Cancel usam um timeout curto fixo). A chave de API é enviada como token Bearer no cabeçalho Authorization de cada requisição de webhook, permitindo que seu app autentique requisições do Authagonal.

Testes

Clique em Testar ao lado de qualquer app de provisionamento para enviar uma requisição de teste à sua URL de callback. Os resultados do teste exibem o código de status HTTP e o corpo da resposta, ajudando você a verificar se seu app está recebendo e processando webhooks corretamente.

Provisioning apps page showing configured apps with test results displaying HTTP status and response body

Teste apps de provisionamento para verificar a entrega e o tratamento de resposta de webhooks

Limites do Plano

O número máximo de apps de provisionamento é configurável por locatário, com um limite padrão de 6. Este limite pode ser ajustado por um administrador se seu fluxo de trabalho exigir alvos de provisionamento adicionais.

Autenticação por Chave de API

Se uma chave de API estiver definida, ela é enviada como token Bearer no cabeçalho Authorization. Use isso para autenticar requisições de webhook do Authagonal.

Equipe

A página de Equipe gerencia os administradores do portal: as pessoas que podem acessar e configurar seu locatário através do portal de gerenciamento. Cada membro da equipe tem uma função (Owner, Admin, Developer ou Support) que decide o que ele pode alterar.

Lista de Administradores

A lista de administradores exibe o nome, endereço de e-mail, função e data de adição de cada membro da equipe. Um indicador "Você" é exibido ao lado da linha do usuário atual para que você possa identificar facilmente sua própria conta.

Convidando Administradores

Para convidar um novo membro da equipe, forneça o endereço de e-mail, o nome e a função. A pessoa recebe um e-mail com um link para definir a senha e ativar a conta; o link é válido por 7 dias.

Campos do convite

Convites de administrador criam uma conta pendente e enviam ao convidado um link de ativação por e-mail.

CampoDescrição
emailEndereço de e-mail do novo admin. Deve ser único no locatário.
nameNome exibido na lista de administradores.
roleFunção a conceder: tenant:admin, tenant:developer ou tenant:support. O padrão é tenant:admin. A função de proprietário não pode ser concedida por convite.

Removendo Administradores

O proprietário do locatário pode clicar em Remover ao lado de qualquer membro da equipe para revogar seu acesso. Um diálogo de confirmação é exibido antes que a remoção seja finalizada. Você não pode remover a si mesmo, e o locatário sempre mantém o seu proprietário.

Team page showing the admin list with name, email, date added columns, a You indicator, and invite/remove controls

Gerencie administradores do portal na página de Equipe

Propriedade

Cada locatário tem um único proprietário. Somente o proprietário pode remover membros da equipe ou transferir a propriedade, usando Tornar Owner em outro membro; o proprietário anterior passa a ser Admin.

Suporte

Abra um ticket de suporte com a equipe Authagonal sem sair do portal. Cada ticket é uma conversa encadeada, então você e nossa equipe ficam alinhados desde o primeiro relato até a resolução.

Seus tickets

A página de suporte lista todos os tickets que você abriu, com a atividade mais recente primeiro. Use o badge de status para ver rapidamente o que está aguardando você e o que está aguardando a gente.

Support ticket list showing each ticket's subject, status badge, priority, and last-activity time, with a New ticket button

Seus tickets de suporte com assunto, status, prioridade e última atividade

  • Cada linha mostra o assunto, o status atual (aberto, pendente, resolvido ou fechado), a prioridade e o horário da última atividade.
  • Clique em Novo ticket para abrir um e, em seguida, dê a ele um assunto, uma prioridade e sua primeira mensagem.
  • Badges de status com cores facilitam varrer a lista em busca de tickets que precisam da sua atenção.

Uma conversa de ticket

Ao abrir um ticket, você vê a conversa completa. As respostas aparecem em ordem e novas mensagens da nossa equipe surgem sem recarregar a página.

Support ticket thread showing the conversation between the customer and the Authagonal team with a reply box and file attachment control

Uma conversa de ticket entre você e a equipe Authagonal

  • As mensagens encadeadas entre você e a equipe Authagonal são exibidas em ordem cronológica.
  • Responda ali mesmo e anexe arquivos para compartilhar logs, capturas de tela ou configuração.
  • A conversa é atualizada ao vivo, então uma resposta da nossa equipe aparece assim que é enviada.
  • Se você responder ao e-mail de notificação em vez disso, sua mensagem é encadeada automaticamente.

Como as respostas chegam até você

A equipe Authagonal trabalha os tickets pelo lado do admin. Você é notificado por e-mail sempre que a equipe responde, então não precisa deixar o portal aberto para acompanhar uma conversa.

Central de suporte para os seus usuários

Separada do suporte que você recebe de nós, o Authagonal pode operar uma central de suporte para os seus usuários finais. Eles abrem tickets a partir das páginas de conta, no host com a marca do seu próprio locatário, e a sua equipe responde pelo portal.

Ela existe porque as pessoas que não conseguem entrar são exatamente as pessoas que não conseguem chegar a uma ferramenta de suporte que exige entrar. A central fica ao lado das telas de login, então um usuário bloqueado ainda tem um caminho, e todo ticket chega já vinculado a uma conta real do seu diretório, e não a um endereço qualquer que alguém digitou.

Como ativar

Abra Suporte ao cliente no portal, vá para a aba Configurações e ative Ativar suporte ao cliente. A aba está disponível para proprietários e administradores. Nada fica visível para os seus usuários até que você faça isso.

ConfiguraçãoO que faz
Ativar suporte ao clienteA chave geral. Desativado, tanto as páginas dos usuários finais quanto a caixa de entrada dos seus operadores ficam ocultas e as APIs delas respondem 404.
Permitir pedidos de visitantes sem sessão iniciadaPermite que um visitante não autenticado abra um ticket, que é o caso de quem está bloqueado para fora. Protegido por uma verificação anti-bot, e a conversa continua por e-mail mais um link privado, já que não há conta na qual entrar.
Notificações por e-mailQuem recebe e-mail quando um ticket chega ou um usuário responde: ninguém, endereços específicos ou toda a sua equipe de suporte (proprietários, administradores e suporte), para que ninguém precise ficar olhando a caixa de entrada.
Default customer languageO idioma assumido para um usuário quando ainda não sabemos o dele, para os tickets e e-mails dele. O idioma salvo do próprio usuário sempre prevalece e, sem nada definido, é o inglês. Esta configuração fica na aba <strong>Geral</strong> de Definições.
URL do webhook de suporteUma URL para a qual enviar eventos de ticket por POST, para levá-los às suas próprias ferramentas.

Não disponível no plano Free

A central de suporte é o único recurso que o plano Free não inclui, porque e-mail de entrada e tradução têm custo real por uso. Todo plano pago tem. Recursos de autenticação nunca são restringidos dessa forma: single sign-on, SCIM, múltiplos fatores, domínios personalizados, personalização de marca e auditoria estão em todos os planos, inclusive no Free.

O que os seus usuários veem

Usuários autenticados têm uma área de suporte nas páginas de conta, no host do seu locatário, com a sua marca. Eles podem abrir um ticket, ver tudo o que já abriram e responder dentro da conversa. As respostas da sua equipe também chegam por e-mail, então o usuário não precisa ficar conferindo.

Com os tickets anônimos ativados, alguém que não consegue entrar ainda pode abrir um. A pessoa informa um endereço de e-mail e a mensagem, e recebe de volta um link privado para a conversa. Esse link é a única forma de entrar, então trate-o como uma credencial: ele é impossível de adivinhar, e qualquer pessoa que o tenha pode ler e responder aquela conversa.

A caixa de entrada dos operadores

A sua equipe responde por Suporte ao cliente no menu lateral do portal. É um lugar separado dos seus próprios tickets conosco, e está disponível para a função tenant:support e superiores, então você pode dar a um agente acesso à central sem lhe dar o resto do portal.

AçãoO que faz
ResponderPublica na conversa. O usuário recebe um e-mail e vê a mensagem ao vivo se estiver com a página aberta.
AtribuirEntrega um ticket a um membro específico da sua equipe, para que duas pessoas não respondam o mesmo.
Status e prioridadeMove um ticket entre aberto, pendente, resolvido e fechado, e marca o quanto ele é urgente. Tickets fechados são excluídos após um período de retenção, em vez de guardados para sempre.
Notas internasNotas visíveis apenas para a sua equipe, nunca para o usuário. Edições e exclusões são registradas no log de auditoria.
Abrir em nome de um usuárioInicia uma conversa com um dos seus usuários escolhendo-o no seu diretório, para quando a conversa começou em outro lugar.
Escalar para o AuthagonalSe um ticket acabar sendo sobre o Authagonal e não sobre o seu produto, escale-o. Isso abre um ticket vinculado com a nossa equipe, opcionalmente levando a conversa até ali, e liga os dois para que você possa acompanhar ambos. Um ticket só pode ser escalado uma vez.

Os usuários escrevem no próprio idioma

Um ticket é armazenado no idioma em que o usuário o escreveu, e cada pessoa na conversa o lê no dela. O seu agente vê a mensagem traduzida para o idioma do portal dele, o usuário vê a sua resposta traduzida para o idioma dele, e o texto original é sempre mantido ao lado. O idioma é detectado a partir da primeira mensagem e fixado no ticket. As traduções são calculadas uma vez por idioma e reaproveitadas, então uma conversa longa não se traduz de novo.

Fusos horários

Um ticket registra o fuso horário a partir do qual o usuário o abriu. Cada mensagem passa a mostrar o horário local dele ao lado do seu, então uma resposta às 14:32 aparece como as 02:32 que ela realmente eram para quem estava esperando. Nada é mostrado quando o fuso é desconhecido, como em um ticket que chegou por e-mail, ou quando ele coincide com o seu.

Webhooks

Defina uma URL de webhook de suporte para receber os eventos de ticket conforme eles acontecem, seja para disparar um alerta ou para espelhar tickets no seu próprio sistema. Os payloads são assinados, então você pode verificar que vieram de nós.

EventoO que faz
support.ticket.createdUm usuário abriu um ticket.
support.ticket.messageUma mensagem foi publicada em uma conversa, por um usuário ou por um dos seus operadores. O campo fromStaff no payload indica qual dos dois.
support.ticket.status_changedO status de um ticket mudou, por exemplo para resolvido.
support.ticket.assignedUm ticket foi atribuído a um membro da equipe.

Importar e migrar

Migre um sistema de identidade existente para o seu locatário Authagonal. Duas fontes são suportadas — Duende IdentityServer (um banco de dados SQL Server) e Auth0 (a Management API). Cada uma executa uma prévia somente leitura para que você revise exatamente o que será copiado antes de confirmar.

Importação do Duende IdentityServer

Migre clientes, scopes, usuários e papéis de um banco SQL Server do Duende IdentityServer existente para o seu locatário Authagonal. A importação roda em duas fases — prévia e commit — para que você revise o que será copiado antes de qualquer alteração.

O que é importado

O importador lê o ConfigurationDb do Duende e as tabelas do ASP.NET Identity e grava as linhas mapeadas no seu locatário. Artefatos de curta duração como persisted grants, device codes e chaves de assinatura são ignorados.

EntidadeTabelas de origemNotas
ClientesClients, ClientSecrets, ClientGrantTypes, ClientScopes, ClientRedirectUrisClientes desativados são importados desativados. Secrets expirados são ignorados.
ScopesApiScopes, ApiResources, IdentityResourcesOs mapeamentos de claims de usuário são preservados onde reconhecidos.
UsuáriosAspNetUsers, AspNetUserClaimsHashes de senha (ASP.NET Identity V3) são copiados como estão e re-hasheados no primeiro login.
PapéisAspNetRoles, AspNetUserRolesAs atribuições de papéis são preservadas.
Logins externosAspNetUserLoginsGuardados como referência; reconecte os IdPs de origem via SSO após a importação.

Prévia antes do commit

Cole sua string de conexão do ConfigurationDb / IdentityDb do Duende e clique em Pré-visualizar. A prévia abre uma conexão somente-leitura e conta cada linha que seria importada. Nenhuma gravação ocorre.

  • Contagens de entidades para clientes, scopes, usuários, papéis e atribuições de papéis.
  • Avisos de colisão quando o locatário de destino já tem clientes (ClientIds correspondentes são sobrescritos), papéis ou scopes (nomes correspondentes são ignorados).
  • Avisos para tabelas desconhecidas e colunas não mapeadas para que você saiba o que será descartado.
Import preview panel showing entity counts and warnings before committing the import

Painel de prévia com contagens e avisos

Hashes de senha

O Duende armazena senhas em ASP.NET Identity V3 (PBKDF2). O PasswordHasher do Authagonal verifica esse formato diretamente e re-hasheia para o formato nativo no primeiro login bem-sucedido — os usuários mantêm suas senhas existentes sem fluxo de redefinição.

Reconciliação de ID de usuário

Se um usuário já existente neste locatário tiver o mesmo e-mail de um registro recebido, a importação gira o userId dessa conta para o sub de origem antes de importar, de modo que as funções, logins e claims importados se anexem à conta existente e os aplicativos que já referenciam o usuário pelo seu sub de origem continuem a resolver após o cutover. A senha e o perfil existentes da conta são preservados; as funções de origem são mescladas por cima. A prévia lista todas as contas que serão reconciliadas antes de você confirmar.

Executando a importação

Clique em Iniciar importação após revisar a prévia. A fase de commit grava clientes, scopes, usuários, papéis e referências de login externo nos stores do locatário. Clientes com um clientId correspondente são sobrescritos; linhas com scope name, email ou role name correspondente são ignoradas, então o importador é seguro para re-executar.

O que não é importado

  • Persisted grants, device codes, sessões server-side — curta duração, regenerados automaticamente.
  • Chaves de assinatura — o Authagonal emite suas próprias chaves por tenant.
  • Colunas e tabelas personalizadas — qualquer coisa fora do schema padrão do Duende é sinalizada como aviso para você saber que esses dados foram descartados.
  • Clientes desativados — importados desativados; reative-os na página Clientes quando estiver pronto.

Indisponível no sandbox

A importação roda apenas no locatário em produção. Saia do modo sandbox antes de importar.

Importar do Auth0

Conecte a Authagonal à Management API do seu locatário Auth0 e traga suas aplicações, APIs, papéis, usuários e conexões corporativas. Os IDs de usuário e de aplicação importados são preservados, então as referências existentes de sub e client_id continuam resolvendo após o corte.

O que você vai precisar

Crie uma aplicação Machine-to-Machine no Auth0 autorizada para a Management API, com estes scopes de leitura: read:users, read:clients, read:resource_servers, read:roles, read:connections, read:client_grants. Cole o domínio, o client ID e o client secret dela no formulário de importação — eles são usados apenas para a importação.

O que é importado

EntidadeTabelas de origemNotas
Aplicaçõesclients, client-grantsPublic vs. confidential é detectado automaticamente. Os client secrets são re-hasheados para continuarem funcionando.
APIs e scopesresource-serversAudiences e scopes são atribuídos a cada cliente a partir dos seus grants.
Papéisroles + atribuiçõesAs atribuições de papel por usuário são preservadas.
Usuáriosusers + identitiesPerfis e metadados são transferidos; identidades sociais/corporativas tornam-se logins vinculados.
Conexõesconnections (OIDC)Conexões OIDC corporativas tornam-se provedores federados. Conexões SAML, sociais e de banco de dados são ignoradas com um aviso.

Senhas

A Management API do Auth0 nunca retorna hashes de senha. Se você tiver a exportação em massa de senhas assistida pelo suporte do Auth0 (NDJSON), forneça-a — os hashes bcrypt são importados na íntegra e seus usuários mantêm as senhas sem redefinição. Esse arquivo também traz o conjunto completo de usuários, removendo o limite de 1.000 usuários da listagem da API do Auth0. Sem ele, os usuários são importados como perfis e definem uma nova senha no primeiro login.

Mesma prévia, rotação e limites

A prévia, a rotação do owner-userId, o commit reexecutável e a restrição de sandbox descritos acima também se aplicam às importações do Auth0.

Referência da API

Cada locatário expõe um servidor OIDC em conformidade com os padrões em https://{slug}.authagonal.io. Todos os endpoints seguem as especificações OAuth 2.0 e OpenID Connect. Esta referência cobre todos os endpoints com os quais sua aplicação pode precisar interagir.

OIDC Authorization Code Flow with PKCE: sequence diagram showing the 9-step flow between your app, the browser, and Authagonal

Fluxo de Authorization Code com PKCE

OIDC Discovery & JWKS

O documento de discovery permite que bibliotecas de cliente OIDC se configurem automaticamente. Nenhuma autenticação é necessária para nenhum dos endpoints.

GET /.well-known/openid-configuration

Retorna o documento de Configuração do Provedor OpenID. A resposta inclui todos os metadados que seu cliente precisa para interagir com este locatário.

CampoDescrição
issuerA URL do emissor do locatário
authorization_endpointURL para requisições de autorização
token_endpointURL para troca de tokens
userinfo_endpointURL para obter claims do usuário
jwks_uriURL para o JSON Web Key Set
revocation_endpointURL para revogação de tokens
introspection_endpointURL para introspection de tokens
end_session_endpointURL para logout / encerramento de sessão
device_authorization_endpointURL para requisições de autorização de dispositivo
pushed_authorization_request_endpointURL do endpoint de Pushed Authorization Request (RFC 9126).
require_pushed_authorization_requestsSe o locatário exige PAR globalmente. Mesmo quando isso é false, clientes individuais ainda podem definir RequirePushedAuthorizationRequests = true.
scopes_supportedLista de escopos suportados
response_types_supportedTipos de resposta suportados
grant_types_supportedTipos de concessão suportados
code_challenge_methods_supportedMétodos PKCE suportados (S256)
backchannel_logout_supportedSe o logout por back-channel é suportado

GET /.well-known/openid-configuration/jwks

Retorna o JSON Web Key Set usado para verificar assinaturas de tokens. A resposta contém um array keys de chaves públicas EC P-256 (os tokens são assinados com ES256), cada uma incluindo os campos kty (EC), use, kid, alg, crv, x e y.

Fetch discovery document
curl https://acme.authagonal.io/.well-known/openid-configuration

Endpoint de Autorização

GET /connect/authorize

Inicia um fluxo de authorization code. O usuário deve ter uma sessão ativa ou será redirecionado para a página de login. Em caso de sucesso, o usuário é redirecionado de volta para sua aplicação com um authorization code.

ParâmetroObrigatórioDescrição
response_typeSimDeve ser "code"
client_idSimSeu identificador de cliente registrado
redirect_uriSimDeve corresponder exatamente a uma URI de redirecionamento registrada
scopeSimLista de escopos separados por espaço (ex: "openid profile email")
stateRecomendadoValor opaco para proteção CSRF, retornado inalterado no redirecionamento
code_challengeObrigatório se PKCEHash SHA-256 codificado em base64url do code_verifier
code_challenge_methodObrigatório se PKCEDeve ser "S256"
nonceOpcionalValor vinculado ao token de ID para proteção contra replay
login_hintOpcionalPré-preencher o campo de e-mail na página de login

Resposta de sucesso: Redirecionamento 302 para redirect_uri com parâmetros de query code e state.

Resposta de erro: Redirecionamento 302 com parâmetros de query error, error_description e state.

PKCE Obrigatório

PKCE é obrigatório por padrão para todos os clientes. Gere um code_verifier (uma string aleatória de 43 ou mais caracteres), aplique o hash SHA-256 e codifique o resultado em base64url para criar o code_challenge.

Pushed Authorization Requests (PAR)

RFC 9126. Em vez de colocar todos os parâmetros de autorização na URL, seu cliente os envia por POST para /connect/par com autenticação de cliente normal e recebe de volta uma request_uri opaca e de curta duração. O navegador então visita /connect/authorize?client_id=...&request_uri=... — nada mais entra no histórico do navegador, logs do servidor ou cabeçalhos Referer, e o servidor já verificou a integridade dos parâmetros sob autenticação do cliente.

POST /connect/par

A autenticação do cliente é a mesma de /connect/token: HTTP Basic com client_id/client_secret ou credenciais codificadas no formulário. Clientes públicos publicam sem segredo. O corpo carrega os mesmos parâmetros que você enviaria normalmente para /connect/authorize; o próprio request_uri é rejeitado (encadear um PAR é proibido pelo §2.1 da especificação). Retorna 201 Created.

ParâmetroObrigatórioDescrição
client_idSimSeu ID de cliente. Deve corresponder ao cliente autenticado.
client_secretClientes confidenciaisSeu segredo de cliente. Necessário para clientes confidenciais.
response_typeSimDeve ser "code"
redirect_uriSimDeve corresponder exatamente a uma URI de redirecionamento registrada
scopeSimLista de escopos separados por espaço (ex: "openid profile email")
code_challengeObrigatório se PKCEHash SHA-256 codificado em base64url do code_verifier
code_challenge_methodObrigatório se PKCEDeve ser "S256"
stateRecomendadoValor opaco para proteção CSRF, retornado inalterado no redirecionamento
nonceOpcionalValor vinculado ao token de ID para proteção contra replay

Resposta

CampoDescrição
request_uriReferência opaca de uso único, ex. <code>urn:ietf:params:oauth:request_uri:abc123…</code>. Passe-a para <code>/connect/authorize</code> como <code>request_uri</code>.
expires_inTempo de vida da <code>request_uri</code> em segundos. O padrão é 90 — valor típico de IdPs de referência.

Na chamada seguinte GET /connect/authorize?client_id=…&request_uri=…, todos os outros parâmetros são puxados do payload enviado e quaisquer parâmetros de query extras são ignorados. O client_id na chamada de autorização deve corresponder ao cliente que enviou a solicitação. Uma vez consumida (ou após expires_in), a request_uri é removida do armazenamento.

Forçar PAR por cliente

Ative Exigir pedidos de autorização enviados em um cliente (Portal, Clients, abra o cliente, aba Segurança) para recusar chamadas simples a /connect/authorize dele. A postura recomendada para clientes de alto risco combina RequirePushedAuthorizationRequests = true com PKCE, o que remove inteiramente a barra de URL como superfície de ataque.
Push an authorization request and follow up
# 1. Push parameters (server returns request_uri + expires_in)
curl -X POST https://acme.authagonal.io/connect/par \
  -u "my-app:CLIENT_SECRET" \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "response_type=code" \
  -d "redirect_uri=https://app.example.com/callback" \
  -d "scope=openid profile email" \
  -d "state=$(openssl rand -hex 16)" \
  -d "code_challenge=YOUR_CODE_CHALLENGE" \
  -d "code_challenge_method=S256"

# 2. Send the user to /authorize with only client_id + request_uri
# https://acme.authagonal.io/connect/authorize?client_id=my-app&request_uri=urn:ietf:params:oauth:request_uri:abc123...

Endpoint de Token

POST /connect/token

Troca credenciais por tokens. As requisições devem usar Content-Type: application/x-www-form-urlencoded. A autenticação do cliente pode ser fornecida via HTTP Basic auth (Authorization: Basic base64(client_id:client_secret)) ou como parâmetros no corpo do formulário (client_id + client_secret).

Concessão de Authorization Code

ParâmetroObrigatórioDescrição
grant_typeSim"authorization_code"
codeSimO authorization code do redirecionamento
redirect_uriSimDeve corresponder à URI usada na requisição de autorização
code_verifierObrigatório se PKCEA string aleatória original usada para gerar o code_challenge
client_idSimSeu identificador de cliente (se não estiver usando Basic auth)
client_secretClientes confidenciaisSeu client secret (se não estiver usando Basic auth)

Concessão de Refresh Token

ParâmetroObrigatórioDescrição
grant_typeSim"refresh_token"
refresh_tokenSimO refresh token a ser trocado
client_idSimSeu identificador de cliente
client_secretClientes confidenciaisSeu client secret

Concessão de Client Credentials

ParâmetroObrigatórioDescrição
grant_typeSim"client_credentials"
client_idSimSeu identificador de cliente
client_secretSimSeu client secret
scopeOpcionalEscopos a solicitar separados por espaço

Concessão de Device Code

ParâmetroObrigatórioDescrição
grant_typeSim"urn:ietf:params:oauth:grant-type:device_code"
device_codeSimO device code da resposta de autorização de dispositivo
client_idSimSeu identificador de cliente
client_secretClientes confidenciaisSeu client secret

Resposta do token:

CampoDescrição
access_tokenO access token para chamadas de API
token_type"Bearer"
expires_inTempo de vida do token em segundos
id_tokenToken de ID do OpenID Connect (quando o escopo openid é solicitado)
refresh_tokenRefresh token (quando o escopo offline_access é concedido)
Exchange authorization code with PKCE
curl -X POST https://acme.authagonal.io/connect/token \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "grant_type=authorization_code" \
  -d "code=AUTHORIZATION_CODE" \
  -d "redirect_uri=https://app.example.com/callback" \
  -d "client_id=my-app" \
  -d "code_verifier=YOUR_CODE_VERIFIER"

Endpoint UserInfo

GET /connect/userinfo

Retorna claims sobre o usuário autenticado. Requer um access token válido com o escopo openid.

CampoTipoDescrição
substringIdentificador único do usuário
emailstringEndereço de e-mail do usuário
email_verifiedbooleanSe o e-mail foi verificado
given_namestringPrimeiro nome
family_namestringSobrenome
namestringNome de exibição completo
phone_numberstringNúmero de telefone (se fornecido). Liberado sob o scope <code>phone</code>.
org_idstringA organização à qual o usuário pertence. Atribuída pelo seu próprio app de provisionamento (veja Apps de provisionamento) ou definida com PUT /api/v1/users/{userId}; o Authagonal nunca a deriva. Liberada sob o scope profile e ausente quando o usuário não tem nenhuma.
rolesstring[]Array de funções atribuídas. Liberado somente quando o token carrega o scope <code>roles</code>.
groupsobject[]Array de associações de grupo, cada uma com id e name. Liberado somente quando o token carrega o scope <code>groups</code>.
Fetch user info
curl https://acme.authagonal.io/connect/userinfo \
  -H "Authorization: Bearer ACCESS_TOKEN"

Token Introspection (RFC 7662)

POST /connect/introspect

Valida um token e retorna seus metadados. Requer credenciais de cliente (Basic auth ou parâmetros no corpo do formulário).

ParâmetroObrigatórioDescrição
tokenSimO token a ser inspecionado
token_type_hintOpcionalDica sobre o tipo de token (ex: "refresh_token")

Resposta de token ativo:

CampoDescrição
activetrue
subSujeito (ID do usuário)
client_idCliente para o qual o token foi emitido
scopeEscopos concedidos separados por espaço
issEmissor
expHora de expiração (timestamp Unix)
iatHora de emissão (timestamp Unix)
audAudiência
token_typeTipo de token (ex: "Bearer")

Resposta de token inativo: { "active": false }

Sempre 200 OK

Conforme a RFC 7662, o endpoint de introspection responde 200 OK para qualquer token, então não pode ser usado para enumerar tokens. Um token inválido, expirado ou revogado simplesmente retorna active: false. A única exceção é o próprio chamador: um cliente que falha na autenticação recebe 401 invalid_client.
Introspect a token
curl -X POST https://acme.authagonal.io/connect/introspect \
  -u "my-app:CLIENT_SECRET" \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "token=ACCESS_OR_REFRESH_TOKEN"

Revogação de Token (RFC 7009)

POST /connect/revocation

Revoga um token emitido anteriormente. Requer credenciais de cliente.

ParâmetroObrigatórioDescrição
tokenSimO token a ser revogado
token_type_hintOpcionalDica sobre o tipo de token (ex: "refresh_token")

O endpoint sempre retorna 200 OK, mesmo para tokens inválidos ou já revogados, conforme a especificação RFC 7009.

Access tokens e refresh tokens

Tanto refresh tokens quanto access tokens podem ser revogados. Revogar um refresh token também revoga os access tokens emitidos a partir dele. Um access token revogado é recusado pela introspection e pelo userinfo, mas um servidor de recursos que valida o JWT localmente continua aceitando-o até que expire; por isso, mantenha curtos os tempos de vida dos access tokens.

Autorização de Dispositivo (RFC 8628)

POST /connect/deviceauthorization

Inicia o fluxo de autorização de dispositivo para dispositivos com restrição de entrada (CLIs, smart TVs, dispositivos IoT). O dispositivo exibe um código para o usuário, que então aprova a requisição em um dispositivo separado com navegador.

ParâmetroObrigatórioDescrição
client_idSimSeu identificador de cliente
client_secretClientes confidenciaisSeu client secret
scopeOpcionalEscopos separados por espaço (padrão: "openid")

Resposta:

CampoDescrição
device_codeCódigo de verificação do dispositivo (usado para polling)
user_codeCódigo voltado ao usuário no formato XXXX-XXXX
verification_uriURL que o usuário visita para inserir o código
verification_uri_completeURL com o user_code pré-preenchido
expires_in300 por padrão (segundos, então o código é válido por 5 minutos). Definido por cliente.
interval5 (segundos — intervalo mínimo de polling)

Fluxo de aprovação: O usuário visita a verification_uri, insere o user_code e aprova a requisição. Enquanto isso, o dispositivo faz polling no endpoint de token com o device_code.

Códigos de erro de polling:

ErroSignificado
authorization_pendingO usuário ainda não aprovou — continue o polling
expired_tokenO device code expirou — reinicie o fluxo
access_deniedO usuário negou a requisição de autorização
Request device authorization
curl -X POST https://acme.authagonal.io/connect/deviceauthorization \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "client_id=my-cli" \
  -d "scope=openid profile email"

Encerrar Sessão / Logout

GET POST /connect/endsession

Encerra a sessão do usuário atual, notifica todos os clientes com uma URI de logout por back-channel ou front-channel registrada e revoga as concessões vinculadas a essa sessão. Sem um id_token_hint que corresponda à sessão atual, o usuário é primeiro solicitado a confirmar o logout.

ParâmetroObrigatórioDescrição
id_token_hintOpcionalO token de ID — usado para validar o post_logout_redirect_uri
post_logout_redirect_uriOpcionalPara onde redirecionar após o logout (deve ser registrado)
stateOpcionalValor opaco retornado no redirecionamento

Se um post_logout_redirect_uri válido for fornecido e corresponder a uma URI registrada, o usuário recebe um redirecionamento 302. Caso contrário, uma resposta JSON confirma que a sessão foi encerrada.

Logout por Back-Channel

Quando um usuário faz logout, Authagonal envia um JWT assinado para o BackChannelLogoutUri de cada cliente. O JWT contém sub, aud, iss e a claim de evento http://schemas.openid.net/event/backchannel-logout. Sua aplicação deve invalidar a sessão local do usuário quando receber esta notificação.

Referência da API SCIM 2.0

Authagonal suporta o protocolo SCIM 2.0 para provisionamento automatizado de usuários e grupos. Provedores de identidade como Okta, Azure AD e OneLogin podem usar esta API para manter seu locatário Authagonal sincronizado com seu diretório corporativo.

URL Base: https://{slug}.authagonal.io/scim/v2

Autenticação: Todas as requisições requerem um token Bearer. Gere um token SCIM no portal na página SCIM: selecione o cliente para o qual o seu IdP provisiona e depois clique em Criar Token.

Cabeçalhos comuns:

CabeçalhoValor
AuthorizationBearer SCIM_TOKEN
Content-Typeapplication/scim+json

Endpoints de listagem aceitam count (padrão 100, máx. 200; 0 retorna apenas o total) e filtragem via o parâmetro filter (ex: userName eq "[email protected]"). Usuários são paginados com cursor: passe o nextCursor da resposta anterior. Grupos aceitam startIndex (base 1) ou cursor.

Usuários

GET /scim/v2/Users: Lista usuários com paginação e filtragem opcionais.

Parâmetro de QueryDescrição
startIndexPara Usuários, somente 1 é aceito; pagine com cursor. Um valor maior retorna 400 invalidValue.
cursorCursor de paginação opaco: passe o nextCursor da página anterior para obter a próxima página
countNúmero máximo de resultados por página (padrão: 100, máx.: 200; 0 retorna apenas o total)
filterExpressão de filtro SCIM (ex: userName eq "[email protected]")

GET /scim/v2/Users/{id}: Obtém um único usuário pelo ID de usuário Authagonal.

POST /scim/v2/Users: Cria um novo usuário. Retorna 201 Created.

CampoObrigatórioDescrição
userNameSimEndereço de e-mail (deve ser único dentro do locatário)
name.givenNameNãoPrimeiro nome
name.familyNameNãoSobrenome
displayNameNãoNome de exibição completo
activeNãoSe o usuário está ativo (padrão: true)
externalIdNãoIdentificador do provedor de identidade de origem

PUT /scim/v2/Users/{id}: Substituição completa de um recurso de usuário. Todos os campos devem ser fornecidos.

PATCH /scim/v2/Users/{id}: Atualização parcial usando SCIM PatchOp.

OperaçãoCaminhos SuportadosValor de Exemplo
replaceuserName, active, name.givenName, name.familyName, displayName, externalId, preferredLanguagetrue / false, ou um valor de string
adduserName, active, name.givenName, name.familyName, displayName, externalId, preferredLanguagetrue / false, ou um valor de string
removename.givenName, name.familyName, displayName, externalId, preferredLanguage(nenhum valor necessário)

DELETE /scim/v2/Users/{id}: Exclui suavemente o usuário (desativa a conta e revoga todos os tokens). Retorna 204 No Content.

Create a user via SCIM
curl -X POST https://acme.authagonal.io/scim/v2/Users \
  -H "Authorization: Bearer SCIM_TOKEN" \
  -H "Content-Type: application/scim+json" \
  -d '{
    "schemas": ["urn:ietf:params:scim:schemas:core:2.0:User"],
    "userName": "[email protected]",
    "name": {
      "givenName": "Jane",
      "familyName": "Smith"
    },
    "displayName": "Jane Smith",
    "active": true,
    "externalId": "ext-12345"
  }'

Grupos

GET /scim/v2/Groups: Lista todos os grupos com paginação e filtragem opcionais.

GET /scim/v2/Groups/{id}: Obtém um único grupo por ID, incluindo sua lista de membros.

POST /scim/v2/Groups: Cria um novo grupo. Retorna 201 Created.

CampoObrigatórioDescrição
displayNameSimNome de exibição do grupo
membersNãoArray de objetos de membros, cada um com um campo value contendo o ID do usuário
externalIdNãoIdentificador do provedor de identidade de origem

PUT /scim/v2/Groups/{id}: Substituição completa de um recurso de grupo (incluindo sua lista de membros).

PATCH /scim/v2/Groups/{id}: Atualização parcial: adicionar, remover ou substituir membros, ou alterar displayName e externalId.

DELETE /scim/v2/Groups/{id}: Exclui permanentemente o grupo. Retorna 204 No Content.

Add members to a group via PATCH
curl -X PATCH https://acme.authagonal.io/scim/v2/Groups/GROUP_ID \
  -H "Authorization: Bearer SCIM_TOKEN" \
  -H "Content-Type: application/scim+json" \
  -d '{
    "schemas": ["urn:ietf:params:scim:api:messages:2.0:PatchOp"],
    "Operations": [
      {
        "op": "add",
        "path": "members",
        "value": [
          { "value": "USER_ID_1" },
          { "value": "USER_ID_2" }
        ]
      }
    ]
  }'

Respostas de Erro SCIM

Quando uma requisição SCIM falha, o corpo da resposta segue o esquema de erro SCIM: { "schemas": ["urn:ietf:params:scim:api:messages:2.0:Error"], "status": "400", "detail": "..." }. Códigos de status comuns incluem 400 (requisição inválida), 404 (recurso não encontrado), 409 (conflito / duplicata) e 429 (limite de taxa excedido).

Portal API (automação)

A Portal API permite que o seu próprio backend automatize tudo o que pode fazer no portal — gerir usuários, clients, grupos, funções, escopos, conexões SSO e configurações — usando uma credencial máquina-a-máquina. É a mesma API que a interface do portal chama.

URL Base: https://portal-api.<your-domain>/api/v1. As requisições autenticam-se com um token de acesso Bearer; o locatário é obtido a partir do token, não do URL.

Criando uma credencial de API

No portal, abra Clients → Create API credential, escolha um nível de acesso e dê-lhe um nome. O Authagonal gera um client OAuth client_credentials configurado para a Portal API e retorna um client ID e um secret.

Copie o secret imediatamente

O client secret é mostrado apenas uma vez, logo após a criação. Guarde-o no seu gerenciador de secrets antes de fechar a caixa de diálogo — se o perder, exclua a credencial e crie uma nova.

Níveis de acesso

ScopeConcede
tenant:ownerAcesso total, incluindo ações destrutivas exclusivas do proprietário, como excluir todo o locatário.
tenant:adminGerenciar tudo exceto ações exclusivas do proprietário — usuários, clients, SSO, grupos, funções, identidade visual e configurações.
tenant:developerGerenciar clients, escopos, identidade visual e aplicações de provisionamento.
tenant:supportLer e gerenciar usuários para tarefas de suporte, e ler o registro de auditoria.

Você só pode conceder o que possui

Uma credencial não pode ser mais privilegiada do que a pessoa que a cria. Um administrador não pode emitir uma credencial com escopo de proprietário, e o escopo administrativo da plataforma nunca pode ser concedido a uma credencial.

Obtendo um token

Troque a credencial por um token de acesso no endpoint de token do seu tenant de administração — https://<your-tenant>.<your-domain>/connect/token — e depois envie o token como cabeçalho Bearer para a Portal API. Os tokens são válidos por uma hora.

Obtenha um token e depois chame a API
# 1. Exchange the credential for an access token (your tenant's token endpoint)
curl -X POST https://acme.authagonal.io/connect/token \
  -d grant_type=client_credentials \
  -d client_id=api-3f2a... \
  -d client_secret=YOUR_CLIENT_SECRET \
  -d scope=tenant:admin

# Response: { "access_token": "ey...", "token_type": "Bearer", "expires_in": 3600 }

# 2. Call the Portal API with the access token
curl https://portal-api.authagonal.io/api/v1/users \
  -H "Authorization: Bearer $ACCESS_TOKEN"

Endpoints

Todos os caminhos são relativos à URL base e exigem um token de acesso Bearer. O escopo ao lado de cada grupo é o nível de acesso mínimo que a credencial precisa. A paginação varia por recurso: usuários e o registro de auditoria aceitam count (1 a 200, padrão 50) e after, definido como o continuationToken da resposta anterior; grupos aceitam startIndex e count; organizações aceitam limit e cursor; clients, funções e escopos retornam todas as linhas.

Clientestenant:developer

GET/api/v1/clientsListar clientes OAuth.

GET/api/v1/clients/{id}Obter um único cliente por ID.

POST/api/v1/clientsCriar um cliente. Retorna 201 com o registro do cliente. Os segredos não são retornados aqui: gere um com POST /api/v1/clients/{clientId}/secrets, que o exibe uma única vez.

PUT/api/v1/clients/{id}Atualizar um cliente (URIs de redirecionamento, tipos de concessão, tempos de vida de token, requisitos PKCE/PAR).

DELETE/api/v1/clients/{id}Excluir um cliente.

POST/api/v1/clients/api-credentialGerar uma credencial de API do Portal máquina a máquina.

Usuáriostenant:support

GET/api/v1/usersListar usuários. Suporta count, search (prefixo de e-mail ou nome), organizationId para filtrar por uma organização e after para paginação por cursor.

GET/api/v1/users/countNúmero total de usuários do inquilino.

GET/api/v1/users/stats/mfaEstatísticas de inscrição em MFA.

GET/api/v1/users/{id}Obter um único usuário.

POST/api/v1/users/inviteConvidar um usuário por e-mail. Cria uma conta pendente e envia por e-mail um link onde o convidado define a própria senha. Os campos opcionais organizationId e organizationRoles também adicionam uma associação a uma organização.

PUT/api/v1/users/{id}Atualizar um usuário (perfil, e-mail, isActive, emailConfirmed, organizationId). Alterar email ou emailConfirmed exige tenant:admin.

DELETE/api/v1/users/{id}Excluir um usuário.

GET/api/v1/users/{id}/mfaGet a user's enrolled MFA methods.

DELETE/api/v1/users/{id}/mfaReset a user's MFA enrollment. Needs tenant:admin.

Funçõestenant:admin

GET/api/v1/rolesListar funções.

POST/api/v1/rolesCriar uma função.

DELETE/api/v1/roles/{id}Excluir uma função.

POST/api/v1/roles/assignAtribuir uma função a um usuário.

POST/api/v1/roles/unassignRemover uma função de um usuário.

Grupostenant:admin

GET/api/v1/groupsListar grupos.

GET/api/v1/groups/{id}Obter um grupo com seus membros.

POST/api/v1/groupsCriar um grupo.

POST/api/v1/groups/{id}/membersAdicionar membros a um grupo.

DELETE/api/v1/groups/{groupId}/members/{userId}Remover um membro de um grupo.

DELETE/api/v1/groups/{id}Excluir um grupo.

GET/api/v1/group-role-mappingsListar os mapeamentos de grupo para função (funções concedidas na emissão do token conforme a associação ao grupo).

Escopostenant:developer

GET/api/v1/scopesListar escopos de API.

POST/api/v1/scopesCriar um escopo.

DELETE/api/v1/scopes/{name}Excluir um escopo.

Conexões SSOtenant:admin

GET/api/v1/saml/connectionsListar conexões SAML.

POST/api/v1/saml/connectionsCriar uma conexão SAML.

DELETE/api/v1/saml/connections/{id}Excluir uma conexão SAML.

GET/api/v1/oidc/connectionsListar conexões OIDC.

POST/api/v1/oidc/connectionsCriar uma conexão OIDC.

DELETE/api/v1/oidc/connections/{id}Excluir uma conexão OIDC.

GET/api/v1/sso/domainsListar os domínios roteados para conexões SSO (descoberta de home-realm).

Personalizaçãotenant:developer

GET/api/v1/brandingObter a personalização do inquilino (cores, logotipo, idiomas suportados).

PUT/api/v1/brandingAtualizar a personalização do inquilino.

Configuraçõestenant:admin

GET/api/v1/settingsObter as configurações do inquilino (webhooks, cadastro público, política de tokens).

PUT/api/v1/settingsAtualizar as configurações do inquilino.

POST/api/v1/settings/webhook-secret/regenerateRotacionar o segredo de assinatura do webhook.

POST/api/v1/settings/test-emailEnviar um e-mail de teste com a configuração de e-mail atual.

Domínios personalizados e e-mailtenant:admin

GET/api/v1/custom-domainsListar domínios de login personalizados e seu status de verificação.

POST/api/v1/custom-domainsAdicionar um domínio personalizado.

POST/api/v1/custom-domains/{domain}/verifyDisparar a verificação de DNS de um domínio personalizado.

DELETE/api/v1/custom-domains/{domain}Remover um domínio personalizado.

GET/api/v1/email/domains/{domainId}Obter os registros DNS e o status de verificação de um domínio de e-mail do remetente.

Registro de auditoriatenant:support

GET/api/v1/auditConsultar o registro de auditoria do inquilino.

Provisionamento de usuários via SCIM

Para provisionamento em massa de usuários e grupos a partir de um IdP (Entra, Okta), use a API SCIM 2.0 em vez desses endpoints.

Exemplo: convidar um usuário

POST /api/v1/users/invite
curl -X POST https://portal-api.authagonal.io/api/v1/users/invite \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "email": "[email protected]",
    "firstName": "Ada",
    "lastName": "Lovelace"
  }'

# 200 OK
# { "userId": "8f3a...", "email": "[email protected]" }

Tudo o que a interface pode fazer

A Portal API expõe os mesmos endpoints que a interface do portal usa, portanto qualquer operação que você possa realizar no portal pode ser automatizada — sujeito ao nível de acesso da credencial.

API de Organizações

Todas as rotas abaixo exigem a política TenantAdmin e ficam em /api/v1/organizations, salvo indicação em contrário. Veja a Portal API para saber como criar uma credencial. As duas rotas de listagem usam paginação por cursor: passe limit (padrão 50, de 1 a 200) e o nextCursor anterior como cursor; elas respondem { items, nextCursor }, e um cursor inválido resulta em 400 invalid_cursor. O objeto de organização carrega uma lista domains somente leitura.

MétodoCaminhoCorpoObservações
GET/api/v1/organizations–Uma página de organizações em ordem de id. Query: cursor?, limit? (padrão 50, de 1 a 200). Retorna { items, nextCursor }; um nextCursor nulo é a última página.
POST/api/v1/organizationsslug, name, brandingJson?, enabled?, requireMembershipForTokens?, allowAutoMembership?, metadata?201 + a organização. 409 slug_taken.
GET/api/v1/organizations/{idOrSlug}–Buscada primeiro por id, depois por slug.
PUT/api/v1/organizations/{id}name?, brandingJson?, slug?, enabled?, requireMembershipForTokens?, allowAutoMembership?, metadata?Apenas os campos informados mudam. Um slug diferente é recusado: ele é imutável depois de criado. domains não pode ser alterado aqui.
DELETE/api/v1/organizations/{id}–Exclui primeiro todas as associações da organização e depois a própria organização.
GET/api/v1/organizations/{id}/members–Uma página de associações em ordem de id de usuário, com o e-mail/nome atual do membro resolvido a partir do user store. Query: cursor?, limit?.
POST/api/v1/organizations/{id}/membersuserId? | email?, status?, roles?201 + a associação. 404 user_not_found. 409 membership_exists. Funções reservadas tenant:* e platform:* são recusadas com 400 invalid_role, não removidas.
PUT/api/v1/organizations/{id}/members/{userId}status?, roles?Definir status como active grava joinedAt se ainda não estiver definido.
DELETE/api/v1/organizations/{id}/members/{userId}–Remove a linha por completo, não é uma mudança de status.
POST/api/v1/organizations/{id}/domainsdomainReivindica um domínio de e-mail, não verificado. 201 + { domain, verified, verifiedAt, createdAt, recordName, recordValue }. 400 domain_invalid. 409 domain_exists, domain_taken.
POST/api/v1/organizations/{id}/domains/{domain}/verify–Consulta o registro TXT em recordName e compara recordValue exatamente. 200 + o domínio quando verificado (uma repetição é um 200 sem efeito); 409 verification_failed em caso de falha; 409 domain_taken; 404 domain_not_found.
DELETE/api/v1/organizations/{id}/domains/{domain}–204. Descarta a reivindicação, verificada ou não. Os membros existentes permanecem. 404 domain_not_found.
POST/api/v1/organizations/backfilldryRun? = trueMigra a tag legada AuthUser.organizationId para linhas reais de Organization/OrganizationMembership.
GET/api/v1/users/{userId}/organizations–Todas as organizações às quais este usuário pertence, com seu status/funções em cada uma.

Telas de Login

Estas são as telas hospedadas que seus usuários finais veem no servidor de auth do seu tenant. A Authagonal entrega todas as telas prontas para uso, então você ganha uma experiência de login completa e segura sem construir nenhuma interface. Esta página percorre cada tela e mostra quais configurações do portal a controlam.

Totalmente white-label

Todas as telas aqui são pintadas pelas configurações de Marca do seu tenant — seu logotipo, cor, nome do aplicativo e CSS personalizado. As telas também respeitam prefers-color-scheme, então alternam entre claro e escuro para combinar com o dispositivo do usuário.

Entrar

Hosted sign-in screen with an email field, Continue button, single sign-on provider buttons, and forgot-password and create-account links
  • Fluxo em duas etapas, e-mail primeiro: o usuário digita o e-mail e clica em Continuar, então o campo de senha aparece.
  • Botões de single sign-on "Continuar com {provider}" aparecem automaticamente quando há conexões SSO.
  • Links de esqueci a senha e criar conta, cada um podendo ser exibido ou ocultado.
  • Captcha opcional Cloudflare Turnstile para deter tentativas de login automatizadas.

Controlado no admin do portal

  • Marca define o logotipo, a cor, o nome do aplicativo, o e-mail de suporte e o CSS personalizado.
  • Exiba ou oculte os links de esqueci a senha e cadastro (Marca).
  • Conexões SSO adicionam os botões de login social (página de SSO).
  • Tempo de vida da sessão e limites de bloqueio (Definições → Sessão).

Cadastro

Account registration screen with first and last name fields, email, password, and a live password-policy checklist
  • Coleta nome e sobrenome (opcional), e-mail e uma senha.
  • Uma checklist de política de senha ao vivo é atualizada conforme o usuário digita, deixando os requisitos claros antes do envio.
  • Captcha opcional Cloudflare Turnstile.
  • Um link "Entrar" para usuários que já têm uma conta.

Controlado no admin do portal

  • Exiba ou oculte o link de cadastro (Identidade Visual). Para desativar o cadastro por completo, desligue Permitir cadastro público (Definições → Sessão).
  • A política de senha do seu tenant orienta a checklist.
  • Marca estiliza a tela inteira.

Esqueci a senha

Forgot-password screen with an email field and a neutral check-your-email confirmation state
  • O usuário digita o e-mail e então vê uma confirmação neutra de "verifique seu e-mail".
  • A tela nunca revela se uma conta existe, o que frustra a sondagem por enumeração de contas.
  • Um link "Voltar para entrar" leva o usuário de volta à tela de login.

Controlado no admin do portal

  • Exiba ou oculte o link de esqueci a senha (Marca).
  • A entrega de e-mail do seu tenant envia a mensagem de redefinição.
  • Marca estiliza a tela inteira.

Redefinir senha

Reset-password screen with new and confirm password fields and a live per-rule requirement checklist
  • Campos de nova senha e confirmar senha com uma checklist de requisitos ao vivo, regra por regra.
  • Um estado claro de link inválido ou expirado quando o token de redefinição não é mais válido.
  • Um estado de sucesso confirmando que a senha foi alterada.

Controlado no admin do portal

  • A política de senha do seu tenant orienta a checklist.
  • Marca estiliza a tela inteira.

Desafio de MFA

MFA challenge screen with a method switcher, a six-digit authenticator code field, recovery-code entry, and a passkey button
  • Um seletor de método entre app autenticador, passkey e código de recuperação.
  • Um campo TOTP de 6 dígitos que é enviado automaticamente assim que todos os dígitos são inseridos.
  • Entrada de código de recuperação para usuários que perderam o acesso ao seu autenticador.
  • Um botão de passkey para verificação baseada em hardware.

Controlado no admin do portal

  • A política de MFA é definida por aplicação (Clientes → Segurança).
  • Qualquer usuário com um fator cadastrado é sempre desafiado, independentemente da política.

Configuração de MFA

MFA setup screen showing enrolled-method status, authenticator QR code and manual key, passkey enrolment, and recovery-code generation
  • Mostra o status dos métodos cadastrados para que o usuário saiba o que já está configurado.
  • Configuração do autenticador via QR code, com chave manual como alternativa e uma etapa de confirmação.
  • Cadastro de passkey para autenticação baseada em hardware.
  • Geração de códigos de recuperação para recuperação de conta.
  • Um pular opcional quando o MFA é por autoatendimento em vez de obrigatório.

Controlado no admin do portal

  • A política de MFA é definida por aplicação; Obrigatório força a configuração no login (Clientes → Segurança).
  • Marca estiliza a tela inteira.

Autorização de dispositivo

Device authorization screen with a centered user-code entry field, an Approve button, and an approved confirmation state
  • Um campo centralizado de entrada do código do usuário para o código exibido no dispositivo.
  • Uma etapa de aprovação para autorizar o dispositivo.
  • Uma tela intermediária de login quando o usuário ainda não está autenticado.
  • Uma confirmação de aprovação depois que o dispositivo é autorizado.

Controlado no admin do portal

  • Habilite a concessão device-code na aplicação (Clients → Scopes & Grants).
  • Defina o tempo de vida do device-code (Clientes → Tokens).
Consent screen showing the requesting application's logo and name, a per-scope permission list, and Allow and Deny buttons
  • Mostra o logotipo e o nome do cliente solicitante.
  • Uma lista por escopo com rótulos amigáveis e legíveis para cada permissão.
  • Botões Permitir e Negar para conceder ou recusar acesso.
  • Um rodapé com dica de consentimento explicando o que a decisão significa.

Controlado no admin do portal

  • Ative Exigir consentimento por aplicação (Clients → Geral).
  • O logotipo, o nome e a URL vêm dos próprios metadados da aplicação.
  • Marca pinta o cartão de consentimento.

Apps conectados (concessões)

Connected apps screen listing the applications a user has authorized with their scopes and granted date, plus a revoke control
  • Lista todos os apps que o usuário autorizou, com seu nome, escopos e data de concessão.
  • Revogue o acesso de um app, com uma etapa de confirmação antes de entrar em vigor.
  • Um estado vazio amigável quando o usuário não autorizou nenhum app.

Controlado no admin do portal

  • A lista é preenchida pelas aplicações que exigem consentimento.
  • Marca estiliza a tela inteira.

Conta

Uma página de conta de autoatendimento hospedada em /login/account onde os usuários autenticados gerenciam o próprio perfil e idioma preferido, sem precisar de acesso ao portal.

Self-service account screen with editable profile fields and a preferred Language selector
  • Editar nome e sobrenome, empresa e telefone; o endereço de e-mail é exibido somente leitura.
  • Escolher um idioma preferido entre os idiomas suportados; a interface mostra a prévia da escolha instantaneamente e a mantém ao salvar.
  • O idioma salvo controla a interface hospedada do usuário e o idioma dos e-mails transacionais que ele recebe.

Controlado no admin do portal

  • Branding estiliza toda a tela.
  • O mesmo idioma preferido pode ser editado por um administrador na página de Usuários do portal.

Fluxos de Autenticação

Os fluxos de autenticação cobrem como os usuários finais interagem com seu locatário Authagonal — fazendo login, se cadastrando, redefinindo senhas e configurando MFA. Esses endpoints são usados pela página de login hospedada e podem ser chamados diretamente se você estiver construindo uma UI de login personalizada.

Login

POST /api/auth/login

Autentica um usuário com e-mail e senha. Em caso de sucesso, assina um cookie de sessão e retorna o perfil do usuário. Se o MFA estiver configurado, a resposta indica que um segundo fator é necessário antes que a sessão seja totalmente estabelecida.

Corpo da requisição:

Login request
{
  "email": "[email protected]",
  "password": "correct-horse-battery-staple"
}

Resposta de sucesso:

CampoTipoDescrição
userIdstringIdentificador único do usuário
emailstringEndereço de e-mail do usuário
namestringNome de exibição completo
mfaAvailablebooleanSe o usuário tem métodos MFA inscritos

Resposta de MFA obrigatório: Quando o usuário tem MFA inscrito, a resposta inclui mfaRequired: true junto com um challengeId e um array methods listando os métodos MFA disponíveis.

Resposta de configuração de MFA obrigatória: Quando a política de MFA da aplicação é Obrigatório, mas o usuário ainda não se inscreveu, a resposta inclui mfaSetupRequired: true com um setupToken para o fluxo de inscrição.

Respostas de erro:

Código de ErroStatus HTTPDescrição
invalid_credentials401E-mail ou senha incorretos
account_disabled403A conta foi desativada por um administrador
email_not_confirmed403O usuário não verificou seu endereço de e-mail
locked_out423A conta está temporariamente bloqueada (inclui retryAfter em segundos). Retornado somente quando a senha está correta; uma senha errada durante o bloqueio retorna invalid_credentials
sso_required409O domínio de e-mail tem SSO configurado (inclui redirectUrl)
too_many_attempts429Muitas tentativas de login a partir deste IP ou para este e-mail; tente novamente mais tarde
captcha_failed400O desafio do Turnstile falhou ou está ausente (somente quando o Turnstile está habilitado)

Verificação de SSO: Se o domínio de e-mail do usuário tem uma conexão SSO configurada, o endpoint de login retorna sso_required com um redirectUrl. O cliente deve redirecionar o usuário para o provedor SSO.

Bloqueio de conta: Após maxFailedAttempts tentativas de login consecutivas com falha, a conta é bloqueada por lockoutDurationMinutes. Ambos os valores são configuráveis nas configurações do locatário.

Página de Login Hospedada

O endpoint de login é tipicamente chamado pela página de login hospedada, não diretamente pela sua aplicação. Use o fluxo de authorization code OIDC para iniciar a autenticação — seus usuários serão redirecionados para a página de login hospedada automaticamente.

Cadastro

POST /api/auth/register

Cria uma nova conta de usuário e envia um e-mail de verificação. Enquanto <strong>Require verified email to sign in</strong> (Definições &rarr; Sessão) estiver ativado, que é o padrão, o usuário deve verificar seu e-mail antes de poder fazer login.

Corpo da requisição:

Registration request
{
  "email": "[email protected]",
  "password": "a-strong-password-here",
  "firstName": "Jane",
  "lastName": "Smith"
}
CampoObrigatórioDescrição
emailSimEndereço de e-mail (deve ser único)
passwordSimDeve atender à política de senha do locatário
firstNameNãoPrimeiro nome
lastNameNãoSobrenome

Sucesso: 201 Created com o userId da nova conta. Registrar-se com um e-mail já existente também retorna 201: nunca revelamos se um e-mail está cadastrado (para evitar enumeração de contas) e, em vez disso, avisamos o titular real da conta por e-mail.

Respostas de erro:

Código de ErroStatus HTTPDescrição
weak_password400A senha não atende à política de senha do locatário
rate_limited429Muitas tentativas de cadastro
provisioning_rejected422Um webhook de provisionamento rejeitou o cadastro
invalid_email400O endereço de e-mail não é válido
captcha_failed400O desafio do Turnstile falhou ou está ausente (somente quando o Turnstile está habilitado)
public_signup_disabled403O cadastro público está desativado para este locatário (Definições &rarr; Sessão)

Política de Senha

Verifique os requisitos de senha do tenant antes do envio via GET /api/auth/password-policy. Isso retorna uma lista rules: o comprimento mínimo e as classes de caracteres obrigatórias.

Redefinição de Senha

POST /api/auth/forgot-password

Solicita um e-mail de redefinição de senha. O endpoint sempre retorna uma resposta de sucesso independentemente de o e-mail existir, para prevenir enumeração de e-mails.

Forgot password request
{
  "email": "[email protected]"
}

POST /api/auth/reset-password

Redefine a senha do usuário usando o token do link de e-mail.

Reset password request
{
  "token": "RESET_TOKEN_FROM_EMAIL",
  "newPassword": "new-strong-password"
}

Efeitos colaterais de uma redefinição de senha bem-sucedida:

  • O contador de tentativas de login com falha é zerado
  • Todos os refresh tokens existentes são revogados
  • Um novo security stamp é gerado (invalidando todas as sessões existentes)

Configuração e Verificação de MFA

Authagonal suporta três métodos de MFA: TOTP (aplicativos autenticadores), WebAuthn (chaves de segurança e biometria) e códigos de recuperação de uso único.

Configuração TOTP

POST /api/auth/mfa/totp/setup: Retorna um <code>setupToken</code>, uma URI de dados de QR code e uma chave de entrada manual. O usuário escaneia o QR code com seu aplicativo autenticador (Google Authenticator, Authy, 1Password, etc.) e confirma a inscrição.

POST /api/auth/mfa/totp/confirm: Confirma a inscrição TOTP enviando o <code>setupToken</code> obtido na configuração junto com um código de 6 dígitos do aplicativo autenticador.

Confirm TOTP enrollment
{
  "setupToken": "SETUP_TOKEN_FROM_SETUP_RESPONSE",
  "code": "123456"
}

Configuração WebAuthn

POST /api/auth/mfa/webauthn/setup — Retorna opções de criação de credencial para a API WebAuthn. O navegador chama navigator.credentials.create() com essas opções.

POST /api/auth/mfa/webauthn/confirm: Confirma a inscrição WebAuthn enviando a resposta de attestation do navegador.

Códigos de Recuperação

POST /api/auth/mfa/recovery/generate: Gera 10 códigos de recuperação de uso único com 10 caracteres (formato <code>XXXXX-XXXXX</code>). Cada código pode ser usado exatamente uma vez para ignorar o MFA. Um aplicativo autenticador ou uma passkey precisa estar inscrito primeiro.

Códigos de Recuperação São Exibidos Apenas Uma Vez

Os códigos de recuperação são exibidos apenas no momento da geração e não podem ser recuperados depois. Se um usuário perder tanto seu dispositivo autenticador quanto seus códigos de recuperação, um administrador deve excluir manualmente sua credencial MFA no portal antes que ele possa fazer login novamente.

Verificação de MFA

POST /api/auth/mfa/verify: Completa o desafio de MFA após um login com senha bem-sucedido.

CampoObrigatórioDescrição
challengeIdSimO ID do desafio da resposta de login
methodSim"totp", "recovery" ou "webauthn"
codeTOTP / RecuperaçãoCódigo TOTP de 6 dígitos ou código de recuperação (XXXXX-XXXXX)
assertionWebAuthnA resposta de asserção do navigator.credentials.get()

Status do MFA

GET /api/auth/mfa/status: Retorna os métodos de MFA atualmente inscritos do usuário.

Fluxo de Login SSO

Authagonal suporta conexões SSO baseadas em SAML 2.0 e OIDC. O roteamento baseado em domínio detecta automaticamente qual provedor SSO usar com base no endereço de e-mail do usuário.

Verificação de SSO

GET /api/auth/[email protected]

CampoTipoDescrição
ssoRequiredbooleanSe o domínio de e-mail requer SSO
providerTypestring"saml" ou "oidc"
connectionIdstringO identificador da conexão SSO
redirectUrlstringA URL para redirecionar o usuário para o login SSO

Fluxo SAML

O usuário é redirecionado para GET /saml/{connectionId}/login que envia uma SAML AuthnRequest para o provedor de identidade. O IdP autentica o usuário e envia uma resposta SAML de volta para o endpoint Assertion Consumer Service (ACS). Authagonal valida a asserção, cria ou atualiza o usuário e assina um cookie de sessão.

Os metadados SAML para configurar seu IdP estão disponíveis em GET /saml/{connectionId}/metadata.

Fluxo OIDC

O usuário é redirecionado para GET /oidc/{connectionId}/login que redireciona para o provedor de identidade de origem com PKCE. Após o usuário se autenticar, o callback em /oidc/callback troca o authorization code, valida o token de ID e cria ou atualiza o usuário.

Provisionamento JIT: Tanto os fluxos SAML quanto OIDC suportam provisionamento just-in-time, que fica desativado por padrão em cada conexão (Ativar provisionamento JIT). Quando está ativado e o usuário ainda não existe no locatário, ele é criado automaticamente a partir das claims do provedor de identidade. Se já existir, seus atributos de perfil são atualizados para corresponder aos valores mais recentes do provedor.

Roteamento Baseado em Domínio

O roteamento baseado em domínio significa que seus usuários não precisam saber qual provedor SSO utilizam. Inserir o endereço de e-mail é suficiente — Authagonal associa o domínio à conexão SSO correta e redireciona automaticamente.

Backend-for-Frontend (BFF)

Um BFF mantém os tokens OAuth completamente fora do navegador. Sua aplicação de página única não guarda nada além de um cookie de sessão httpOnly, e um cliente confidencial no seu próprio backend executa o fluxo OpenID Connect e mantém os tokens no servidor.

Tudo o que uma aplicação de página única consegue ler, o cross-site scripting consegue roubar, e isso inclui um token de acesso em memória e um refresh token no localStorage. Guardar tokens no navegador também limita o tempo de vida deles, porque um refresh token de longa duração ao alcance de scripts é um risco permanente. A best current practice do IETF OAuth 2.0 for Browser-Based Apps recomenda esse padrão exatamente por esse motivo.

Em troca, você ganha uma sessão que sobrevive a um recarregamento de página sem nenhum token à vista, a renovação tratada para você no servidor, revogação imediata através do logout back-channel, e um proxy autenticado, de modo que sua API nunca precisa interpretar um token que o navegador poderia ter adulterado.

Crie o cliente

No portal, abra Clients e escolha Criar app BFF. Informe a URL base de onde seu aplicativo é servido, por exemplo https://app.acme.com, e o Authagonal registra para você um cliente confidencial corretamente configurado, em vez de deixar que você monte um por conta própria:

ConfiguraçãoValor
URI de redirecionamento{appBaseUrl}/bff/callback
URI de redirecionamento pós-logout{appBaseUrl}/
URI de logout back-channel{appBaseUrl}/bff/backchannel-logout
Tipos de concessãoauthorization_code, refresh_token
Escoposopenid, profile, email, offline_access
PKCE e client secretAmbos obrigatórios

O segredo é exibido uma única vez

A resposta traz clientId, clientSecret e authority, e o segredo nunca pode ser recuperado depois, porque apenas o hash dele é armazenado. Coloque-o direto na configuração ou no cofre de segredos do seu backend. Se você perdê-lo, crie outro cliente em vez de tentar recuperar este.

Conecte ao seu backend

Dois runtimes são suportados e compartilham o mesmo protocolo central: Authagonal.Bff para .NET e @authagonal/bff para Node, este último com adaptadores para Express e Next.js. Aponte qualquer um deles para os valores que o portal acabou de fornecer. O pacote Node também precisa de um cookieSecret próprio, que ele usa para criptografar seus cookies.

.NET
// dotnet add package Authagonal.Bff
builder.Services.AddAuthagonalBff(o =>
{
    o.Authority    = "https://acme.authagonal.io";       // your tenant auth host
    o.ClientId     = builder.Configuration["Bff:ClientId"]!;
    o.ClientSecret = builder.Configuration["Bff:ClientSecret"]!;
    o.Scope        = ["openid", "profile", "email", "offline_access"];
    o.PostLogoutRedirectUri = "https://app.acme.com/";
});

// Trust X-Forwarded-Proto from your ingress. With no options, UseForwardedHeaders() changes nothing.
builder.Services.Configure<ForwardedHeadersOptions>(o =>
{
    o.ForwardedHeaders = ForwardedHeaders.XForwardedProto;
    o.KnownNetworks.Clear();
    o.KnownProxies.Clear();
});

var app = builder.Build();

app.UseForwardedHeaders();   // required behind a proxy or ingress, see the note below
app.MapAuthagonalBff();
app.MapFallbackToFile("index.html");   // your SPA
app.Run();
Node (Express)
// npm install @authagonal/bff
import express from 'express';
import { authagonalBff } from '@authagonal/bff/express';

const app = express();

app.use(authagonalBff({
  authority: 'https://acme.authagonal.io',
  clientId: process.env.BFF_CLIENT_ID,
  clientSecret: process.env.BFF_CLIENT_SECRET,
  cookieSecret: process.env.BFF_COOKIE_SECRET,   // encrypts the session and login cookies
  scope: ['openid', 'profile', 'email', 'offline_access'],
  postLogoutRedirectUri: 'https://app.acme.com/',
}));

app.listen(8080);

Atrás de um proxy, confie nos cabeçalhos encaminhados

Quase toda implantação coloca o BFF atrás de um ingress ou balanceador de carga que termina o TLS e fala HTTP simples com o seu processo. Sem o tratamento dos cabeçalhos encaminhados, o BFF acredita que a requisição é insegura e emite o cookie de sessão __Host- sem o atributo Secure, que os navegadores então descartam silenciosamente. O sintoma é um login que conclui sem erro nenhum e uma sessão que nunca aparece. No .NET, habilite XForwardedProto em ForwardedHeadersOptions e chame app.UseForwardedHeaders() antes de MapAuthagonalBff(), como acima: a chamada sem opções não confia em nenhum cabeçalho. Os adaptadores Node leem X-Forwarded-Proto por conta própria e sempre marcam um cookie __Host- como Secure; ajuste a configuração de trust proxy do seu framework para que o endereço do cliente encaminhado à sua API seja o real.

Endpoints

Montados sob /bff por padrão. Eles precisam ser servidos a partir da mesma origem da sua SPA, porque o cookie de sessão é httpOnly e same-origin: coloque-os atrás do mesmo hostname, e não em um domínio de API separado.

RotaFinalidade
GET /bff/login?returnUrl=/Inicia o login e redireciona para o Authagonal. Depois, devolve o usuário à returnUrl.
GET /bff/callbackA URI de redirecionamento OIDC. Tratada para você; você nunca escreve isso.
GET /bff/userRetorna isAuthenticated, as claims da sessão e sessionExpiresAt. Exige o cabeçalho anti-forgery.
GET|POST /bff/logoutEncerra a sessão localmente e no Authagonal.
POST /bff/backchannel-logoutRecebe notificações de logout do Authagonal, de modo que um logout feito em outro lugar encerre também esta sessão.

A partir do navegador

Toda requisição que não seja de navegação precisa levar um cabeçalho anti-forgery estático. Ele protege contra cross-site request forgery junto com o atributo SameSite do cookie: um envio de formulário cross-site não consegue definir um cabeçalho personalizado, então uma requisição sem ele é recusada.

Verificando quem está autenticado
const me = await fetch('/bff/user', {
  headers: { 'X-Authagonal-Bff': '1' },
}).then(r => r.json());

if (!me.isAuthenticated) {
  // Navigate, do not fetch: this is a redirect to your identity provider.
  window.location.href = '/bff/login?returnUrl=' + encodeURIComponent(location.pathname);
}

Faça login e logout navegando, e não com fetch: location.href = '/bff/login'. Essas rotas respondem com um redirecionamento para o seu provedor de identidade, e uma cadeia de redirecionamentos não é algo que o fetch consiga seguir de forma útil.

Chamando a sua API

O BFF pode encaminhar a sua API sob o caminho base dele e anexar o token de acesso da sessão no percurso. O navegador envia um cookie, a sua API recebe um bearer token que valida normalmente, e nada desse token fica visível para a página nem pode ser forjado por ela. Registre um upstream e as requisições para /bff/api/** chegam nele autenticadas. Deixe a lista vazia e o proxy fica completamente desativado.

Encaminhando uma API upstream
o.Upstreams.Add(new BffUpstream
{
    Prefix        = "/orders",                        // matches /bff/api/orders/**
    TargetBaseUrl = "https://api.internal.acme.com",
    StripPrefix   = false,                            // keep /orders in the forwarded path
});
OpçãoPadrãoO que faz
Upstreams[]As APIs para as quais o proxy encaminha. Vazio desativa o endpoint de proxy.
Prefix/Prefixo de caminho depois de /bff/api que este upstream atende, por exemplo /orders.
TargetBaseUrl-URL base para a qual as requisições são encaminhadas.
StripPrefixfalseRemove o prefixo correspondente antes de encaminhar. Permite usar um prefixo sintético de roteamento para distribuir um único BFF entre vários backends que compartilham o mesmo namespace de caminhos.
AllowAnonymousProxyRequestsfalseEncaminha uma requisição sem sessão utilizável sem um cabeçalho Authorization, em vez de recusá-la. Para uma API que atende tanto chamadores autenticados quanto anônimos.
RequiredAuthority[]Uma trava de autoridade em pares type:action, por exemplo email:send. Quando definida, o proxy verifica os authorization details RFC 9396 do token de saída antes de encaminhar.
AuthorityLocation-A raiz de locations RFC 9396 pela qual este upstream é conhecido, quando a autoridade é concedida sobre um identificador público de recurso diferente do endereço interno que o proxy chama.
StrictAuthorityfalseRecusa uma chamada que carregue uma restrição de concessão que o proxy não consegue avaliar, em vez de encaminhá-la. O proxy encaminha às cegas e não deriva nenhum contexto de restrição, então isso vem desativado por padrão.
ExchangeRoutes[]Rotas de proxy cujas chamadas upstream usam um token trocado e vinculado a um contexto, em vez do token de acesso principal da sessão. O primeiro padrão que corresponder vence.

WebSockets

Um handshake de WebSocket não consegue carregar um cabeçalho personalizado nem um bearer token, então nem o cabeçalho anti-forgery nem o proxy ajudam. Ative os tickets e a SPA pode chamar GET /bff/ws-ticket, colocar o ticket de uso único e curta duração na URL de conexão, e fazer a sua API resgatá-lo. Gere um imediatamente antes de cada conexão: ele é excluído no primeiro uso e expira em segundos.

OpçãoPadrãoO que faz
WsTicketsEnabledfalseAtiva o endpoint ws-ticket. Desativado por padrão.
WsTicketLifetime30sPor quanto tempo um ticket é válido. Mantido curto de propósito, já que ele trafega em uma URL.
TicketExchangeParams[]Parâmetros de query que uma requisição de ticket pode encaminhar para uma troca de token, de modo que o ticket fique vinculado a esse contexto em vez de valer para tudo.

Entregando um token ao navegador, deliberadamente

O sentido de um BFF é que o navegador não guarda nenhum token, então isto é opcional e restrito. Existe para o único caso que o modelo de cookie não alcança: um resource server em outra origem, como um app que você incorpora em um iframe, que precisa ser chamado com um bearer. Ativado, GET /bff/token?resource=… retorna um token trocado: o token da sessão reduzido a um único recurso da lista de permitidos e vinculado a qualquer parâmetro de contexto também permitido. O navegador nunca vê o token da própria sessão, e o que ele recebe tem vida curta e uma única audiência. Uma requisição que nomeie um recurso fora da lista de permitidos é recusada, e é isso que impede que isso vire uma fábrica de tokens de uso geral.

OpçãoPadrãoO que faz
TokenEndpointEnabledfalseAtiva o endpoint de token. Desativado por padrão.
TokenEndpointResources[]Os valores de resource aos quais um token pode ser endereçado. Qualquer outro é recusado.
TokenEndpointExchangeParams[]Parâmetros de query encaminhados para a troca como vínculos de contexto, por exemplo project_id.

Atendendo vários locatários com um só BFF

Defina um parâmetro de query de locatário e uma única implantação atende muitos locatários: /bff/login?slug=acme seleciona o locatário, um resolver fornece a authority e as credenciais de cliente daquele locatário, a chave viaja no cookie de correlação até a sessão, e o logout back-channel resolve o locatário a partir do emissor do token. O resolver padrão mantém o comportamento de locatário único idêntico byte a byte, então você não paga nada por isso a menos que use.

Rodando mais de uma instância

As sessões ficam atrás de IBffSessionStore, cujo padrão é um cache em processo. Isso serve para uma única instância e é errado para várias: um usuário cuja próxima requisição cair em outra réplica é desconectado. Registre um armazenamento compartilhado, como o Redis através de IDistributedCache, antes de adicionar o BFF.

Um armazenamento compartilhado não basta sozinho

Você também precisa de um lock de renovação entre réplicas. O single-flight da renovação é local ao processo, enquanto a sessão e o refresh token rotativo dela vivem no armazenamento que todas as réplicas compartilham. Duas réplicas podem ler a mesma sessão, ambas decidirem que ela precisa ser renovada e ambas resgatarem o mesmo refresh token. Isso é indistinguível de um replay de token roubado, e a resposta correta a um replay é revogar toda a família de concessões, então um BFF com várias instâncias e sem lock pode desconectar usuários como rotina. Forneça-o de uma das duas formas: registre um ILeaseProvider através de clustering, ou implemente IBffRefreshLockStore no seu armazenamento de sessões, o que é uma escrita condicional com tempo de vida e é o caminho mais curto quando você já usa Redis. Um BFF cujo armazenamento parece compartilhado e não tem lock avisa sobre isso na inicialização, em vez de deixar que você descubra pelo ticket de suporte de um usuário.

Opções que vale conhecer

O conjunto completo, na grafia do .NET. O pacote Node aceita as opções centrais em camelCase, então BasePath é basePath e SessionLifetime é sessionLifetimeSeconds. PersistentCookie, CorrelationLifetime (fixo em 15 minutos no Node) e LoginPassthroughParams são exclusivos do .NET.

OpçãoPadrãoO que faz
Authority-O host de autenticação do seu locatário. Os metadados OIDC são descobertos a partir dele. Obrigatório, exceto se você for multi-locatário, caso em que o resolver o fornece.
ClientId-O id do cliente confidencial registrado para este BFF.
ClientSecret-O client secret. Um BFF é um cliente confidencial, então isto é obrigatório.
Scopeopenid profile offline_accessEscopos solicitados. Inclua offline_access, ou não existe refresh token e as sessões terminam quando o token de acesso terminar.
BasePath/bffOnde as rotas do BFF são montadas.
CallbackPath/bff/callbackO caminho da URI de redirecionamento OIDC. Precisa coincidir com aquele com que o cliente foi registrado.
CookieName__Host-agbffNome do cookie de sessão. O prefixo __Host- exige HTTPS, então o desenvolvimento local sobre HTTP simples precisa de outro nome.
SessionLifetime8hPor quanto tempo uma sessão pode viver. Ajuste para corresponder ao tempo de vida absoluto do seu refresh token, ou um usuário ocioso será desconectado enquanto ainda detém uma credencial que continuava válida.
PersistentCookiefalseSe o cookie sobrevive ao fechamento do navegador. De um jeito ou de outro, o refresh token permanece no servidor.
CorrelationLifetime30mQuanto tempo um login pode levar entre o seu início e o callback. Isso limita o cookie que carrega o state, o nonce e o verifier PKCE, então o caso que ele precisa suportar é o do usuário que deixa a tela de login aberta e volta depois.
RefreshThresholdSeconds60Quantos segundos antes da expiração o token de acesso é renovado.
AntiForgeryHeaderX-Authagonal-BffO nome do cabeçalho que o navegador precisa enviar em requisições que não sejam de navegação.
PostLogoutRedirectUri-Onde o navegador chega depois que o logout é concluído.
ReturnUrlAllowlist[]Origens absolutas que uma returnUrl não relativa pode ter como destino. Caminhos relativos são sempre permitidos e todo o resto é forçado para /, então um open redirect não é alcançável pela rota de login.
LoginPassthroughParams[]Parâmetros de query encaminhados de /bff/login para a requisição de authorize, por exemplo prompt, para que um link de introdução leve ao cadastro em vez do login.
TenantQueryParam-Defina para atender vários locatários com um só BFF. Veja acima.

Os dois runtimes se comportam igual

Os pacotes .NET e Node implementam o mesmo contrato de protocolo central, então login, callback, user, logout e logout por back-channel, o cookie, o cabeçalho anti-forgery, o comportamento de renovação e o proxy upstream básico são idênticos. Tickets de WebSocket, o endpoint de token, as rotas de exchange, StripPrefix, os gates de authority e o proxy anônimo são exclusivos do .NET. Os nomes acima estão na grafia do .NET; o Node usa os equivalentes em camelCase.

Tudo é substituível

As peças são interfaces, então você pode mover o BFF para a sua própria infraestrutura sem fazer um fork dele: IBffSessionStore para onde as sessões ficam, ICookieProtector para a criptografia do cookie (ASP.NET Data Protection por padrão) e ITokenClient para falar com os endpoints de token e de revogação. Um único BFF também pode atender vários locatários através de IBffTenantResolver, selecionando o locatário a partir de um parâmetro de query no login e resolvendo-o a partir do emissor do token no logout back-channel.

Opere o seu portal a partir de um assistente de IA

Conecte um assistente de IA ao seu locatário e peça a ele as coisas que você faria clicando pelo portal: encontrar um usuário que não consegue fazer login, verificar se ele ainda tem um segundo fator, convidar alguém, ver quem tem uma função de administrador.

É uma conexão OAuth comum, não uma chave de API. Cada pessoa faz login como ela mesma e aprova o acesso, então um assistente consegue fazer exatamente o que aquela pessoa consegue fazer no portal, e nada além disso. Nada de novo é criado que possa vazar, e revogar um assistente não mexe em nenhum dos outros.

Como ativar

Abra Configurações e ative o acesso de assistente de IA. Ele fica desativado até você fazer isso e, enquanto está desativado, o endpoint não existe, em vez de apenas recusar. Depois de ativado, o painel mostra a URL para colar no seu cliente de IA:

A sua URL do MCP
https://portal-api.authagonal.io/api/v1/mcp/{your-tenant}

Como um assistente obtém permissão

Um assistente se registra sozinho antes de conseguir iniciar um login, e é a ativação do acesso de assistente de IA que permite isso. Você não precisa ativar mais nada e, em especial, não deve ativar o registro dinâmico de clientes no seu locatário de usuários finais por causa disso: essa configuração vale para o locatário que atende os seus próprios usuários, e não é ali que um assistente faz login. Registrar-se não é ter acesso. Um assistente recém-registrado não tem absolutamente nada até que alguém da sua equipe faça login e o aprove, e a partir daí cada ferramenta confere de novo a função dessa pessoa.

O que um assistente pode fazer

Exatamente o que a pessoa que o conectou pode fazer, decidido a cada chamada com base no token dela. Um agente tenant:support recebe as ferramentas de diagnóstico e do dia a dia; as ferramentas de administrador não ficam apenas escondidas dele, elas são recusadas se forem chamadas pelo nome. Tudo o que é restrito dentro do portal continua restrito: mudar o endereço de e-mail de um usuário exige a função de administrador lá, e exige aqui também.

Como é uma concessão comum, você a gerencia do jeito comum: remova o assistente na página Aplicações autorizadas da sua conta e ele não consegue mais renovar, então para de funcionar quando o access token atual expirar. Toda alteração que um assistente faz é gravada no seu registro de auditoria como a pessoa em nome de quem ele agiu, então a trilha é a mesma que você já lê.

As ferramentas

Trinta e três nesta versão. O seu cliente de IA decide quais ativar, então você pode entregar a um assistente apenas as ferramentas de leitura, se for só isso que você quer que ele faça.

FerramentaFunçãoO que faz
find_userSuporteEncontra usuários por e-mail, prefixo de nome ou id. O ponto de partida para todo o resto.
get_userSuporteUm usuário por completo, incluindo se ele está ativo, confirmado e bloqueado.
get_user_mfaSuporteQuais segundos fatores alguém tem inscritos.
get_user_sessionsSuporteOnde um usuário está com sessão aberta no momento.
search_auditSuporteBusca no registro de auditoria por ator, ação ou pelo objeto da ação.
list_usersSuporteLista o diretório, opcionalmente filtrado por uma organização.
get_user_statsSuporteQuantos usuários você tem e quantos usam um segundo fator.
invite_userSuporteConvida alguém por e-mail.
resend_inviteSuporteEnvia um convite de novo.
send_verification_emailSuporteEnvia de novo a mensagem de verificação de e-mail.
update_userSuporteAtualiza um perfil. Alterar o endereço de e-mail continua exigindo administrador.
revoke_user_sessionsSuporteEncerra a sessão de um usuário em todos os lugares.
list_rolesAdministradorAs funções definidas no seu locatário.
list_role_membersAdministradorQuem tem uma determinada função.
assign_roleAdministradorDá uma função a um usuário.
unassign_roleAdministradorTira uma função.
reset_user_mfaAdministradorRemove todos os segundos fatores, para quem perdeu o autenticador.
get_settingsAdministradorA configuração do seu locatário.
list_sso_connectionsAdministradorAs suas conexões de SSO e os domínios que elas cobrem.
list_organizationsAdministradorAs organizações do seu locatário, uma página de cada vez.
get_organizationAdministradorUma organização por id ou slug, com os seus domínios de e-mail.
create_organizationAdministradorCria uma organização. O slug é permanente.
update_organizationAdministradorAltera o nome, as opções de política, os metadados ou a marca de uma organização. O slug não pode mudar.
delete_organizationAdministradorExclui uma organização e todas as suas associações.
list_organization_membersAdministradorOs membros de uma organização, uma página de cada vez.
add_organization_memberAdministradorAdiciona um usuário a uma organização.
update_organization_memberAdministradorAltera o status ou as funções de um membro dentro de uma organização.
remove_organization_memberAdministradorRemove um usuário de uma organização.
add_organization_domainAdministradorReivindica um domínio de e-mail para uma organização. Retorna o registro TXT de DNS a publicar.
verify_organization_domainAdministradorVerifica o registro TXT e marca o domínio como verificado. Pode ser repetido sem risco.
remove_organization_domainAdministradorDescarta a reivindicação de um domínio. Os membros existentes permanecem.
list_user_organizationsAdministradorAs organizações a que um usuário pertence, com o status e as funções em cada uma.
list_clientsDesenvolvedorOs clientes OAuth registrados no seu locatário.

Leitura e escrita ficam marcadas

Cada ferramenta informa ao seu cliente se ela apenas lê, se muda alguma coisa e se essa mudança é destrutiva. Um bom cliente usa isso para fazer uma consulta sem interromper você e para parar antes de algo como remover um segundo fator. Trate isso como uma conveniência, não como um controle: quem realmente decide o que um assistente pode fazer é a sua própria função, verificada a cada chamada.

O que ainda não está incluído

Excluir usuários, criar ou editar conexões de SSO, faturamento, backups e segredos de cliente estão todos ausentes desta versão. A exclusão pertence à sua fila de apagamento, e não ao lado dela; uma conexão de SSO é grande o bastante para que uma edição errada tranque do lado de fora a empresa inteira, então essas ficam somente leitura por enquanto; e uma ferramenta que devolvesse um segredo de cliente o colocaria na transcrição de um assistente. Conte para nós quais dessas você quer e em que ordem.

Autenticação de servidor MCP

Se você expõe um servidor Model Context Protocol, o Authagonal pode ser o servidor de autorização por trás dele. Um assistente de IA se conecta, a pessoa por trás dele faz login e concede o acesso, e o seu servidor recebe um token bearer normal, que você valida como o de qualquer outra API.

A alternativa é uma chave de API colada na configuração de um assistente, ou seja, uma credencial sem nenhum usuário por trás dela, sem expiração, sem etapa de consentimento e sem forma de revogar um conector sem rotacionar a chave para todo mundo. Fazer isso como OAuth significa que a concessão pertence a uma pessoa identificada, fica visível no seu registro de auditoria e pode ser revogada pelo portal sem mexer em mais nada.

Como a conexão acontece

Toda a troca é conduzida por discovery, então um cliente em conformidade não precisa de nada configurado além da URL do seu servidor.

EtapaO que acontece
1O conector chama o seu servidor MCP sem token e recebe um 401 que indica onde procurar.
2Ele busca os seus metadados de recurso protegido, que apontam o seu locatário Authagonal como servidor de autorização.
3Ele busca os metadados do servidor de autorização do locatário e, como nunca foi registrado em lugar nenhum, se registra sozinho.
4Ele envia o usuário para fazer login e aprovar o acesso, indicando o seu servidor MCP como o recurso para o qual quer um token.
5Ele chama o seu servidor de novo com o token bearer resultante, que fica limitado ao seu servidor e àquele usuário.

Nada nessa sequência é específico do Authagonal: é a especificação de autorização do MCP, construída sobre a RFC 9728 para os metadados do recurso, a RFC 8414 para descobrir o servidor de autorização, a RFC 7591 para o registro e a RFC 8707 para nomear o recurso. Um conector que segue a especificação funciona sem precisar de nenhum tratamento especial para nós.

Deixe os conectores se registrarem sozinhos

Um conector que você nunca viu não tem como usar um cliente que você criou à mão, então ele registra um em tempo de execução. Isso vem desativado por padrão. Ative o registro dinâmico de clientes em Configurações e o endpoint de registro aparece no seu documento de discovery; deixe desativado e o endpoint não é anunciado e recusa as requisições. Ativá-lo abre o registro apenas para o seu locatário, nunca para o de mais ninguém.

ProteçãoO que acontece
Tipos de concessãoSó é possível registrar os fluxos de authorization code e de refresh. O auto-registro não consegue criar um cliente máquina a máquina que dispensaria o usuário por completo.
PKCEObrigatório em todo cliente registrado, independentemente do que o registro tenha pedido.
ConsentimentoTambém obrigatório. Um conector registrado não consegue obter um token enquanto uma pessoa não vir o que ele está pedindo e aprovar.
EscoposOs escopos nativos do OIDC estão sempre disponíveis. Além deles, um cliente que se auto-registra só pode pedir um escopo chamado mcp, e somente depois que o seu tenant o definir sem restrições de função. Os escopos roles e groups não podem ser obtidos por auto-registro.
Limite de taxaDez registros por endereço IP por hora, para que um endpoint aberto não possa ser usado para encher o seu repositório de clientes.

Os dois caminhos de discovery são atendidos

Clientes MCP resolvem o servidor de autorização por /.well-known/oauth-authorization-server (RFC 8414), enquanto clientes OIDC usam /.well-known/openid-configuration. O seu locatário responde nos dois com os mesmos metadados, então um conector que segue a especificação do MCP encontra você sem que ninguém precise dizer onde procurar.

O que o seu servidor MCP implementa

Duas coisas pequenas, e depois ele é um resource server comum. Primeiro, publique os metadados de recurso protegido apontando o seu locatário como servidor de autorização. Sirva-os no caminho well-known e, se o seu endpoint MCP estiver em um subcaminho, também na forma com o sufixo de caminho, já que os clientes tentam as duas.

Metadados de recurso protegido
GET https://your-app.example/.well-known/oauth-protected-resource

{
  "resource": "https://your-app.example/mcp",
  "authorization_servers": ["https://acme.authagonal.io"],
  "bearer_methods_supported": ["header"],
  "scopes_supported": ["mcp"]
}

Segundo, quando uma chamada chegar sem um token válido, responda 401 com um cabeçalho WWW-Authenticate apontando para esses metadados. É esse cabeçalho que transforma uma recusa em uma conexão: sem ele o cliente não tem como descobrir onde se autenticar e simplesmente falha.

Validando o token
// Validate the connector's token like any other resource server.
builder.Services.AddAuthentication().AddJwtBearer("McpBearer", o =>
{
    o.Authority = "https://acme.authagonal.io";              // your tenant
    o.TokenValidationParameters.ValidAudience = "https://your-app.example/mcp";
});

// Unauthenticated? Point the connector at the metadata rather than just refusing.
http.Response.Headers.WWWAuthenticate =
    "Bearer resource_metadata=\"https://your-app.example/.well-known/oauth-protected-resource\"";
return Results.Unauthorized();

Verifique a audience, não apenas a assinatura

Valide que o token foi emitido para o seu servidor. O conector indica o seu servidor MCP como o recurso, então a audience do token é a URL do seu recurso. Um resource server que confere apenas a assinatura e o emissor vai aceitar um token emitido para outro recurso do mesmo locatário, e é assim que o acesso de um conector vira o de outro.

Escopos, planos e revogação

Defina um escopo chamado mcp na sua página Escopos, sem restrições de função, e um conector que se auto-registra poderá solicitá-lo; ele aparece na tela de consentimento para que o usuário veja o que está aprovando. O subject do token é a pessoa que fez login, então o seu servidor pode decidir o que essa pessoa específica pode fazer, em vez de tratar todos os conectores igual. Um conector auto-registrado não pode solicitar os escopos roles ou groups, então consulte essas informações do seu lado em vez de esperar recebê-las no token.

Como é uma concessão OAuth comum, a revogação funciona do jeito comum: o usuário remove o conector na página Aplicações autorizadas da conta dele, o que descarta a concessão e o refresh token, de modo que o conector não consegue renovar. Os access tokens existentes dele são recusados na hora por /connect/introspect e /connect/userinfo; um servidor que apenas valida o JWT localmente aceita um desses tokens até que expire. O registro de auditoria registra cada login com o cliente ao qual ele se destinava.

ConfiguraçãoO que acontece
Dynamic client registrationConfiguração do portal que permite aos conectores se registrarem sozinhos. Desativada por padrão.
mcpO único escopo além dos nativos do OIDC que um cliente que se auto-registra pode solicitar. Defina-o no seu tenant, sem restrições de função, para oferecê-lo.
resourceO parâmetro que um conector envia para indicar o seu servidor MCP, o que restringe a audience do token a ele.

Crie uma interface de login personalizada

Substitua as telas de login, registro, redefinição de senha e MFA hospedadas pela Authagonal pela sua própria interface, enquanto a Authagonal continua cuidando da autenticação, MFA, SSO, sessões e emissão de tokens. Dois caminhos: use nossa biblioteca de componentes React ou chame a API de autenticação diretamente de qualquer framework. É opcional: primeiro ative Interface de início de sessão personalizada em Definições → Sessão.

A fully customized hosted login page with a tenant logo, brand color, and support email in the footer

Pré-requisito: um domínio personalizado no seu domínio raiz

A sessão de login é um cookie first-party, então sua interface e o servidor de autenticação da Authagonal devem compartilhar um domínio registrável. Aponte um domínio de autenticação personalizado para a Authagonal no mesmo domínio raiz em que seu aplicativo é executado — por exemplo, autenticação em login.acme.com, aplicativo em app.acme.com. A configuração Custom login UI permanece desativada até que exista um domínio personalizado ativo.

Sua interfaceHost de autenticaçãoFunciona?
app.acme.comlogin.acme.com✅ mesmo domínio raiz
acme.comauth.acme.com✅ mesmo domínio raiz
app.acme.comacme.authagonal.io❌ cross-site
myapp.iologin.acme.com❌ cross-site

Por que um domínio personalizado é obrigatório

Um cookie de sessão cross-site seria um cookie de terceiros — que os navegadores (Safari, Chrome) estão eliminando gradualmente. Manter a autenticação no seu próprio domínio raiz torna o cookie first-party e preparado para o futuro, e é o que a plataforma impõe: chamadas de autenticação cross-origin só são aceitas de uma origem que compartilhe o domínio raiz do host de autenticação.

Nenhuma configuração de CORS no cliente é necessária para as chamadas /api/auth: assim que a Interface de início de sessão personalizada estiver ativada, qualquer origem no mesmo domínio registrável do seu domínio de autenticação é admitida automaticamente. Adicione a origem da sua interface (por exemplo, https://app.acme.com) às CORS Origins permitidas do cliente (Clients → URIs) somente se o navegador também realizar a troca de tokens.

React: @authagonal/login

npm i @authagonal/login entrega a lógica de autenticação e a interface em um único pacote — o mesmo sobre o qual o login hospedado da Authagonal é construído. Escolha sua altitude:

  • Aplicativo completo — adicione App e personalize o tema via branding.
  • Componha páginas — use LoginPage, MfaChallengePage, ResetPasswordPage… dentro do seu próprio layout.
  • Primitivos + lógica — crie suas próprias telas com AuthLayout/Button/Input e o cliente da API (login, mfaVerify, forgotPassword, …).
Uma tela personalizada usando a API do @authagonal/login
import { AuthLayout, Input, Button, login, ApiRequestError } from '@authagonal/login';

// returnUrl: the /connect/authorize URL your login page was opened with
function MyLogin({ returnUrl }: { returnUrl: string }) {
  async function onSubmit(email: string, password: string) {
    try {
      const res = await login(email, password, returnUrl);  // POST /api/auth/login (sets the session cookie)
      if (res.mfaRequired) {/* render your MFA step, then mfaVerify(res.challengeId!, 'totp', code) */}
      else if (res.mfaSetupRequired) {/* enrol first: mfaTotpSetup(res.setupToken) */}
      else window.location.href = returnUrl;                 // resume /connect/authorize
    } catch (e) {
      if (e instanceof ApiRequestError) {/* show e.message; e.error is the error code */}
    }
  }
  return <AuthLayout>{/* your own markup + <Input/> <Button/> */}</AuthLayout>;
}

Qualquer framework: chame a API de autenticação

Não usa React? Chame os endpoints do fluxo de autenticação diretamente (em /api/auth) e, em seguida, repasse para o fluxo OIDC padrão /connect/authorize. Envie credentials: 'include' para que o cookie de sessão seja armazenado.

EndpointFinalidade
POST /api/auth/loginAutentica; retorna mfaRequired ou uma URL de retorno
POST /api/auth/registerRegistro self-service (quando habilitado)
POST /api/auth/forgot-passwordInicia uma redefinição de senha
POST /api/auth/reset-passwordConclui uma redefinição de senha
GET /api/auth/password-policyPolítica de senha (para renderizar as regras)
POST /api/auth/mfa/*Configuração + verificação de MFA (TOTP, WebAuthn, recuperação)

Use credentials: 'include'

A sessão é um cookie, então suas requisições fetch devem enviar credenciais. Chamadas cross-origin só funcionam quando Custom login UI está habilitado e sua origem compartilha o domínio raiz do host de autenticação — caso contrário, são recusadas com 403.
Autentique e, em seguida, repasse para o OIDC
# 1. Authenticate (browser fetch; credentials:'include' so the session cookie is stored)
curl -i -X POST https://login.acme.com/api/auth/login \
  -H "Content-Type: application/json" \
  -H "Origin: https://app.acme.com" \
  --data '{"email":"[email protected]","password":"..."}'
# (handle {"mfaRequired":true} → POST /api/auth/mfa/verify, then continue)

# 2. Hand off to the OAuth flow: top-level navigation to the authorize endpoint with PKCE:
# https://login.acme.com/connect/authorize?client_id=my-app&redirect_uri=...&response_type=code
#   &scope=openid%20profile%20email&code_challenge=...&code_challenge_method=S256
# The session cookie (same-site) authenticates the user; you get back a code → exchange at /connect/token.

Um Tenant, Muitos Clientes

Um padrão para um integrador, um tenant e N clientes com marca própria, cada um com seu domínio de login e seus próprios usuários, sem um tenant por cliente. É para isso que o provisionamento declarativo e as organizações existem: transformar isso em uma mudança de configuração, e não em uma tarefa de engenharia.

A estrutura

  • Uma organização por cliente, dentro de um único tenant.
  • Um domínio de login com marca por cliente, cada um fixado à organização desse cliente: entrar nele só pode emitir um token para essa organização.
  • A aplicação também é servida por host de cliente, tudo a partir do mesmo deployment: nada no código, no build ou na imagem muda entre os clientes.
  • A relying party escolhe sua authority pelo host em que está rodando, e não por uma constante de build: o mesmo bundle se conecta a um domínio de login diferente conforme o host de cliente que o serviu.

Passo a passo

Provisione o cliente. Chame o endpoint de provisionamento declarativo com uma spec que cita a nova organização e seu domínio. A chamada é idempotente e limitada por seção.

Spec de provisionamento
{
  "organizations": [
    { "slug": "acme", "name": "Acme Pty Ltd" }
  ],
  "customDomains": [
    { "domain": "login.acme.example", "organizationSlug": "acme" }
  ]
}

Aponte o DNS do cliente para o tenant. Um CNAME na zona do próprio cliente, comprovando controle e intenção, sem token TXT.

CNAME record
_authagonal-challenge.login.acme.example.  CNAME  <slug>.<platformDomain>.

Mesma conta Cloudflare da plataforma?

O registro deve ser somente DNS (sem proxy): um CNAME com proxy entre duas zonas na mesma conta nunca chega ao SaaS custom hostname da plataforma. Uma zona de cliente em outra conta nem tem um toggle de proxy que possa ser configurado errado.

Aponte a aplicação para o host do cliente. A relying party resolve a própria authority OIDC a cada requisição, pelo host que está servindo no momento. Um host sem entrada no mapa de clientes recorre à derivação clássica de tenant único, então adicionar um cliente é puramente aditivo.

oidc.ts
export function resolveCustomer(): { authority: string; clientId: string } {
  const cfg = getConfig();
  const customer = cfg.customers?.[window.location.host];
  if (customer) return customer;
  const baseDomain = cfg.baseDomain || window.location.hostname.replace(/^consumer\./, '');
  return { authority: `https://${cfg.tenantSlug}.${baseDomain}`, clientId: cfg.clientId };
}

O cliente não pede nada específico de organização: nenhum parâmetro organization, nenhum scope por cliente. A fixação de domínio faz toda a seleção de organização no lado do servidor, e é isso que faz "a aplicação é o mesmo código para todos os clientes" ser verdade de fato.

O que o cliente vê

A página de login exibe a marca própria de cada organização mesclada sobre a do tenant. Veja Substituição de marca. Cada cliente pode ter seu próprio nome de app, logo, cor e e-mail de suporte sem afetar os demais.

Um usuário do cliente A que tenta entrar no host do cliente B é recusado, e não vê os dados do cliente B, em uma de duas formas, dependendo de como o conflito surgiu:

  • A relying party não envia nada e simplesmente chega ao domínio fixado: a fixação fornece a organização em nome do usuário, a seleção passa a ser explícita, e um usuário do cliente A sem associação em B é recusado no ponto em que o token seria emitido.
  • A relying party cita ela mesma uma organização diferente: recusado diretamente pelo middleware de fixação de domínio com um 400, antes de qualquer página de login ser exibida.

A recusa por associação redireciona de volta ao app

A primeira forma acima não é uma página de login quebrada: é um redirecionamento OIDC comum com error=access_denied de volta ao redirect_uri da própria relying party, com uma descrição que nomeia exatamente qual associação de organização estava faltando.

Integrando o cliente N+1

Com o Terraform conduzindo a chamada de provisionamento, integrar mais um cliente é editar um arquivo: mais uma entrada no array organizations, mais uma entrada de domínio que a fixa, mais um registro DNS. Nada na aplicação, no deployment ou no build muda: o resolvedor baseado em host reconhece o novo cliente assim que a entrada de configuração existe.

Implementação de referência

Um tenant de dev persistente exercita todo esse padrão de ponta a ponta em dois domínios de clientes reais, com uma suíte de testes end-to-end que provisiona membros, verifica a marca e a claim org_id e confirma as duas formas de recusa acima. É documentação executável, não apenas uma descrição.

Execute localmente
cd e2e-consumer && DOMAIN=authagonal.dev npx playwright test organizations-domains

A suíte roda por padrão como qualquer outro spec; ela pode ser ignorada em um ambiente em que os domínios de referência não estão provisionados, já que é o único spec da suíte que depende de infraestrutura fora do controle do próprio repositório.

Planos e Limites

Authagonal oferece um plano Free e quatro níveis pagos. Todo plano inclui todos os recursos de autenticação. Os planos diferem no limite de Usuários Ativos Mensais (MAU) e no preço de excedente, e o plano Free tem apenas suporte da comunidade, sem a central de suporte do locatário.

Níveis de Plano

PlanoLimite de MAUExcedenteCusto de Excedente/Usuário
Free250Não—
Starter1,000Não—
Pro5.000Sim$0,04/usuário
Scale25.000Sim$0,025/usuário
Enterprise100.000Sim$0,015/usuário

Usuários Ativos Mensais (MAU)

Um Usuário Ativo Mensal é qualquer usuário único que se autentica com sucesso pelo menos uma vez durante um mês civil (UTC). Usuários provisionados via SCIM que não fizeram login não contam para o total de MAU.

Excedente: se o seu plano suporta excedente (Pro e superiores) e o excedente está habilitado para o seu locatário (fica desativado por padrão), usuários além do limite de MAU são cobrados pela taxa por usuário mostrada na tabela de planos acima. Um limite de excedente define o número máximo de usuários extras permitidos além do limite.

Aplicação: se o seu plano não suporta excedente (Free, Starter) ou o excedente não está habilitado, usuários que já fizeram login neste mês sempre mantêm o acesso. Quando o locatário excede seu limite pela primeira vez, começa um período de carência de 10 dias durante o qual novos usuários ainda podem fazer login. Depois dele, usuários que não fizeram login neste mês são recusados até o mês seguinte ou até você fazer upgrade.

Conjunto Completo de Recursos em Todos os Planos

Todos os planos incluem o conjunto completo de recursos — SSO, SCIM, MFA, domínios personalizados, marca, webhooks, registro de auditoria e o portal.