Estrutura de Acessos
Quem pode fazer o quê, sobre qual território e conquista — e como os agentes AI entram como identidades de primeira classe, com guardrails de aprovação humana.
Três camadas de autorização
Autorização = (pode a ação?) ∧ (pode neste client?) — com o banco como rede de segurança.
Papéis (roles)
Fixos em código no MVP. Custom roles em banco = fase enterprise.
| Role | Tipo | Escopo | Poder |
|---|---|---|---|
| owner | interno | Account | Billing, deletar território, tudo. |
| admin | interno | Workspace | Gerencia membros, clients, integrações (sem billing). |
| manager | interno | Workspace | Opera todos os clients; sem billing/membros. |
| member | interno | Client(s) | Opera só os clients atribuídos via client_access. |
| client_user | EXTERNO | Client | O cliente final. Vê só a conquista dele, read-only (portal). |
Matriz de permissões
Permissões no formato resource:action, versionadas em código.
| Permissão | owner | admin | manager | member | client_user |
|---|---|---|---|---|---|
| billing:manage | ✓ | · | · | · | · |
| members:manage | ✓ | ✓ | · | · | · |
| integration:connect | ✓ | ✓ | ✓ | · | · |
| crm:read / write | ✓ | ✓ | ✓ | ✓* | read |
| ads / social / seo · operar | ✓ | ✓ | ✓ | ✓* | read |
| budget:spend · post:publish | ✓ | ✓ | ✓ | opt | · |
| agent:create / configure | ✓ | ✓ | ✓ | · | · |
| agent:approve | ✓ | ✓ | ✓ | · | · |
* escopado aos clients atribuídos. budget:spend, post:publish e agent:approve são permissões perigosas, isoladas de propósito — são a base do guardrail dos agentes.
Interno × Externo · o portal do cliente
type = internal
A equipe da agência. Enxerga o território e seus clients conforme o role. Acessa integrações, custos de AI, billing.
type = external
O cliente final. Obrigatoriamente filtrado por client_access: nunca vê dados no nível do território (billing, outros clients, custo de AI). Uma 2ª camada de RLS impõe isso.
Agentes como identidades · service accounts
Todo agente AI age via uma identidade não-humana, permission-bounded.
Identidade
Cada agente tem um service_account com escopo próprio. Nunca pode mais do que suas permissões — um agente de social tem post:draft, não post:publish.
Atribuição
Toda ação do agente é registrada no audit_log com o run_id. A timeline mostra "Agente GEO adicionou uma nota" naturalmente.
Guardrail
Ação perigosa → cria approval_request e o run pausa até um humano com *:approve liberar. "Zero auto-post" é arquitetural.
AuthContext · o que costura tudo
Um único contexto flui por todo request E todo job de agente.
AuthContext {
actorType: 'user' | 'api_key' | 'service_account'
actorId: uuid
workspaceId: uuid // território ativo → SET LOCAL app.workspace_id
userType: 'internal' | 'external'
role: string
permissions: Set<string>
clientScope: uuid[] | 'all'
runId: uuid // presente em execução de agente
}