Autenticação e Autorização são grandes partes do puzzle de segurança que precisa ser resolvido por arquitetos de nuvem e engenheiros DevOps. Neste blog, vamos olhar especificamente em como alcançar autorização/controle de acesso; isto é, quais ações a entidade autenticada pode realizar na malha de serviços Istio. Ela ajuda a segurar a infraestrutura impedindo ações com intenção malévola.
A autorização em uma malha de serviços pode ser definida usando políticas OPA. OPA é um mecanismo que ajuda os funcionários DevOps a definir e aplicar políticas de autorização para cargas de trabalho do Kubernetes. Neste texto, vamos ver:
- O que é a OPA
- Por que você deve integrar a OPA com a malha de serviços Istio
- Como o Istio e a OPA autorizam solicitações
- As etapas exatas que você pode seguir para integrar a OPA com o Istio
O que é a OPA?
A OPA (abreviação de “Open Policy Agent”) é um motor de aplicação de políticas de código aberto e de propósito geral que permite que os funcionários DevOps defina as políticas como código usando uma linguagem declarativa de alto nível chamada Rego. A OPA ajuda a definir e aplicar de forma centralizada as políticas em toda a pilha, aliviando os desenvolvedores de escrever políticas de autorização no código do aplicativo. Aqui é como a OPA funciona (referir-se ao Figure 1):
- O aplicativo/serviço recebe uma solicitação.
- O serviço envia uma solicitação de autorização em JSON para a OPA.
- A OPA verifica a solicitação contra as políticas de autorização definidas.
- A OPA toma a decisão e retorna a resposta de autorização (PERMITIR/NEGAR) para o serviço no formato JSON.
Figura 1: Fluxo de solicitação de autorização com OPA
Observe que não é preciso que seja uma aplicação escrita por um desenvolvedor que está enviando a solicitação de autorização: pode ser o Argo CD, o recurso da API do Gateway do Kubernetes, o Terraform, o Prometheus ou qualquer outra coisa, já que o OPA é de propósito geral. (Mencionei e desenhei uma aplicação em um cluster Kubernetes aqui por questões de conveniência e melhor compreensão.)
Por que integrar o OPA com o Istio?
O Istio tem um mecanismo de autorização robusto. No entanto, ter um motor de aplicação de políticas dedicado como o OPA junto à grade de serviços do Istio tem seus próprios benefícios:
- Sistema de gerenciamento centralizado para definir e aplicar políticas: O OPA torna mais fácil para os DevOps gerenciar centralmente as políticas de autorização para toda a stack. Isso inclui cargas de trabalho em grade, stack não-mesh e também verificações de autorização (uma política que impede o deploy no final de semana, por exemplo).
- Mais flexibilidade e granularidade na definição de políticas: Se você olhar para a tabela abaixo (Figura 2), é claro que a autorização do Istio pode fazer muito e corresponde à solicitação com base em uma variedade de campos de diferentes fontes de dados. No entanto, a CRD de AuthorizationPolicy do Istio pode ter limitações em configurar o corpo da solicitação HTTP ou qualquer dado contextual nos campos, para os quais o OPA pode ser usado. Ao contrário do Istio, o OPA pode usar qualquer dado para a avaliação da política.
- Configuração simplificada de AuthZ: Pode ser cansativo para os DevOps configurar regras de autorização complexas no Istio. O OPA é configurado usando o Rego, que é semelhante a um linguagem de programação. É relativamente fácil definir regras de política básicas à complexas usando o Rego.
Figura 2: Comparação tabular entre autorização do Istio e do OPA (fonte)
Como o Istio e o OPA autorizam solicitações
Os DevOps podem implantar o OPA como um serviço separado ou como um container sidecar junto do proxy Envoy e do container da aplicação num pod. A abordagem de container sidecar é melhor para reduzir o atraso.
Os containers sidecar do OPA precisam ser injetados no pod da aplicação, tal como os containers sidecar do proxy Envoy do Istio. Podemos configurar os containers OPA injetados para montar ConfigMaps que contêm as regras de autorização; todos os containers sidecar OPA no namespace então montarão a mesma configuração e regras AuthZ definidas no ConfigMap.
Uma vez que o container sidecar do OPA for injetado, o proxy Envoy enviará solicitações de autorização para o OPA para tomar decisões de autorização quando o serviço receber uma solicitação:
Figura 3: Fluxo de trabalho de autorização Istio-OPA
Suppose que as pessoas da equipe DevOps não querem que todos os containers OPA injetados no mesmo namespace sejam baseados na mesma configuração e que querem impor regras diferentes. Nesse caso, eles terão que fazer qualquer das seguintes ações:
- Remover o hard coding que permite à política de injeção atual usar um ConfigMap particular
- Configurar o webhook mutante e desabilitar a injeção sidecar no nível do pod
- Servir pacotes de política de um servidor HTTP remoto
- Implantação da aplicação e dos sidecars em um namespace diferente com um ConfigMap diferente
Passos Para Integrar O Opa Com O Istio: Demonstração
A ideia aqui é tornar o OPA o autorizador externo em vez dos sidecars do proxy Envoy — para tomar decisões de controle de acesso.
Eu usarei a clássica aplicação Bookinfo da documentação do Istio para a demonstração. Eu configurarei o OPA com o Istio para o controle de acesso e verificarei se é imposto disparando pedidos para bookinfo/productpage:
Figura 4: Diagrama de tutorial de integração Istio-OPA
Note que /productpage é a UI, que faz chamadas internas a outros serviços, como os serviços de avaliações e revisões (diagram). Eu injetarei o OPA em cada pod no namespace bookinfo
; todos os containers OPA montam o mesmo ConfigMap e têm as mesmas políticas de autorização por causa disso. O comportamento padrão da aplicação Bookinfo
não encaminha qualquer autenticação HTTP, portanto as chamadas internas falharão na autenticação e, portanto, na autorização.
Nós seguiremos os passos dados na ordem:
- Configurar injeção de sidecar OPA
- Permitir comunicação entre o proxy do Istio e o OPA
- Deploy OPA configuration
- Aplicar configuração do Istio
- Deploy the application and test the Istio-OPA authorization setup
O pré-requisito para a demonstração é ter o Istio v1.19+ instalado em seu cluster. Aqui estou usando o Istio v1.21.0.
O OPA fornece um quickstart.yaml para instalação fácil. Eu dividi o yaml em três para melhor entendimento: IMESH GitHub repo.
Step 1: Configure OPA Sidecar Injection
Aplicar o opa_controller.yaml:
kubectl apply -f opa_controller.yaml
O opa_controller.yaml
deploys everything — TLS certificates, ConfigMap containing injection policy, admission controller deployment, and mutating webhook configuration — into the opa-istio
namespace (refer to Figure 5):
- The mutating webhook controller (
opa-istio-admission-controller
) will then listen for a particular label (opa-istio-injection
) with the value set to enabled. - O controlador de webhook chama o
admission-controller
, que possui a política de injeção. - A política de injeção diz ao
admission-controller
como injetar o container sidecar do OPA no pod.
Figura 5: Configuração de injeção de sidecar do OPA
Agora, antes de deployar a aplicação Bookinfo, vamos criar o namespace bookinfo
e seguir as próximas etapas:
Crie o namespace bookinfo
aplicando bookinfo-ns.yaml:
kubectl apply -f bookinfo-ns.yaml
opa-istio-injection: enabled
, to auto-inject OPA sidecars.
Step 2: Habilitar a Comunicação entre o Proxy do Istio e o OPA
Edite o ConfigMap do Istio no namespace istio-system
e adicione extensionProviders
(opa-ext-authz-grpc
), para que ele habilite a autorização externa na mesh:
- Copie
extensionProviders
das observações em opa_controller.yaml. - Edite o ConfigMap do Istio e adicione
extensionProviders
no campo da mesh. - Certifique-se que a identação esteja correta.
- Salve a configuração.
Essa etapa torna possível que o istio-proxy
comunique com o container opa-istio
no pod para pedidos de autorização.
Se você olhar para o extensionProviders
, é um filtro de tipo ExtAuthzGrpc
em Envoy com um serviço especificado e porta:
...
extensionProviders:
- name: opa-ext-authz-grpc
envoyExtAuthzGrpc:
service: opa-ext-authz-grpc.local
port: "9191"
...
O nome, endereço de serviço e porta dos extensionProviders
devem ser os mesmos no opa_authz.yaml e opa_config.yaml.
Passo 3: Implementar Configuração do OPA
O opa_config.yaml define configurações relacionadas a políticas abertas. Ele tem opa-istio-config
e opa-policy ConfigMaps
— que definem a implementação de serviço gRPC (envoy_ext_authz_grpc
) e as políticas de autorização reais, respectivamente.
As políticas de autorização podem ser divididas em duas partes: a primeira define as condições sob as quais a autorização é permitida ou negada; a segunda define os papéis de usuário e as permissões para cada papel.
As políticas de autorização podem levar algum tempo para se ajustar, pois o Rego não usa muitas palavras-chave aqui. Habilite uma versão mais recente do Rego para obter palavras-chave (palavra-chave permitir se condição, por exemplo).
Aplique a configuração do OPA no namespace bookinfo
, juntamente com a aplicação:
kubectl apply -f opa_config.yaml -n bookinfo
Passo 4: Aplicar Configuração do Istio
O arquivo opa_authz.yaml contém configurações do Istio. Tem uma AuthorizationPolicy
e um ServiceEntry
. Observe que o fornecedor da Política de Autorização é opa-ext-authz-grpc
, que é o extensionProvider
que configuramos no ConfigMap no passo 2.
Similarmente, o hostname definido no ServiceEntry
é o mesmo que o endereço do serviço fornecido no extensionProvider
(opa-ext-authz-grpc.local
). O serviço gRPC irá executar na porta 9191 no localhost 127.0.0.1, que o ServiceEntry
faz com que os sidecars do opa-istio
sejam acessíveis dentro do pod pelo contêiner istio-proxy
.
Implemente a configuração:
kubectl apply -f opa_authz.yaml -n bookinfo
Passo 5: Implemente o Aplicativo e Teste a Configuração de Autorização do Istio-OPA
Implemente o aplicativo Bookinfo e o gateway:
kubectl apply -f /your_Istio_directory/samples/bookinfo/platform/kube/bookinfo.yaml -n bookinfo
kubectl apply -f /your_Istio_directory/samples/bookinfo/networking/bookinfo-gateway.yaml -n bookinfo
Verifique os pods no namespace bookinfo
:
kubectl get pods -n bookinfo
Você pode ver que cada pod tem 3 contêineres executando nele: o aplicativo, o proxy Envoy (istio-proxy
) e o OPA (opa-istio
).
Obtenha o IP do gateway Istio para acessar o serviço:
kubectl get svc -n istio-system

Agora tudo está pronto, e estamos prontos para testar as políticas de autorização. As políticas que definimos em opa_config.yaml são as seguintes:
...
user_roles = {
"alice": ["guest"],
"bob": ["admin"]
}
role_perms = {
"guest": [
{"method": "GET", "path": "/productpage"},
],
"admin": [
{"method": "GET", "path": "/productpage"},
{"method": "GET", "path": "/api/v1/products"},
],
...
Alice é um usuário convidado que só pode acessar o /productpage
; Bob é um admin que pode acessar as rotas /productpage
e /api/v1/products
. Vamos verificar as políticas.
Tentando acessar /api/v1/products
de Alice:
curl -vvv your_istio_gateway_ip/api/v1/products -u alice:password
Você pode ver que a resposta 403 Proibido
desde que Alice não tem acesso àquele caminho. Vamos tentar o mesmo caminho como Bob:
curl -vvv your_istio_gateway_ip/api/v1/products -u bob:password
Ele mostra o status HTTP 200 OK
e o conteúdo da página no final da resposta.
Exemplo de Cenário de Controle de Acesso com OPA
Você pode usar a POLítica de Autorização CRD do Istio para impor a política mostrada no demo acima. Você não precisa do OPA. No entanto, há casos em que a autorização do Istio pode ser limitada, conforme mencionado no início da tabela. Deixe-me dar um exemplo simples.
Suponha que há uma aplicação de BookReviews, que é um serviço de GraphQL, onde os revisores enviam resenhas, os editores editam e publicam essas resenhas, e os usuários lidam com as resenhas publicadas.
Quando um revisor adiciona uma resenha ao serviço, a solicitação incluiria o JWT do revisor, contendo os grupos e papéis (revisor ou editor) aos quais o revisor pertence. O corpo da solicitação também conteria a consulta de mutação GraphQL com os dados da resenha recém-criada.
Vamos dizer que você quer garantir as seguintes condições:
- Somente revisores podem enviar resenhas.
- Um editor pode editar uma resenha apenas se ela for escrita por um revisor que pertence ao mesmo grupo gerenciado por ele.
- Somente editores podem marcar uma resenha como “pronta para publicação”.
Este é o diagrama que inclui as políticas acima:
A Política de Autorização do Istio terá dificuldade em impor as condições acima. A razão é que o Istio não pode usar o corpo da solicitação GraphQL para verificações de autorização, que é um objeto JSON junto do JWT necessário para a avaliação da política.
OPA não tem essas limitações. Ele pode carregar qualquer dado para verificações de política, e DevOps pode escrever essas regras de uma maneira mais ergonômica usando Rego.
Vídeo: demonstração em ação
Se você preferir assistir à demonstração em ação, por favor verifique o vídeo abaixo:S
Suporte Empresarial para Integração do Istio
A maioria das empresas usa o OPA para definir e executar políticas de autorização para toda sua estrutura. Ter um mecanismo central de controle de acesso melhora a segurança e a agilidade dos times de TI. Caso contrário, os desenvolvedores gastarão tempo desenvolvendo políticas de autorização em seu código de aplicação escrito em um determinado idioma, o que impede a escalabilidade e o lançamento mais rápido da lógica de negócios.
Source:
https://dzone.com/articles/5-steps-to-integrate-istio-with-opa