Pular para o conteúdo

Conceitos

Autorização baseada em relações (Zanzibar)

Intuição

Imagine que, em vez de manter uma lista de quem pode abrir cada documento, você anota só fatos simples: "Ana é membra desta equipe", "esta equipe tem acesso a esta pasta", "este documento está dentro desta pasta". Para saber se Ana pode abrir o documento, basta seguir a cadeia de fatos até encontrar um caminho que ligue Ana ao documento. Assim, quando um fato muda (Ana sai da equipe), tudo o que dependia dele muda junto, sem precisar reescrever lista nenhuma.

Como funciona

No Zanzibar, as permissões são guardadas como tuplas de relação no formato objeto#relação@usuário; grupos não são uma entidade especial, e sim objetos cujas relações representam participação. O lado do usuário da tupla pode ser um userset, isto é, o conjunto de quem tem certa relação com outro objeto, o que permite representar grupos aninhados. Cada namespace (tipo de objeto) tem uma configuração com regras de reescrita de userset, que derivam uma relação de outras sem gravar tuplas redundantes: ela pode vir direto das tuplas, ser herdada de outra relação do mesmo objeto (quem é editor também conta como leitor) ou ser obtida seguindo um objeto pai (herdar os leitores da pasta que contém o documento). Assim, a política complexa fica na configuração e o armazenamento guarda só fatos simples; a API inclui Read, Write, Check, Expand e Watch, e o Check responde se um usuário tem determinada relação com um objeto. As tuplas ficam no Spanner, cujos timestamps de commit refletem a ordem causal das escritas; para evitar o new enemy problem (por exemplo, ainda enxergar um documento sensível depois de ser removido da ACL da pasta), o cliente recebe um zookie ao autorizar uma alteração de conteúdo, guarda-o junto com aquela versão e o envia nas checagens seguintes, que então são avaliadas num snapshot pelo menos tão recente quanto o zookie. Sem zookie, o sistema escolhe um snapshot recente que favorece a baixa latência, de modo que o custo de frescor só é pago onde há necessidade de garantia causal. Para grupos muito grandes e profundamente aninhados, onde percorrer a hierarquia seria lento, o sistema de indexação Leopard representa a participação em grupos como conjuntos e acelera as consultas de alcançabilidade; contra pontos quentes, os servidores usam cache distribuído com hashing consistente e uma tabela de locks para que várias requisições não calculem o mesmo resultado ao mesmo tempo.

Na prática

O paper se tornou a referência para o controle de acesso baseado em relacionamentos (ReBAC), em que a decisão depende das relações entre entidades e não apenas de papéis fixos; faz sentido considerá-lo em produtos com compartilhamento, herança por pastas e grupos aninhados, onde a permissão é na prática um grafo de relações. Segundo o paper, o Zanzibar atende centenas de serviços do Google e, em mais de três anos de produção, manteve latência no percentil 95 abaixo de 10 ms e disponibilidade acima de 99,999%. A lição de design é separar um modelo mínimo de tuplas, uma configuração declarativa que deriva permissões e um serviço central que trata consistência causal, cache e latência de cauda como requisitos desde o início, entregando o zookie ao cliente em vez de forçar leituras sempre atuais.

Use em um desenho

Pratique na escola de System Design os casos que dependem deste conceito.