/azure-cli-credentials-proxy

Azure CLI developer credential proxy for Docker, designed for use in local development environments.

Primary LanguageC#Apache License 2.0Apache-2.0

Azure CLI developer credentials proxy for Docker

Docker Hub

This simple containerized application acts as a proxy, allowing other containerized applications to access Azure developer credentials without installing Azure CLI on each individual container. It is designed for use in local development environments only.

Getting started

Add workleap/azure-cli-credentials-proxy:latest to your docker-compose.yml and mount your Linux or WSL ~/.azure/ directory:

version: "3"

services:
  azclicredsproxy:
    image: workleap/azure-cli-credentials-proxy:latest
    volumes:
      - "\\\\wsl$\\<DISTRONAME>\\home\\<USERNAME>\\.azure\\:/app/.azure/" # On Windows with WSL
      - "/home/<USERNAME>/.azure:/app/.azure/" # On Linux

Finally, add two environment variables to your containerized applications that use DefaultAzureCredential or ManagedIdentityCredential:

version: "3"

services:
  # azclicredsproxy: [...]

  myservice:
    build: .
    depends_on:
      - azclicredsproxy
    environment:
      - "IDENTITY_ENDPOINT=http://azclicredsproxy:8080/token"
      - "IMDS_ENDPOINT=dummy_required_value"

Motivation

When developers run services on their operating system, they use their personal Azure identity (username@company.com) to access protected Azure resources, thanks to Azure CLI. The az login command caches Azure personal credentials in a local ~/.azure/ directory, which is then used by DefaultAzureCredential - specifically AzureCliCredential, a part of the former.

When these services run in Azure cloud (App Service, AKS, etc.), protected Azure resources are typically accessed using ManagedIdentityCredential, which uses a service principal-based Azure identity authentication mechanism also included in DefaultAzureCredential.

However, when developers attempt to run these same services in Docker locally, the Docker images do not include Azure CLI. These images also lack access to a service principal. While Dockerfiles can be modified to install Azure CLI, and containers can mount the local ~/.azure/ directory, there are several disadvantages:

  • Azure CLI is not suitable for production as an authentication mechanism
  • Azure CLI adds a significant 1GB to the Docker image

Despite these issues, developers often use their personal Azure identity in local Docker containers. A GitHub issue created in March 2021 remains open.

Solution

Instead of installing Azure CLI in each service, we can run another container - a proxy, which is the only one that contains Azure CLI and a mount on ~/.azure/. This container exposes a single endpoint that returns the Azure developer credentials retrieved with Azure CLI.

Then, we must add two environment variables to each service:

  • IDENTITY_ENDPOINT: the URL of the proxy endpoint (e.g., http://azclicredsproxy:8080/token)
  • IMDS_ENDPOINT: an arbitrary but mandatory value (e.g., random-placeholder)

With these two environment variables, any service that uses DefaultAzureCredential or ManagedIdentityCredential will now call the proxy when Azure credentials are needed. This is because one of ManagedIdentityCredential's source implementations explicitly looks for both of these environment variables if they are specified.

With this proxy, Dockerfiles can remain untouched and production-ready. The proxy can easily be added to an existing docker-compose.yml, and the environment variables are also easy to add. Now, the containerized environment looks like this:

Notes

Keep in mind that you cannot mount a Windows-based ~/.azure/ credentials directory to a Linux container. On Windows, the credentials file cache is a binary file encrypted with DPAPI. On Linux, DPAPI is not supported and the file is not encrypted.

The solution is to use az login on your WSL distribution and mount \\wsl$\Ubuntu\home\<WSLUSERNAME>\.azure\ instead of %USERPROFILE%\.azure\.

License

Copyright © 2023, Workleap Inc.. This code is licensed under the Apache License, Version 2.0. You may obtain a copy of this license at https://github.com/gsoft-inc/gsoft-license/blob/master/LICENSE.