Skip to content

Personificação

Público

Este artigo é para operadores da plataforma GCM. Administradores de igreja devem ver Usuários e funções — a personificação só está disponível para a equipe com a claim platform_admin ou superadmin, e é a ação mais auditada da plataforma.

A personificação permite que um usuário da equipe entre no espaço de trabalho de um cliente como se fosse o admin daquela organização, para que ele possa reproduzir um bug, rodar uma correção pontual ou guiar um cliente por uma tela em uma chamada. É um recurso regular, não uma porta dos fundos — cada entrada e saída é capturada em platform_audit_log, restrita a uma chave do sessionStorage (não localStorage, não um cookie) e termina automaticamente quando a aba fecha.

Transferência de personificação a partir da ficha de detalhes da organização

Como iniciar uma sessão

Na lista Organizações, abra a ficha de detalhes de qualquer linha (o chevron no final da linha, ou Abrir na tabela de operações de faturamento). A ficha lateral direita mostra plano, status, equipe e módulos. O botão azul Abrir conta no topo da linha de ações é o ponto de entrada.

Clique nele, e três coisas acontecem em ordem:

  1. Um diálogo de confirmação pede um motivo em texto livre. Isso é obrigatório.
  2. O frontend chama o RPC Postgres start_impersonation com o id da organização-alvo e o motivo.
  3. Se o RPC tiver sucesso, a linha em admin_impersonation é criada, o id da organização é escrito no sessionStorage sob a chave gcm_impersonation, o cache do React Query é limpo (para prevenir vazamento de dados entre organizações) e o usuário é redirecionado para / — que agora resolve para a camada de tenant do cliente.

Uma faixa vermelha dizendo "Vendo como ... (personificação)" aparece no topo da camada do tenant. As páginas de admin do cliente renderizam como se você fosse ele: o painel dele, os membros dele, as doações dele. Você pode clicar em qualquer botão que o admin dele poderia clicar.

Um alvo de cada vez

Iniciar uma nova personificação enquanto uma está em andamento é bloqueado pelo RPC. Termine a sessão atual primeiro. O comportamento é intencional — a tabela de auditoria assume uma linha ativa por ator.

Para que serve o motivo

O campo de motivo é obrigatório e termina em três lugares:

  • A coluna admin_impersonation.reason.
  • A linha platform_audit_log com action = 'impersonation_started'.
  • O KPI de "Personificações" de 7 dias na aba do log de auditoria.

Escreva algo que um futuro auditor possa ler. "Ticket de suporte #4421 — doador vê 500 no formulário de doação" é bom. "verificando" não é. O auditor é você, em 90 dias, depois que o cliente reclamar.

Como a RLS te mantém no escopo

Enquanto você está personificando, o auxiliar SQL current_org_id() retorna o id da organização-alvo em vez do seu. Toda política de RLS na plataforma usa current_org_id() (não claims brutas do JWT), então leituras e escritas são silenciosamente restritas aos dados do cliente. Você pode ler os membros dele porque a política passa; você não pode ler os membros de outra organização porque o auxiliar não retorna o id dela.

É por isso que usamos current_org_id() e não auth.jwt() ->> 'organization_id' em políticas. O segundo vazaria pela personificação.

Há uma rede de segurança extra: funções edge leem o contexto de personificação via getCallerContext para que elas também saibam que estão rodando sob o id de um cliente, não o seu. Logs de auditoria incluem tanto actor_id (você) quanto target_org_id (o cliente) para que uma trilha forense exista de qualquer forma.

Como uma sessão termina

Uma sessão termina de três formas:

  1. Você volta para o modo plataforma — clique em Voltar à plataforma na faixa. O frontend chama end_impersonation, limpa o sessionStorage, limpa o cache do React Query, escreve uma linha de auditoria impersonation_ended e te empurra para /platform.
  2. Você fecha a aba — o sessionStorage é apagado automaticamente. A linha admin_impersonation permanece aberta até você fazer login de novo, mas o escopo do JWT já foi e o próximo login do usuário da equipe a fecha. Razão para esse design: um dispositivo roubado não pode retomar uma sessão reabrindo a aba.
  3. Você faz logout — igual a fechar a aba do ponto de vista da personificação.

Encadeamento (personificar, atualizar a aba, personificar outra pessoa) é bloqueado porque a nova chamada de RPC termina a linha anterior antes de criar uma nova.

O que você deve e não deve fazer

Fazer

  • Reproduzir o bug que o cliente relatou, e então voltar.
  • Guiar um cliente por uma tela em uma chamada — ele vê seu cursor, você vê os dados dele.
  • Rodar uma correção pontual documentada (por exemplo, semear um fundo padrão ausente) quando ele aprovou a mudança por escrito.

Não fazer

  • Editar configuração que o cliente não esperaria que você tocasse. Se não tem certeza, pergunte primeiro e linke a solicitação no campo de motivo.
  • Enviar mensagens, postar em canais ou disparar workflows como o cliente. O destinatário vê o nome e número da organização, não o seu — qualquer coisa que você envie é permanentemente atribuída a eles.
  • Permanecer em personificação mais do que a tarefa leva. A faixa é visível para qualquer um que passe pelo seu monitor.

Lendo a trilha de auditoria de personificação

A aba Log de auditoria carrega um KPI de 7 dias para personificações e o AuditLogViewer te deixa filtrar por ação. Três ações importam:

  • impersonation_started — início bem-sucedido. Os metadados incluem target_org_id, org_name, reason.
  • impersonation_ended — saída limpa via Voltar à plataforma.
  • impersonation_failed — o RPC start_impersonation rejeitou a chamada. Os metadados incluem o erro subjacente. Uma tentativa falha geralmente é um disparo errado de RLS, uma organização-alvo que não existe mais ou uma conta de equipe que acabou de perder sua claim.

Filtre por actor_email = <você> para ver suas próprias sessões dos últimos 7 dias. Filtre por metadata->>'target_org_id' = <id> para ver cada sessão da equipe contra um cliente — uma resposta útil para "alguém da sua equipe entrou na nossa conta recentemente?".

Quando algo parece errado

Se você chega em uma página de tenant e os dados não parecem do cliente — nomes de membros errados, idioma errado, logo de organização errado — volte para o modo plataforma imediatamente. Dois modos de falha podem causar isso:

  1. Cache velho — o cache do React Query sobreviveu à entrada. Faça um hard refresh da página; se isso resolve, o bug está no caminho de entrada e vale um issue do Sentry.
  2. Linha de personificação travada — sua sessão anterior não foi fechada limpamente e current_org_id() está retornando o alvo antigo. Faça logout completo, faça login novamente e o auth-hook vai resetar o JWT.

Em ambos os casos, escreva uma entrada de auditoria depois explicando o que você viu. Todo o ponto de a superfície de personificação ser auditável é que aprendemos com casos extremos.