Aprimorando a segurança de workloads: Implementando aplicações Passwordless no Azure com identidades gerenciadas

Leonardo Guilen
7 min readFeb 6, 2024

Entenda como as identidades gerenciadas do Azure facilitam a criação de aplicações sem senha (Passwordless). Eliminando a necessidade de desenvolvedores gerenciarem segredos, credenciais, certificados e chaves usados para autenticar e proteger a comunicação entre serviços.

Introdução

Um dos desafios mais comuns enfrentados pelos desenvolvedores ao manter o código-fonte nos recursos do Azure é: como armazenar e recuperar os segredos sem precisar salvar nenhuma credencial. Existem recursos como o Azure Key Vault que auxiliam nesse gerenciamento de forma extremamente segura, mas ainda sim, eventualmente é necessário a manutenção desses valores.

Uma solução recomendada é utilizar Identidades Gerenciadas do Azure para tirar a necessidade de os desenvolvedores gerenciarem essas credenciais, e atribuir essa função ao próprio Azure. Mas afinal, o que são as tais das Identidades Gerenciadas?

O que é o Azure Managed Identity?

A Identidade Gerenciada do Azure é um recurso que fornece uma identidade para que os serviços se autentiquem com segurança no ecossistema do Azure sem a necessidade de gerenciar credenciais diretamente. Ele simplifica o gerenciamento das credenciais usadas para autenticação nos serviços do Azure.

Quando você habilita uma Identidade Gerenciada para uma instância de serviço (como uma máquina virtual, função do Azure ou Serviço de Aplicativo do Azure), o Azure cria uma identidade para esse serviço no Azure Entra ID (Antigamente conhecido como Azure AD). Essa identidade pode então ser usada para autenticar o serviço ao acessar outros recursos do Azure, como o Azure Key Vault, o Armazenamento do Azure, o Banco de Dados SQL do Azure e muito mais.

Há dois tipos de Managed Identities:

  • Identidade gerenciada atribuída pelo sistema (System-assigned): O Azure cria e gerencia automaticamente o ciclo de vida da identidade (incluindo credenciais) para a instância de serviço.
  • Identidade gerenciada atribuída pelo usuário (User-assigned): Você cria a identidade como um recurso autônomo do Azure e depois a atribui a um ou mais serviços do Azure. Isso permite que vários serviços compartilhem a mesma identidade.

Em geral, o Azure Managed Identity simplifica a autenticação e aumenta a segurança dos serviços do Azure, fornecendo uma solução de identidade gerenciada dentro do ecossistema do Azure.

Construção do Lab

A ideia do lab será criar uma infraestrutura para implantar uma imagem docker de uma aplicação .NET que consome eventos de uma fila do Service Bus.

Como resultado final, teremos o seguinte ambiente provisionado:

Uma breve explicação do fluxo:

  1. Container Instance puxa uma imagem que será colocada no Registry e inicia a execução do container.
  2. O Container em execução solicita um token de autenticação para o Managed Identity.
  3. O Managed Identities pede um token para o Entra ID, que o retorna caso o recurso solicitante possua uma identidade gerenciada atribuída.
  4. Um token de acesso é entregue para o Container Instance.
  5. Com o token em mãos, a aplicação rodando dentro do container consegue se conectar aos recursos necessários SE houver uma role atribuída ao recurso do Container Instance que permita o acesso ao AppConfiguration e o namespace do Service Bus.

Provisionando Recursos

Para o lab, teremos que criar 4 recursos. App Configuration, Service Bus, Container Registry e Container Instance.

Vamos começar criando o recurso do Service Bus, iniciando pela criação do namespace.

A configuração básica é suficiente para o lab. Podemos prosseguir para a criação. Após o recurso ter sido implantado, criaremos uma fila nomeada como “events”.

Por enquanto é isso. Vamos criar e configurar o App Configuration.

Com o recurso criado, atribuiremos duas configurações novas que serão utilizadas pela aplicação para conectar-se ao Service Bus.

Lembre-se de ir utilizar o namespace do service bus que foi criado. Acesse o recurso e na aba de Overview copie o valor do campo chamado “host name”.

Em seguida, criaremos o Container Registry responsável em armazenar as imagens Docker das aplicações.

Nenhuma configuração adicional é necessária no pós implantação.

E por fim, temos que implantar o Container Instance uma ótima solução para rodar containers Docker de um jeito rápido e simples no Azure.

Essa configuração básica é suficiente para subir um container, e por enquanto é isso que precisamos.

Enviando imagem para o Container Registry

A aplicação que será implantada tem duas principais funções: Carregar os valores do App Configuration e iniciar o consumo de mensagens do Service Bus.

Gist com a implementação simplificada:

Para enviar a imagem dessa aplicação para o Azure, primeiro passo é autenticar no Registry. Para isso usaremos a CLI com os seguintes comandos:

az login
az acr login --name crlabbrazilsouth001 <-- Registry Name

Após autenticado com sucesso, faremos o build e push para o Registry:

docker buildx build -t crlabbrazilsouth001.azurecr.io/eventconsumer .
docker push crlabbrazilsouth001.azurecr.io/eventconsumer

Done! Subimos a imagem para o Azure e acessando o Registry via portal podemos confirmar isso:

Por último, devemos atualizar a imagem do Container Instance para utilizar a que subimos a pouco. E como faremos isso? Com a CLI, claro.

az container create \
--resource-group rg-lab-brazilsouth-001 \
--name ci-lab-brazilsouth-001 \
--image crlabbrazilsouth001.azurecr.io/eventconsumer \
--restart-policy OnFailure \
--environment-variables "Azure__AppConfiguration__Endpoint=https://appcs-lab-brazilsouth-001.azconfig.io"

Container atualizado. Porém, visualizando os logs de execução do container vemos que há um erro de autenticação:

E por que isso? Simples. Estamos tentando conectar em recursos, mas não fornecemos nenhum tipo de credencial para realizar a autenticação.

Mas isso é proposital, pois deixaremos o Azure cuidar dessa camada de segurança através das Identidades Gerenciadas.

Configurando Identidades Gerenciadas

Para configurar uma identidade gerenciada para um recurso, um dos jeitos é ir até o portal do Azure e acessar o recurso que terá essa funcionalidade habilitada. Nesse caso, o Container Instance.

Após salvar as alterações, será criado um identificador exclusivo atribuído a esse recurso, quando ele é registrado no Microsoft Entra ID.

Isso é tudo? Claro que não. Aqui habilitamos a identidade gerenciada para o recurso do Container Instance no Microsoft Entra ID, mas é apenas a etapa de autenticação. Agora, precisamos atribuir as permissões a identidade gerenciada, ou seja, dizer quais recursos podem se conectar e as funções permitidas. Aqui trabalharemos com Azure RBAC.

Como podemos ver, não temos nada atribuído ainda. Poderíamos atribuir as roles usando o botão Add role assignment, mas é uma funcionalidade em preview (até a data desse post), e ainda não possui todos os escopos disponíveis. Portanto, vamos acessar o IAM de cada recurso e fazer a atribuição por lá.

Iniciando com o App Configuration:

Essa é a lista de funções pré-definidas para esse recurso. Selecionei a função App Configuration Data Reader, pois queremos que o nosso app tenha permissão apenas de leitura dos dados.

Próximo passo é dizer para quem iremos atribuir essa função, que nesse caso, é a identidade gerenciada criada no recurso Container Instance. E por fim, revise se está tudo certo e confirme a atribuição.

Pronto! Nossa aplicação é capaz de ler os valores do App Configuration. Agora é só repetir o processo para o recurso do Service Bus, atribuindo a função Azure Service Bus Data Receiver a nossa identidade gerenciada.

Validação e testes

Com todas as etapas realizadas, se listarmos novamente as atribuição de roles na identidade gerenciada, veremos que temos recursos associados agora.

Para testar, primeiro de um restart na instância que está rodando e aguarde até que o status seja Running. Após isso, acesse o container e analise os logs:

Note que a aplicação conseguiu obter um token com sucesso e com esse token foi possível ler os valores do App Configuration e iniciar uma conexão com o nosso Service Bus.

Para garantir que o consumo de mensagens está funcionando, vamos publicar uma nova mensagens no Service Bus e analisar o log novamente.

That works! :)

Conclusão

Em resumo, a implementação de aplicações no Azure com identidades gerenciadas oferece uma abordagem inovadora e segura para lidar com questões de autenticação. Ao utilizar identidades gerenciadas no Azure, os desenvolvedores podem simplificar a gestão de credenciais, deixando com que o mecanismo do Azure fique responsável por isso. E assim, melhoramos muito a segurança dos nossos workloads no dia a dia.

--

--

Leonardo Guilen

Software Engineer focused on backend technologies, DevOps and Cloud. Researcher of the best coding standards, performance optimization and security enhancements