Exemplo 1: ABAC básico com OPA e Rego - AWS Orientação prescritiva

As traduções são geradas por tradução automática. Em caso de conflito entre o conteúdo da tradução e da versão original em inglês, a versão em inglês prevalecerá.

Exemplo 1: ABAC básico com OPA e Rego

Esta seção descreve um cenário em que o OPA é usado para tomar decisões de acesso sobre quais usuários têm permissão para acessar informações em um microsserviço fictício de folha de pagamento. Trechos de código do Rego são fornecidos para demonstrar como você pode usar o Rego para renderizar decisões de controle de acesso. Esses exemplos não são exaustivos nem uma exploração completa das capacidades do Rego e do OPA. Para uma visão geral mais completa do Rego, recomendamos que você consulte a documentação do Rego no site da OPA.

ABAC básico com OPA e Rego

Exemplo de regras básicas de OPA

No diagrama anterior, uma das regras de controle de acesso aplicadas pela OPA para o microsserviço de folha de pagamento é:

Os funcionários podem ler seu próprio salário.

Se Bob tentar acessar o microsserviço da folha de pagamento para ver seu próprio salário, o microsserviço da folha de pagamento poderá redirecionar a chamada da API para a API da OPA para tomar uma RESTful decisão de acesso. O serviço de folha de pagamento consulta a OPA para obter uma decisão com a seguinte entrada JSON:

{ "user": "bob", "method": "GET", "path": ["getSalary", "bob"] }

O OPA seleciona uma política ou políticas com base na consulta. Nesse caso, a política a seguir, escrita em Rego, avalia a entrada JSON.

default allow = false allow = true { input.method == "GET" input.path = ["getSalary", user] input.user == user }

Essa política nega acesso por padrão. Em seguida, ele avalia a entrada na consulta vinculando-a à variável input global. O operador ponto é usado com essa variável para acessar os valores da variável. A regra Rego allow retorna verdadeira se as expressões na regra também forem verdadeiras. A regra Rego verifica se a method entrada é igual a GET. Em seguida, ele verifica se o primeiro elemento na lista path está getSalary antes de atribuir o segundo elemento na lista à variável. user Por fim, ele verifica se o caminho que está sendo /getSalary/bob acessado é verificando se a user solicitação,input.user, corresponde à user variável. A regra allow aplica a lógica if-then para retornar um valor booleano, conforme mostrado na saída:

{ "allow": true }

Regra parcial usando dados externos

Para demonstrar recursos adicionais do OPA, você pode adicionar requisitos à regra de acesso que está aplicando. Vamos supor que você queira impor esse requisito de controle de acesso no contexto da ilustração anterior: 

Os funcionários podem ler o salário de qualquer pessoa que se reporte a eles.

Neste exemplo, o OPA tem acesso a dados externos que podem ser importados para ajudar a tomar uma decisão de acesso:

"managers": { "bob": ["dave", "john"], "carol": ["alice"] }

Você pode gerar uma resposta JSON arbitrária criando uma regra parcial no OPA, que retorna um conjunto de valores em vez de uma resposta fixa. Este é um exemplo de uma regra parcial:

direct_report[user_ids] { user_ids = data.managers[input.user][_] }

Essa regra retorna um conjunto de todos os usuários que se reportam ao valor deinput.user, que, nesse caso, ébob. A [_] construção na regra é usada para iterar sobre os valores do conjunto. Esta é a saída da regra:

{ "direct_report": [ "dave", "john" ] }

A recuperação dessas informações pode ajudar a determinar se um usuário é subordinado direto de um gerente. Para alguns aplicativos, é preferível retornar JSON dinâmico do que retornar uma resposta booleana simples.

Juntando tudo isso

O último requisito de acesso é mais complexo do que os dois primeiros porque combina as condições especificadas nos dois requisitos:

Os funcionários podem ler seu próprio salário e o salário de qualquer pessoa que se reporte a eles.

Para cumprir esse requisito, você pode usar esta política da Rego:

default allow = false allow = true { input.method == "GET" input.path = ["getSalary", user] input.user == user } allow = true { input.method == "GET" input.path = ["getSalary", user] managers := data.managers[input.user][_] contains(managers, user) }

A primeira regra da política permite o acesso de qualquer usuário que tente ver suas próprias informações salariais, conforme discutido anteriormente. Ter duas regras com o mesmo nome,allow, funciona como um operador lógico ou em Rego. A segunda regra recupera a lista de todos os subordinados diretos associados input.user (dos dados no diagrama anterior) e atribui essa lista à managers variável. Por fim, a regra verifica se o usuário que está tentando ver seu salário é um subordinado direto, input.user verificando se seu nome está contido na managers variável.

Os exemplos nesta seção são muito básicos e não fornecem uma exploração completa ou completa das capacidades do Rego e do OPA. Para obter mais informações, revise a documentação do OPA, consulte o arquivo GitHub README do OPA e experimente no playground do Rego.