Kong Gateway é um API gateway de código aberto que garante que somente as solicitações certas sejam lidas, enquanto gerencia segurança, limitação de taxa, log e muito mais. OPA (Open Policy Agent) é uma engine de política de código aberto que assume o controle das decisões de segurança e acesso de sua aplicação. Pense nisto como a mente que desacopla a aplicação de políticas, portanto, seus serviços não precisam se preocupar com a aplicação de regras. Em vez disso, a OPA faz o raciocínio com sua linguagem Rego, avaliando políticas em APIs, microserviços, ou até em Kubernetes. É flexível, seguro e faz a atualização de políticas fácil. A OPA funciona avaliando três coisas chave: entrada (dados em tempo real, como solicitações), dados (informações externas, como papéis de usuário) e política (lógica em Rego que decide se deve “permitir” ou “negar”). Juntos, esses componentes permitem que a OPA mantenha seu jogo de segurança forte enquanto mantém as coisas simples e consistentes.
O que estamos procurando alcançar ou resolver?
Este texto muitas vezes tem dados no OPA como um velho amigo estável — estático ou mudando lentamente. É usado ao lado dos dados de entrada mudando constantemente para tomar decisões inteligentes. Mas, imagine um sistema com uma extensa rede de microserviços, montes de usuários e um banco de dados massivo como o PostgreSQL. Este sistema lida com um grande volume de transações a cada segundo e precisa manter sua velocidade e throughput sem dificuldades.
Controle de acesso refinado em tal sistema é complicado, mas com o OPA, você pode transferir a carga pesada de seus microserviços e manipulá-la no nível da gateway. Ao se unir ao Kong API Gateway e ao OPA, você obtém um throughput de primeira classe e um controle de acesso preciso.
Como você mantém dados de usuário precisos sem abrandar as coisas? Fazer acessos constantes ao banco de dados PostgreSQL para buscar milhões de registros é caro e lento. Atingir precisão e velocidade geralmente requer compromissos entre os dois. Vamos buscar um equilíbrio prático desenvolvendo um plugin personalizado (no nível da gateway) que carrega frequentemente e armazena em cache localmente dados para o OPA usar na avaliação de suas políticas.
Demanda
Ao criar a demonstração, configurei dados de exemplo no PostgreSQL, contendo informações de usuário como nome, e-mail e função. Quando um usuário tenta acessar um serviço através de uma URL específica, a OPA avalia se a solicitação é permitida. A política Rego verifica a URL da solicitação (recurso), o método e a função do usuário, e então retorna verdadeiro ou falso com base nas regras. Se for verdadeiro, a solicitação é permitida; se for falso, o acesso é negado. Até agora, é uma configuração direta. Vamos mergulhar no plugin personalizado. Para uma compreensão mais clara de sua implementação, por favor, refira-se ao diagrama abaixo.
Quando uma solicitação chega pelo Proxy Kong, o plugin personalizado do Kong é acionado. O plugin buscaria os dados necessários e os passaria para a OPA, juntamente com a entrada/pesquisa. Essa busca de dados tem duas partes: uma seria procurar no Redis os valores necessários, e se encontrados, passá-los para a OPA; caso contrário, faria uma consulta adicional no Postgres, buscaria os dados e os armazenaria no Redis antes de passá-los para a OPA. Podemos rever isto quando executarmos os comandos na próxima seção e observarmos os registros. A OPA toma uma decisão (com base na política, entrada e dados) e, se for permitido, o Kong continuará enviando a solicitação para a API. Usando esta abordagem, o número de consultas ao Postgres é significantemente reduzido, ainda que os dados disponíveis para a OPA sejam razoavelmente precisos, preservando a baixa latência.
Para começar a construir um plugin personalizado, precisamos de um arquivo handler.lua
onde a lógica central do plugin é implementada e um arquivo schema.lua
que, conforme o nome indica, define o esquema de configuração do plugin. Se você está começando a aprender a escrever plugins personalizados para o Kong, consulte este link para mais informações. A documentação também explica como empacotar e instalar o plugin. Vamos prosseguir e entender a lógica the plugin.
O primeiro passo do demo seria instalar o OPA, o Kong, o Postgres e Redis no seu ambiente local ou em qualquer ambiente de nuvem. Clone em este repositório.
Revise o arquivo docker-compose.yaml que tem as configurações definidas para deployar todos os quatro serviços acima. Observe as variáveis de ambiente do Kong para ver como o plugin personalizado é carregado.
Execute os comandos abaixo para deployar os serviços:
docker-compose build
docker-compose up
Uma vez que verifique que os containers estão rodando, o Kong manager e o OPA estão disponíveis em respectivos endpoints https://localhost:8002 e https://localhost:8181, como mostrado abaixo:
Crie um serviço de teste, uma rota e adicione o nosso plugin personalizado do Kong a esta rota usando o comando abaixo:
curl -X POST http://localhost:8001/config -F config=@config.yaml
A política OPA definida no arquivo authopa.rego é publicada e atualizada no serviço OPA usando o comando abaixo:
curl -X PUT http://localhost:8181/v1/policies/mypolicyId -H "Content-Type: application/json" --data-binary @authopa.rego
Este exemplo de política concede acesso a solicitações de usuário apenas se o usuário estiver acessando o caminho /demo com o método GET
e tiver o papel de "Moderador"
. Regras adicionais podem ser adicionadas conforme necessário para personalizar o controle de acesso com base em diferentes critérios.
opa_policy = [
{
"path": "/demo",
"method": "GET",
"allowed_roles": ["Moderator"]
}
]
A configuração está agora pronta, mas antes de testar, precisamos de algum dado de teste para adicionar no Postgres. Eu adicionei algum dado de exemplo (nome, e-mail e papel) para alguns funcionários, conforme mostrado abaixo (refere-se ao PostgresReadme).
Aqui está um exemplo de solicitação bem-sucedida e fracassada:
Agora, para testar a funcionalidade central deste plugin personalizado, vamos fazer duas solicitações consecutivas e verificar os logs para ver como a recuperação de dados está acontecendo.
Aqui estão os logs:
2024/09/13 14:05:05 [error] 2535#0: *10309 [kong] redis.lua:19 [authopa] No data found in Redis for key: [email protected], client: 192.168.96.1, server: kong, request: "GET /demo HTTP/1.1", host: "localhost:8000", request_id: "ebbb8b5b57ff4601ff194907e35a3002"
2024/09/13 14:05:05 [info] 2535#0: *10309 [kong] handler.lua:25 [authopa] Fetching roles from PostgreSQL for email: [email protected], client: 192.168.96.1, server: kong, request: "GET /demo HTTP/1.1", host: "localhost:8000", request_id: "ebbb8b5b57ff4601ff194907e35a3002"
2024/09/13 14:05:05 [info] 2535#0: *10309 [kong] postgres.lua:43 [authopa] Fetched roles: Moderator, client: 192.168.96.1, server: kong, request: "GET /demo HTTP/1.1", host: "localhost:8000", request_id: "ebbb8b5b57ff4601ff194907e35a3002"
2024/09/13 14:05:05 [info] 2535#0: *10309 [kong] handler.lua:29 [authopa] Caching user roles in Redis, client: 192.168.96.1, server: kong, request: "GET /demo HTTP/1.1", host: "localhost:8000", request_id: "ebbb8b5b57ff4601ff194907e35a3002"
2024/09/13 14:05:05 [info] 2535#0: *10309 [kong] redis.lua:46 [authopa] Data successfully cached in Redis, client: 192.168.96.1, server: kong, request: "GET /demo HTTP/1.1", host: "localhost:8000", request_id: "ebbb8b5b57ff4601ff194907e35a3002"
2024/09/13 14:05:05 [info] 2535#0: *10309 [kong] opa.lua:37 [authopa] Is Allowed by OPA: true, client: 192.168.96.1, server: kong, request: "GET /demo HTTP/1.1", host: "localhost:8000", request_id: "ebbb8b5b57ff4601ff194907e35a3002"
2024/09/13 14:05:05 [info] 2535#0: *10309 client 192.168.96.1 closed keepalive connection
------------------------------------------------------------------------------------------------------------------------
2024/09/13 14:05:07 [info] 2535#0: *10320 [kong] redis.lua:23 [authopa] Redis result: {"roles":["Moderator"],"email":"[email protected]"}, client: 192.168.96.1, server: kong, request: "GET /demo HTTP/1.1", host: "localhost:8000", request_id: "75bf7a4dbe686d0f95e14621b89aba12"
2024/09/13 14:05:07 [info] 2535#0: *10320 [kong] opa.lua:37 [authopa] Is Allowed by OPA: true, client: 192.168.96.1, server: kong, request: "GET /demo HTTP/1.1", host: "localhost:8000", request_id: "75bf7a4dbe686d0f95e14621b89aba12"
Os logs mostram que para a primeira solicitação, quando não há dados em Redis, os dados são buscados no Postgres e armazenados em cache em Redis antes de enviá-los para o OPA para avaliação. Na solicitação subsequente, já que os dados estão disponíveis em Redis, a resposta será muito rápida.
Conclusão
Em resumo, combinando o Kong Gateway com o OPA e implementando o plugin personalizado com cache do Redis, balanceamos eficazmente a precisão e a velocidade para o controle de acesso em ambientes de alto throughput. O plugin minimize o número de consultas caras à Postgres pela cache de funções de usuário no Redis após a consulta inicial. Nas solicitações subsequentes, os dados são recuperados do Redis, reduzindo significativamente a latência enquanto mantém informações de usuário precisas e atualizadas para avaliações de políticas OPA. Esta abordagem garante que o controle de acesso granular seja tratado eficientemente no nível do gateway sem sacrificar desempenho ou segurança, tornando-se uma solução ideal para dimensionar microserviços enquanto impõe políticas de acesso precisas.
Source:
https://dzone.com/articles/enhanced-api-security-fine-grained-access-control