Uma lista de controle de acesso é uma lista anexada a um recurso que nomeia quais usuários ou papéis podem acessá-lo e o que cada um pode fazer. O vínculo é a ideia toda: onde sistemas de papéis penduram permissões em pessoas, a ACL as pendura no objeto — cada registro com sua própria lista de convidados, cada entrada (uma entrada de controle de acesso, ACE) um sujeito pareado com seus direitos. É uma das construções de segurança mais antigas da computação, e em backends de aplicação é como “só a Ada e os editores podem tocar neste documento” vira um campo em vez de uma feature.
Principais pontos
| Pergunta | Resposta |
|---|---|
| A estrutura | Objeto → lista de entradas · cada entrada = sujeito + permissões |
| Os três significados | Filtros de tráfego de rede · permissões de arquivos · ACLs por registro na aplicação |
| vs. RBAC | A ACL responde “quem pode tocar neste objeto?” — o RBAC, “o que este papel pode fazer?” |
| A saída de escala | Entradas de papel + ACLs padrão + regras em nível de classe para o caso comum |
| A regra de ferro | Avaliada no servidor, em toda requisição — nunca no cliente |
A lista de convidados de um objeto
Documento "Roadmap Q3" — ACL
┌────────────────────┬─────────┬─────────┐
│ sujeito │ leitura │ escrita │
├────────────────────┼─────────┼─────────┤
│ user usr-8fk2 (Ada)│ sim │ sim │ ← dona
│ user usr-2mq7 (Bob)│ sim │ — │ ← grant individual
│ role editors │ sim │ sim │ ← um papel como uma entrada
│ público (todos) │ — │ — │ ← padrão: fechado
└────────────────────┴─────────┴─────────┘
Como dado, no próprio registro:
{ "title": "Q3 roadmap",
"ACL": { "usr-8fk2": { "read": true, "write": true },
"usr-2mq7": { "read": true },
"role:editors": { "read": true, "write": true } } }
Escrevendo essa lista de convidados em código de aplicação:
// JavaScript / Node.js — Back4app JS SDK
// A per-object ACL: this document's own guest list
const doc = new Parse.Object('Document');
doc.set('title', 'Q3 roadmap');
const acl = new Parse.ACL(currentUser); // owner: read + write
acl.setReadAccess(reviewerId, true); // one user: read only
acl.setRoleWriteAccess('editors', true); // a role as an entry
acl.setPublicReadAccess(false); // everyone else: nothing
doc.setACL(acl);
await doc.save(); // enforced server-side on every future request // Flutter / Dart — Back4app Flutter SDK
// A per-object ACL: this document's own guest list
final doc = ParseObject('Document')..set('title', 'Q3 roadmap');
final acl = ParseACL(owner: currentUser); // owner: read + write
acl.setReadAccess(userId: reviewerId, allowed: true); // one user: read only
acl.setRoleWriteAccess('editors', true); // a role as an entry
acl.setPublicReadAccess(allowed: false); // everyone else: nothing
doc.setACL(acl);
await doc.save(); // enforced server-side on every future request // iOS / Swift — Back4app Swift SDK
// A per-object ACL: this document's own guest list
var doc = Document()
doc.title = "Q3 roadmap"
var acl = ParseACL()
acl.setReadAccess(user: currentUser, value: true) // owner: read…
acl.setWriteAccess(user: currentUser, value: true) // …and write
acl.setReadAccess(objectId: reviewerId, value: true) // one user: read only
acl.setWriteAccess(roleName: "editors", value: true) // a role as an entry
acl.publicRead = false // everyone else: nothing
doc.ACL = acl
try await doc.save() // enforced server-side on every future request // Android / Kotlin — Back4app Android SDK
// A per-object ACL: this document's own guest list
val doc = ParseObject("Document")
doc.put("title", "Q3 roadmap")
val acl = ParseACL(ParseUser.getCurrentUser()) // owner: read + write
acl.setReadAccess(reviewerId, true) // one user: read only
acl.setRoleWriteAccess("editors", true) // a role as an entry
acl.publicReadAccess = false // everyone else: nothing
doc.acl = acl
doc.save() // enforced server-side on every future request Os três significados de “ACL”
A maioria das explicações escolhe um deles em silêncio; o termo nomeia, de fato, três mecanismos:
| Família | Anexada a | Uma entrada parece | Avaliada por |
|---|---|---|---|
| ACLs de rede | Interfaces de roteador/firewall | Regra allow/deny sobre IPs, portas, protocolo — ordenada, vence o primeiro match, deny implícito no fim | Dispositivos de rede |
| ACLs de sistema de arquivos | Arquivos e diretórios | user:ada:rw- — estendendo dono/grupo/outros (POSIX acl(5)) | O sistema operacional |
| ACLs de aplicação | Linhas, documentos, objetos | Usuário/papel → flags de leitura/escrita no registro | Seu backend, por requisição |
Elas compartilham a forma — uma lista de entradas sujeito-permissão guardando um recurso — e diferem em todo o resto. A casa deste artigo é o terceiro significado: as listas de permissão por registro dos backends de aplicação, o menos coberto e, para quem desenvolve produto, o mais usado.
Como uma requisição é avaliada: o modelo de dois gates
As camadas são como sistemas maduros conciliam controle grosso e fino: as permissões em nível de classe declaram a política da categoria inteira (“só usuários autenticados; só moderadores excluem”), e a ACL por objeto decide o registro individual. A requisição precisa passar pelos dois gates — o que significa que uma ACL esquecida não abre o que a regra da classe fechou, e uma regra de classe generosa ainda não expõe um objeto trancado. A mesma lógica de camadas aparece um nível abaixo como segurança em nível de linha, quando o próprio banco aplica o predicado por linha.
ACL vs. RBAC vs. ABAC
| ACL | RBAC | ABAC | |
|---|---|---|---|
| Permissões vinculadas a | Cada objeto | Papéis atribuídos a usuários | Regras sobre atributos |
| Pergunta nativa | Quem pode tocar neste objeto? | O que este papel pode fazer? | Este acesso é permitido neste contexto? |
| Granularidade | A mais fina — por registro, por usuário | Grossa — por função | Arbitrária — por condição |
| Custo de administração | Cresce com objetos × sujeitos | Cresce com papéis | Cresce com a complexidade das regras |
| Auditar “quem vê X?” | Trivial — leia a lista de X | Indireto — expanda os papéis | Difícil — avalie as regras |
| Auditar “o que a Ada vê?” | Difícil — varra todos os objetos | Trivial — leia os papéis dela | Difícil |
| Fraqueza | Proliferação de listas | Explosão de papéis, sem nuance por objeto | Depuração opaca de políticas |
A resposta honesta é composição, não competição: papéis cuidam do acesso que segue a função de trabalho; ACLs cuidam das decisões por objeto que papéis não conseguem expressar (“este rascunho, estes dois revisores”); regras de atributo entram quando o contexto importa (hora, tenant, estado). A dobradiça prática entre os dois primeiros é a ACE de papel — uma linha da ACL cujo sujeito é um role — que mantém o controle em nível de objeto enquanto delega a rotatividade de membros ao sistema de papéis.
O problema de escala — e a escada de mitigação
ACLs por objeto ingênuas crescem como N objetos × M sujeitos: um milhão de documentos listando usuários individuais significa que cada contratação, desligamento e reorganização edita listas espalhadas pelo dataset — o “difícil de gerenciar” que todo livro-texto menciona, tornado concreto. A escada de mitigação, na ordem de subida: entradas de papel (uma ACE cobre uma população que muda; a associação atualiza em um lugar só); ACLs padrão (cada objeto novo já nasce com leitura/escrita do dono e as entradas de papel certas — o análogo, na aplicação, das ACLs default do POSIX em diretórios); regras em nível de classe para o caso comum, reservando listas por objeto para as exceções; e, em escala pesada de relacionamentos, autorização baseada em grafo (ReBAC), que deriva o acesso de relacionamentos em vez de armazenar listas. Sistemas que pulam a escada não abandonam as ACLs — afogam-se nelas.
Enforcement: no servidor ou nada
Uma ACL aplicada no cliente é uma sugestão. Esconder botões, filtrar listas em JavaScript ou confiar que o app só envie IDs permitidos falham do mesmo jeito: o atacante edita a requisição, não a interface — incrementa /documents/41 para /documents/42 e lê o registro de outra pessoa. Essa classe de falha — broken object-level authorization, a primeira da lista de segurança de APIs da OWASP — é exatamente o que as ACLs por objeto existem para fechar, e a orientação da OWASP é direta: verificações de autorização rodam no servidor, por requisição, por objeto; ter acesso a um tipo de objeto nunca implica acesso a todo objeto daquele tipo. A avaliação pertence à camada de dados, onde nenhum caminho do cliente consegue contorná-la.
Casos de uso comuns
- Conteúdo gerado por usuários — cada post, arquivo ou nota pertence a quem criou, compartilhado registro a registro.
- Colaboração em documentos — listas de leitores/editores por documento; a caixa de compartilhar é um editor de ACL vestindo UX.
- Registros multiusuário com exceções — o caso de RH: o titular do registro lê, o gestor escreve, o papel de auditores lê tudo.
- Escopo por tenant e por time — entradas de papel por time em classes compartilhadas, com grants por objeto para exceções entre times.
- Apps privados por padrão — mensagens, saúde, finanças: todo objeto fechado na criação, aberto apenas por entradas explícitas.
Você deveria usar ACLs ou papéis? Matriz de decisão
| Situação | Escolha |
|---|---|
| O acesso segue a função de trabalho por muitos registros | Papéis (RBAC) |
| Cada registro precisa das próprias decisões de compartilhamento | ACLs |
| Os dois padrões ao mesmo tempo (a maioria dos apps reais) | Regras de classe + ACLs com entradas de papel |
| ”Todos leem, o dono escreve” | Flag de leitura pública na ACL + entrada do dono |
| Regras dependem de contexto (hora, estado, tenant) | Condições de atributo acima da ACL |
| Lógica profunda de relacionamentos (organogramas, grupos aninhados) | Sistemas estilo ReBAC |
Limitações e trade-offs
- A proliferação é a trajetória padrão. Sem entradas de papel e defaults, listas por objeto viram confete inauditável; a escada de mitigação não é opcional em escala.
- “O que este usuário pode acessar?” é a consulta cara. ACLs otimizam a auditoria por objeto; o inventário por sujeito exige varreduras ou índices secundários.
- Defaults errados são vazamentos silenciosos. Um objeto criado com leitura pública fica público até alguém notar; ACLs padrão merecem a mesma revisão que código.
- A performance carrega a verificação. Toda leitura filtra por ACL; a avaliação precisa ser indexada e aplicada na camada de dados, não remendada endpoint a endpoint.
- ACLs autorizam; não autenticam. A lista vale o que vale a identidade apresentada a ela — sessions e tokens são a dependência a montante.
ACLs no Back4app
O Back4app é uma plataforma open-source de Backend as a Service (BaaS) que combina banco de dados gerenciado, APIs REST e GraphQL geradas automaticamente, autenticação, armazenamento de arquivos e funções serverless com Cloud Code. Aqui a ACL é um campo de primeira classe: todo objeto carrega uma, as abas de código acima são a API completa — padrões de dono, grants por usuário, entradas de papel, flags públicas — e o enforcement acontece no Back4app em toda requisição REST, GraphQL e Live Query, então assinaturas em tempo real respeitam as mesmas listas de convidados que as consultas. O modelo de dois gates chega intacto: as permissões em nível de classe definem a política da categoria no dashboard, as ACLs por objeto a refinam registro a registro, e uma configuração de ACL padrão faz objetos novos nascerem privados do dono. A escada de escala já vem montada — roles são objetos que você gerencia como qualquer outro dado — deixando as decisões de design, e não a maquinaria de enforcement, como a sua parte do trabalho.
Perguntas frequentes
O que é uma ACL em termos simples?
Uma lista de convidados anexada a cada recurso: ela nomeia quem pode acessar aquele objeto específico e o que cada um pode fazer — Ada lê e escreve, Bob só lê, todos os demais ficam de fora. A lista viaja com o objeto, então cada objeto pode ter regras diferentes.
O que é uma entrada de controle de acesso (ACE)?
Uma linha da lista: um sujeito (um usuário, um papel ou "todos") pareado com as permissões concedidas ou negadas a ele. Uma ACL é simplesmente uma coleção ordenada de ACEs anexada a um único recurso.
Quais são os tipos de ACL?
Três famílias compartilham o nome: ACLs de rede (filtros de tráfego ordenados em roteadores e firewalls), ACLs de sistema de arquivos (listas de permissão por arquivo que estendem dono/grupo/outros) e ACLs de aplicação ou de banco de dados (listas de permissão por registro na camada de dados). No desenvolvimento backend, a terceira é normalmente a que se quer dizer.
Qual a diferença entre ACL e RBAC?
A direção do vínculo. A ACL pendura permissões em cada recurso, por sujeito — ideal quando objetos individuais exigem decisões individuais. O RBAC pendura permissões em papéis e atribui usuários a eles — ideal quando o acesso segue a função de trabalho por muitos recursos. Sistemas reais combinam os dois: roles para o grosso, ACLs para as exceções por objeto.
Como ACLs funcionam em um banco de dados?
Cada linha ou documento carrega (ou referencia) sua própria lista de permissões — tipicamente um campo ACL que mapeia IDs de usuário e nomes de papéis para flags de leitura/escrita. O banco ou o backend avalia essa lista em toda operação, o que combina naturalmente com segurança em nível de linha e camadas de permissão por tabela.
Qual a diferença entre uma ACL e uma capability list?
Duas visões da mesma matriz de acesso: a ACL é uma coluna — armazenada com o objeto, listando seus sujeitos — e a capability list é uma linha — armazenada com o sujeito, listando seus objetos. ACLs tornam "quem pode tocar neste objeto?" auditável na hora; capabilities facilitam "o que este usuário pode tocar?", mas dificultam a revogação.
Por que ACLs não escalam sozinhas?
Porque a contabilidade cresce como objetos × sujeitos: cada contratação, desligamento e troca de time significa editar listas espalhadas por milhões de objetos. As mitigações são entradas de papel (uma ACE cobre um grupo que muda), ACLs padrão aplicadas na criação e regras em nível de classe cuidando do caso comum, deixando as listas por objeto só para as exceções.
Qual a diferença entre permissões por objeto e por classe?
Granularidade. Permissões por classe (ou por tabela) controlam uma categoria inteira — "só usuários logados podem consultar Documents". ACLs por objeto controlam um registro — "só Ada pode ler este documento". Sistemas em camadas verificam primeiro o gate da classe, depois a ACL do objeto; a requisição precisa passar pelos dois.