Skip to content

Instantly share code, notes, and snippets.

@chgeuer
Created June 26, 2023 15:56
Show Gist options
  • Select an option

  • Save chgeuer/29b9fb91f480567bc8098fbe9f60ed0a to your computer and use it in GitHub Desktop.

Select an option

Save chgeuer/29b9fb91f480567bc8098fbe9f60ed0a to your computer and use it in GitHub Desktop.

Gitlab using managed identity to access Azure

In #GitLab, you don't need to request a GitLab-issued token from some token endpoint. Instead, you just specify in your id_tokens section that you want a token for a certain audience, and GitLab hosts the #JWT token in the environment variable you specify.

In this example, GitLab issues a token for the audience api://AzureADTokenExchange and makes it available in the environment variable ID_TOKEN_FOR_AZURE.

image-20230522090952500

Demo how to access an Azure resource, in this example read a secret from KeyVault (az keyvault secret show).

image: mcr.microsoft.com/azure-cli:latest

build1:
  stage: build
  id_tokens:
    ID_TOKEN_FOR_AZURE:
      aud: "api://AzureADTokenExchange"
  script:
    - echo "##### Full token contents"
    - jq -R 'split(".") | .[1] | @base64d | fromjson' <<< "${ID_TOKEN_FOR_AZURE}"
    - echo "##### Config necessary for Azure"
    - jq -R 'split(".") | .[1] | @base64d | fromjson | {issuer:.iss,audiences:[.aud],subject:.sub}' <<< "${ID_TOKEN_FOR_AZURE}"
    - echo "##### Logging-in to the Azure user-assigned managed identity"
    - az login --service-principal --tenant "${AZURE_TENANT_ID}" --username "${AZURE_UAMI_CLIENT_ID}" --federated-token "${ID_TOKEN_FOR_AZURE}" --allow-no-subscriptions
    - echo "##### Fetching a secret from KeyVault"
    - az keyvault secret show --vault-name "${AZURE_KEYVAULT_NAME}" --name "${AZURE_KEYVAULT_SECRET_NAME}" | jq .

Another example could be

image: mcr.microsoft.com/azure-cli:latest

build1:
  stage: build
  id_tokens:
    MEIN_TOKEN:
      aud: "api://AzureADTokenExchange"
  script:
    - az login --service-principal --tenant "${AZURE_TENANT_ID}" --username "${AZURE_UAMI_CLIENT_ID}" --federated-token "${MEIN_TOKEN}" --allow-no-subscriptions
    - az group deployment create .... WHATEVER    

The JWT looks like this:

{
  "iss": "https://gitlab.com",
  "sub": "project_path:chgeuer/azure-workload-identity-federation-demo:ref_type:branch:ref:main",
  "aud": "api://AzureADTokenExchange",

  "namespace_path": "chgeuer", "namespace_id": "...",  
  "project_path": "chgeuer/azure-workload-identity-federation-demo", "project_id": "...",  
  "user_login": "chgeuer", "user_id": "...", "user_email": "...",
  "pipeline_id": "...",
  "pipeline_source": "push",
  "job_id": "...",
  "ref": "main",
  "ref_type": "branch",
  "ref_path": "refs/heads/main",
  "ref_protected": "true",
  "runner_id": ...,
  "runner_environment": "gitlab-hosted",
  "sha": "71c7d2186cba2f0ec544f84ea6561395e759f9a1",
  "jti": "b8af816d-cb58-441d-9e8d-bbe396f4c366",
  "iat": 1684785093,
  "nbf": 1684785088,
  "exp": 1684788693
}

The config JSON for the managed identity

{
  "issuer": "https://gitlab.com",
  "audiences": [
    "api://AzureADTokenExchange"
  ],
  "subject": "project_path:chgeuer/azure-workload-identity-federation-demo:ref_type:branch:ref:main"
}

image-20230522090631770

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment