Scopes
Scopes são strings hierárquicas no formato <domínio>.<ação>. Cada App declara em seu cadastro o conjunto máximo de scopes que pode requisitar; cada installation subscreve um subconjunto desses scopes — o admin do tenant pode reduzir o que concede no momento do consentimento.
Princípio do menor privilégio
Peça apenas os scopes que sua App realmente precisa. Submissões que pedem
*.writequando só leem dados são rejeitadas na revisão de publicação. Apps publicadas que escalarem scopes além do necessário podem ser despublicadas sem aviso.
Justificativa por scope é exigida na revisão manual (MVP). Em texto livre, em português, explicando por que o scope é necessário para a função da App.
Catálogo de scopes
| Scope | Permite | Notas |
|---|---|---|
orders.read | Ler pedidos do tenant via GET /public/v1/orders. Receber order.created e order.statusChanged via webhook. | Inclui itens, totais, status, e identidade do cliente (nome + telefone) — trate como PII. |
orders.write | Criar e atualizar pedidos (endpoints POST/PATCH em /public/v1/orders/*, em roadmap). | Hoje somente leitura está exposta na public-api — orders.write está reservado para implementação em release futura. Apps que pedirem hoje terão o scope reservado mas inativo. |
menu.read | Ler categorias e itens via GET /public/v1/menu/items. Receber menu.updated. | Inclui preços, descrições, modificadores, fotos. |
menu.write | Editar cardápio (criar/atualizar/remover itens e categorias). | Endpoints em roadmap; hoje reservado e inativo na public-api. |
inventory.read | Ler estoque (GET /public/v1/inventory/*, em roadmap). Receber inventory.adjusted. | Por filial — granularidade Branch. |
inventory.write | Movimentar estoque (ajustes, transferências, recebimento de compra). | Endpoints em roadmap. |
reservations.read | Ler reservas via GET /public/v1/reservations. | Hoje ativo na public-api. |
reservations.write | Criar reservas via POST /public/v1/reservations. | Hoje ativo na public-api. Validação de DTO em hardening (gap S2 — veja public-api-v1.md). |
fiscal.read | Ler NF-e, NFS-e e exports SPED. Receber fiscal.export.monthly. | Endpoints GET /public/v1/fiscal/* em roadmap. Necessário para bridges contábeis (Domínio, Contmatic). |
customers.read | Ler dados de clientes (CPF/CNPJ, email, telefone, histórico de pedidos). | PII sensível — submissão exige justificativa forte e revisão estendida. LGPD: sua App vira controlador conjunto desses dados. |
webhooks.subscribe | Wildcard — recebe todos os eventos de domínio que o tenant tiver instalado, independentemente do read scope correspondente. | Use apenas quando sua App precisa observar eventos cruzados. Não substitui scopes de read para chamadas REST. |
Endpoints marcados "em roadmap" são contratos planejados — o scope é declarável hoje (o serviço aceita) mas a rota correspondente em
/public/v1/*ainda não foi exposta. Vejapublic-api-v1.mdpara a lista atual de endpoints ativos.
Como o tenant pode reduzir scopes
Durante o POST /t/:slug/admin/marketplace/apps/:appSlug/install, o admin envia em body.scopes o subconjunto que aceita conceder. O backend valida requestedScopes ⊆ App.scopes e rejeita com 400 se houver scope não declarado pela App.
Implicação para você publisher: sua App deve degradar bem se receber menos scopes do que pediu. Exemplo concreto:
// App pediu: ['orders.read', 'menu.read', 'webhooks.subscribe']
// Tenant aprovou: ['orders.read', 'webhooks.subscribe']
// → desabilite a feature de sincronização de cardápio gracefully
// no seu UI; não derrube a App inteira.A forma mais segura é fazer um cache local dos installation.scopes retornados no install e gate cada feature por scope:
function canSyncMenu(installation): boolean {
return installation.scopes.includes('menu.read');
}UI de consentimento
No frontend de admin do tenant, scopes aparecem em português claro, não em strings técnicas. Mapeamento (i18n):
| Scope | Label exibida ao tenant |
|---|---|
orders.read | "Ler seus pedidos" |
orders.write | "Criar e atualizar pedidos" |
menu.read | "Ler seu cardápio" |
menu.write | "Editar seu cardápio" |
inventory.read | "Ler seu estoque" |
inventory.write | "Movimentar seu estoque" |
reservations.read | "Ler suas reservas" |
reservations.write | "Criar reservas" |
fiscal.read | "Ler suas notas fiscais e exports" |
customers.read | "Ler dados dos seus clientes (CPF, email, telefone)" |
webhooks.subscribe | "Receber notificações em tempo real de tudo que acontece" |
A descrição que você fornece no cadastro da App aparece embaixo da lista — use para contextualizar por que cada scope é necessário.
Mudanças de scope pós-install
Hoje não há fluxo de "re-consent" para escalar scopes em uma installation já ativa. Para adicionar scope novo a uma App já instalada, o tenant precisa revogar e reinstalar. Apps devem comunicar isso claramente ao seu user-base quando um upgrade exigir novos scopes.
Roadmap:
PATCH /t/:slug/admin/marketplace/installations/:idcom fluxo de reconsentimento — sem ETA hoje.
Auditoria
Toda chamada autenticada à public-api é logada com installationId, tenantId, event/endpoint, timestamp na collection marketplace_app_api_calls (em hardening — gap S5 em public-api-v1.md). Em caso de incidente, o tenant pode pedir o relatório completo dos últimos 90 dias via ticket de suporte.
Para o publisher: mantenha seu próprio log de qual installation fez o quê — facilita response a pedido de DPA do tenant sob LGPD.