name: supabase-edge-functions-auth-debug
description: Debugar erros 401/403 em Supabase Edge Functions (Deno) no VPS — tokens JWT sem sub, verifyTokenInline, bypass is_super_admin, e chamadas internas GoTrue. Aplica-se a projetos deploy-vps na VPS 31.97.243.106.
triggers:
- edge function retorna 401 Unauthorized
- token JWT service_role não funciona
- admin panel dá 403 Forbidden após login
- verifyTokenInline rejects service role token sem sub
- GoTrue admin API retorna 404 via Kong
Supabase Edge Functions Auth Debug (VPS)
Contexto
- - VPS: 31.97.243.106, Docker compose project
deploy-vps - - JWT_SECRET:
kETxz0JNJhJyg5UYxbd8zG6g2v9kXTYZGjY+3v7LUKI=(HS256) - - Service role tokens têm
role: supabase_admin+is_super_admin: truemas SEM camposub - - ANON_KEY TEM
sub, service role NÃO TEM - - Edge functions em
/home/deno/functions/dentro do containerdeploy-vps-functions-1 - - GoTrue direto (bypass Kong):
http://deploy-vps-auth-1:9999/admin/users - - NUNCA dar
docker restartno Kong — rotas Kong são perdidas e não voltam automaticamente - - Service role token usa
payload.rolecomo id —"supabase_admin"não existe na tabelauser_roles - -
dbFetchnão deve enviarAuthorization: Bearer SERVICE_ROLE_KEYpara PostgREST — PostgREST valida como JWT de usuário e falha na assinatura - - Ordem de debugging é crítica — não avanzar se problema anterior não está resolvido
Ordem de debugging
Sempre seguir esta ordem — não pular etapas:
1. Token válido? (exp está no futuro?) → se não, gerar novo
2. verifyTokenInline aceita sem sub? → se não, aplicar fix
3. 401 → 403? (token aceito mas admin check falha) → confirmar
4. is_super_admin bypass funciona? → aplicar fix
5. Testar
Problemas e fixes
P1: verifyTokenInline rejeita tokens sem sub
Tokens de service role não têm sub. Código original rejeita todos:
`typescript
if (!payload.sub) return null; // → 401 Unauthorized
`
Fix — permite tokens com is_super_admin: true mesmo sem sub:
`typescript
if (!payload.sub && !payload.is_super_admin) return null;
const id = payload.sub || payload.role; // usa "supabase_admin" como id
`
P2: is_super_admin não faz bypass da verificação de admin role
Token passa na verificação JWT (vira 403 em vez de 401) mas isCallerAdmin("supabase_admin") nunca encontra nada na tabela user_roles.
Fix — depois de verifyTokenInline(token), decodificar payload e pular verificação DB:
`typescript
const callerPayload = JSON.parse(new TextDecoder().decode(
base64UrlDecode(token.split('.')[1] + '==')
));
const isSuperAdmin = callerPayload.is_super_admin === true;
if (!isSuperAdmin) {
const hasAdmin = await isCallerAdmin(caller.id);
if (!hasAdmin) {
return new Response(JSON.stringify({ error: "Forbidden" }), {
status: 403,
headers: { ...corsHeaders, "Content-Type": "application/json" },
});
}
}
`
P3: SERVICE_ROLE_KEY expirado
Token tem exp no passado. Gerar novo:
`python
import jwt, time
secret = 'kETxz0JNJhJyg5UYxbd8zG6g2v9kXTYZGjY+3v7LUKI='
payload = {
'iss': 'supabase', 'ref': 'rochasales',
'role': 'supabase_admin',
'iat': int(time.time()),
'exp': int(time.time()) + 28800,
'is_super_admin': True,
'email': 'service_role@rochasales'
}
print(jwt.encode(payload, secret, algorithm='HS256'))
`
Atualizar em /docker/deploy-vps/.env e recriar container:
`bash
docker compose up -d functions
`
P4: GoTrue admin API via Kong retorna 404
dbFetch com endpoint /auth/v1/admin/users gera URL /rest/v1/auth/v1/admin/users — PostgREST não tem rota para isso.
Criar authFetch separada que chama GoTrue diretamente:
`typescript
async function authFetch(endpoint: string, options: RequestInit = {}) {
const response = await fetch(http://deploy-vps-auth-1:9999${endpoint}, {
...options,
headers: {
'Authorization': Bearer ${SERVICE_ROLE_KEY},
'Content-Type': 'application/json',
...options.headers,
},
});
return response;
}
`
Confirmar nome do container GoTrue na rede Docker:
`bash
docker network inspect deploy-vps_backend | grep -A5 deploy-vps-auth
`
Deploy de correções
`bash
Copiar arquivo corrigido para o container
docker cp /tmp/index.ts deploy-vps-functions-1:/home/deno/functions/main/index.ts
Reiniciar container (não afeta Kong nem outras apps)
docker restart deploy-vps-functions-1
Verificar logs
docker logs deploy-vps-functions-1 --tail 20
`