Skip to content

OIDC Setup

What is OIDC?

OpenID Connect (OIDC) allows your GitHub Actions workflows to access Azure resources without storing any credentials as long-lived GitHub secrets. Azure natively supports OIDC through Entra ID federated credentials. This is the most secure authentication method for production environments.

Before you begin, ensure you have the following:

  • Azure CLI
  • An Azure subscription with permissions to create App Registrations and assign RBAC roles
  1. Terminal window
    az login
  2. Terminal window
    az account show --query '{subscriptionId:id, tenantId:tenantId}' -o json

    Example output:

    {
    "subscriptionId": "00000000-0000-0000-0000-000000000000",
    "tenantId": "00000000-0000-0000-0000-000000000000"
    }
  3. Terminal window
    export SUBSCRIPTION_ID="<subscription-id>"
    export TENANT_ID="<tenant-id>"
    export GITHUB_ORG="<github-org-or-username>"
    export REPO_NAME="<repository-name>"
  4. Terminal window
    az ad app create --display-name "terrateam"

    Note the appId from the output:

    {
    "appId": "00000000-0000-0000-0000-000000000000",
    ...
    }
    Terminal window
    export CLIENT_ID="<appId>"
  5. Terminal window
    az ad sp create --id "$CLIENT_ID"
  6. Get the App Registration’s object ID (different from the client/app ID):

    Terminal window
    APP_OBJECT_ID=$(az ad app show --id "$CLIENT_ID" --query "id" -o tsv)

    Create a flexible federated credential using the Microsoft Graph beta API. This uses claimsMatchingExpression with the matches operator and * wildcard to allow authentication from any branch, tag, or pull request in your repository:

    Terminal window
    az rest --method POST \
    --uri "https://graph.microsoft.com/beta/applications/${APP_OBJECT_ID}/federatedIdentityCredentials" \
    --headers "Content-Type=application/json" \
    --body "{'name': 'terrateam-github', 'issuer': 'https://token.actions.githubusercontent.com', 'audiences': ['api://AzureADTokenExchange'], 'description': 'Terrateam GitHub Actions OIDC', 'claimsMatchingExpression': {'value': 'claims[\'sub\'] matches \'repo:${GITHUB_ORG}/${REPO_NAME}:*\'', 'languageVersion': 1}}"

    Verify the credential was created:

    Terminal window
    az rest --method GET \
    --uri "https://graph.microsoft.com/beta/applications/${APP_OBJECT_ID}/federatedIdentityCredentials" \
    --query "value[].{name:name, expression:claimsMatchingExpression.value}" -o table
  7. Grant the service principal permissions on your subscription:

    Terminal window
    az role assignment create \
    --assignee "$CLIENT_ID" \
    --role "Contributor" \
    --scope "/subscriptions/$SUBSCRIPTION_ID"

After setting up Azure resources, configure Terrateam to use OIDC authentication:

  1. Create the .terrateam/config.yml configuration file at the root of your Terraform repository.

  2. hooks:
    all:
    pre:
    - type: oidc
    provider: azure
    client_id: "CLIENT_ID"
    tenant_id: "TENANT_ID"
    subscription_id: "SUBSCRIPTION_ID"

Test that OIDC authentication is working:

  1. Create a simple Terraform configuration in your repository
  2. Open a pull request with the changes
  3. Comment terrateam plan on the pull request
  4. Terrateam should successfully authenticate using OIDC and show the plan output

Azure OIDC with Terrateam works by:

  1. Terrateam requests a GitHub OIDC token with audience api://AzureADTokenExchange
  2. The token is passed directly to the Terraform AzureRM/AzAPI providers via environment variables
  3. The providers exchange the token with Entra ID for Azure credentials

The following environment variables are automatically set:

VariableValue
ARM_USE_OIDCtrue
ARM_CLIENT_IDYour App Registration client ID
ARM_TENANT_IDYour Entra ID tenant ID
ARM_OIDC_TOKENThe GitHub OIDC token
ARM_SUBSCRIPTION_IDYour Azure subscription ID (if configured)

Now that you have Azure authentication configured, you are now able to use Terrateam for plan and apply operations against Azure resources.