Demesne

O mecanismo de autorização sobre o qual o Fóir roda. As regras de acesso são escritas uma só vez, em um único arquivo de spec, e o Demesne as compila em row-level security do Postgres, de modo que o banco as aplica a toda consulta. Nós o construímos para o Fóir e o publicamos sob a licença Apache 2.0.

O que ele faz

Uma spec do Demesne descreve quatro coisas: o formato do seu tenancy, os tipos de usuário e de credencial que agem, as tabelas sobre as quais eles agem e as relações que os conectam, como propriedade, papéis, compartilhamento e participação em grupos.

A partir desse arquivo, o compilador gera as políticas de row-level security e as funções de banco de dados que essas políticas chamam. Também gera um mapa de permissões para Go e TypeScript, para as perguntas que não são sobre linhas ("este usuário pode publicar?"), e os claims que uma sessão precisa carregar. Mude a spec e gere de novo, e o banco e o código da aplicação se movem juntos.

Por que as regras vivem no banco de dados

A autorização costuma ficar no código da aplicação: um serviço que você chama, ou verificações espalhadas pelos handlers de requisição. Dos dois jeitos, ela protege apenas os caminhos que se lembram de perguntar. Um job em segundo plano, um novo endpoint ou uma consulta digitada em um console de banco de dados passa por fora dela.

O Demesne coloca a decisão nos dados. A mesma política filtra toda consulta, seja qual for o código que a enviou, de modo que um caminho que esquece de verificar recebe de volta apenas as linhas que o chamador tinha permissão para ver.

Por que escrevemos um compilador

Row-level security é o lugar certo para uma regra e uma coisa incômoda de escrever à mão. Um produto multi-tenant precisa de propriedade, papéis, grupos aninhados e compartilhamento, repetidos em cada tabela, e esses padrões são fáceis de errar de maneiras sutis.

Os mecanismos que compartilham o modelo do Demesne, o Zanzibar do Google e os projetos open source que o seguem, rodam como um serviço separado. Sua aplicação precisa chamar esse serviço a cada decisão e manter a cópia dele das relações em sincronia com seus dados. Queríamos o modelo sem o serviço, então as regras do Demesne leem suas tabelas existentes na mesma transação da consulta.

Como sua saída é verificada

O build do Demesne compara cada arquivo gerado, byte a byte, com uma cópia commitada. Cada verificação de permissão do lado da aplicação carrega literalmente a condição da política correspondente, de modo que o código não pode se afastar do banco sem fazer o build falhar. Executada contra um Postgres de verdade, a suíte de testes instala as funções geradas e confirma que o SQL concorda com as versões em Go e em TypeScript, caso a caso.

Para um banco de dados que já está implantado, demesne diff informa qualquer diferença entre a spec e as políticas em vigor.

Por que ele é open source

O componente que decide quem pode ler seus dados é o que você deveria poder inspecionar. Qualquer plataforma pode dizer que seus tenants são isolados. Com o Demesne, você pode ler o compilador que escreve nossas políticas, os testes que ele precisa passar e o SQL que ele produz, e pode executar tudo isso você mesmo.

Nada no Demesne é específico do Fóir. Ele funciona com qualquer banco Postgres e lê a sessão que o seu próprio provedor de login emite, e o guia do repositório explica como adotá-lo em um schema existente. Uma equipe sem nenhum interesse na nossa plataforma pode usá-lo, o que é a melhor verificação que conhecemos de que o modelo se sustenta.

O que isso significa no Fóir

O modelo de acesso do Fóir é uma única spec do Demesne, que no momento em que escrevemos governa cerca de cem tabelas. Um teste lista todas as tabelas do nosso schema e falha em qualquer uma que tenha sido adicionada sem uma decisão registrada sobre como ela é protegida.

As regras que você define para o seu próprio projeto, como quem é dono de um registro e quais papéis podem ler um modelo, são dados que essas políticas leem, então também passam a valer dentro do banco de dados. Aplicado no banco de dados descreve como as políticas são geradas, forçadas e testadas.

Ele vai com você

Uma exportação Postgres do seu projeto inclui políticas de row-level security que reproduzem quais linhas cada um dos seus usuários podia ler, prontas para você aplicar ao banco de dados que agora é seu. Se você quiser o modelo inteiro na sua própria infraestrutura, o mecanismo está disponível para uso sob uma licença que permite isso.

Onde ele é a ferramenta errada

O Demesne é só para Postgres. É uma biblioteca e uma ferramenta de linha de comando, sem nenhum serviço hospedado para chamar. Toda regra precisa ser expressável como uma condição SQL, e as perguntas que andam no sentido contrário ("quem pode ver este registro?") são respondidas de forma conservadora. O repositório traz uma comparação com Zanzibar, Ory Keto, OpenFGA, Cerbos e Oso que diz onde cada um deles é a melhor escolha.

Leia por conta própria

A linguagem da spec, o SQL gerado e a suíte de testes estão todos no repositório.