Skip to main content

Configuração do Vault para Self-Hosting

O Switchbord armazena secrets por workspace no Supabase Vault — uma extensão do Postgres que criptografa secrets no nível do banco de dados. Esta página cobre o que quem faz self-hosting precisa saber para fazer o vault funcionar corretamente, especialmente ao executar múltiplos workspaces.

Visão geral: Dois Modos de Resolução de Secrets

O Switchbord suporta duas abordagens para fornecer secrets em runtime, como o token de acesso da Meta: Modo Vault (padrão, recomendado) Secrets são armazenados por workspace em vault.secrets, vinculados a cada workspace via app_private.workspace_secret_bindings. O worker os lê em runtime usando funções RPC do Supabase. Esta é a abordagem correta para qualquer deployment com mais de um workspace. Fallback por variável de ambiente (apenas single-workspace) Se SELF_HOSTED=true estiver definido e uma leitura do vault falhar, o worker recorre a WHATSAPP_META_ACCESS_TOKEN a partir do ambiente. Isso é uma conveniência para operadores executando um único workspace que desejam pular completamente a configuração do vault.
SELF_HOSTED=true contorna as consultas ao vault e serve uma credencial compartilhada a todos os workspaces. Se seu deployment tiver mais de um workspace, isso fará com que as mensagens do workspace A sejam enviadas usando o token do workspace B. Não use o fallback por variável de ambiente em deployments multi-workspace.

Por que Deployments Multi-Tenant Devem Usar o Vault

Quando o worker processa uma mensagem de saída, ele resolve o token de acesso da Meta procurando o workspace que é dono da conversa. No modo vault, ele chama sb_read_workspace_secret(workspace_id, 'meta-access-token') — uma consulta com escopo definido que retorna apenas o secret pertencente àquele workspace. Com SELF_HOSTED=true, a consulta é completamente pulada e o valor da variável de ambiente é retornado independentemente de qual workspace está fazendo a requisição. Não há isolamento por workspace. Um segundo workspace adicionado depois usará silenciosamente o token do primeiro workspace, o que falhará ou — pior — terá sucesso com a conta errada.
Se você inicialmente fez o deployment com SELF_HOSTED=true para um único workspace e agora está adicionando um segundo workspace, você deve remover essa flag, configurar os secrets do vault para ambos os workspaces e reiniciar o worker antes que o segundo workspace funcione corretamente.

Como os Secrets Fluem pelo Sistema

1

O operador salva uma credencial em Settings

O operador abre Settings → Provider e insere um token de acesso da Meta (ou uma API key para um provider de IA). O app web do Switchbord envia isso para /api/settings/secrets.
2

A API armazena o secret no Supabase Vault

A rota da API chama storeWorkspaceSecret(workspaceId, secretKind, value), que chama vault.create_secret() e insere uma linha em app_private.workspace_secret_bindings mapeando o workspace ID e o secret kind para o vault secret ID.
3

O worker lê o secret no momento do envio

Quando o worker está prestes a enviar uma mensagem, ele chama a função RPC do Supabase sb_read_workspace_secret com o workspace ID e o secret kind. A função é executada com privilégios SECURITY DEFINER, lê de vault.secrets, e retorna o valor decriptado. Nenhuma conexão direta com o banco de dados é necessária a partir do worker.
O worker nunca armazena secrets em cache entre requisições. Cada operação de envio dispara uma nova leitura do vault, de modo que rotacionar um secret em Settings tem efeito imediato.

Requisitos de Configuração do Supabase

Extensão Vault

O Supabase Vault é habilitado por padrão em todos os projetos do Supabase Cloud. Se você está executando uma instância self-hosted do Supabase, confirme que a extensão está habilitada:
Se a consulta não retornar nenhuma linha, habilite-a:
As migrações do Switchbord também criam o schema app_private e a tabela workspace_secret_bindings automaticamente quando você executa supabase db push ou aplica migrações. Você não precisa criá-los manualmente.

Funções RPC

O worker usa duas funções wrapper RPC públicas que devem estar presentes no seu banco de dados:
  • sb_read_workspace_secret(p_workspace_id uuid, p_kind text) — retorna o valor do secret decriptado para um workspace e secret kind
  • sb_resolve_workspace_by_verify_token(p_verify_token text) — retorna o workspace ID que corresponde a um determinado verify token da Meta
Essas funções são criadas pelas migrações do Switchbord. Se você encontrar erros de function does not exist, execute novamente suas migrações contra o banco de dados de destino:

Armazenando Secrets

Há duas formas de popular secrets no vault para um workspace: UI de Settings (recomendado) Abra Settings → Provider no app web do Switchbord e insira as credenciais diretamente. A UI chama a API de escrita do vault automaticamente. Nenhum acesso direto ao banco de dados é necessário. SQL editor do Supabase Dashboard Para configuração inicial ou carregamento em massa, você pode inserir secrets diretamente:
Não insira secrets em texto plano em nenhuma tabela de schema público. Sempre use vault.create_secret() para que o valor seja criptografado antes do armazenamento.

Variáveis de Ambiente do Worker

O worker precisa apenas de uma service role key do Supabase para ler do vault. Nenhuma conexão direta com o banco de dados é necessária para leituras. Obrigatórias: Opcionais:
Se você está fazendo deploy no Railway, defina essas como service variables no painel de ambiente do seu serviço worker. O worker as capturará no próximo deploy sem qualquer alteração de código.

Referência de Tipos de Secret


Solução de Problemas

vault_unavailable

A extensão vault não está habilitada, ou o schema app_private está ausente.
  • Confirme que a extensão vault existe (veja a verificação SQL acima)
  • Execute novamente as migrações do Switchbord: supabase db push
  • Confirme que o SUPABASE_SECRET_KEY do worker é uma service role key válida, não a chave anon

vault_read_error

A função RPC existe, mas retornou um erro ao tentar ler um secret.
  • Verifique se sb_read_workspace_secret foi criada com sucesso pelas suas migrações
  • Confirme que SUPABASE_SECRET_KEY tem permissões de service role (a chave anon não pode chamar funções SECURITY DEFINER que verificam por service_role)
  • No SQL editor do Supabase, verifique se a função existe: \df sb_read_workspace_secret

vault_secret_missing

A função executou com sucesso, mas não encontrou vínculo para o workspace e secret kind solicitados. O secret nunca foi armazenado.
  • Abra Settings → Provider para o workspace afetado e salve a credencial ausente
  • Ou insira o vínculo manualmente usando o SQL acima
  • Verifique se o workspace ID em app_private.workspace_secret_bindings corresponde ao workspace que está fazendo a requisição

O worker envia mensagens com a conta errada

Este é um sintoma de SELF_HOSTED=true estar definido em um deployment multi-workspace. A credencial de fallback por variável de ambiente está sendo usada em vez dos secrets do vault por workspace. Remova SELF_HOSTED=true do ambiente do worker e garanta que todos os workspaces tenham seus secrets configurados no vault.

Guias Relacionados