Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
This article shows how to:
- Create a Microsoft Entra Workload ID and Kubernetes service account.
- Configure the managed identity for token federation.
- Create a Microsoft Azure Key Vault with a new secret and role assignments (for a demo).
- Deploy the workload and verify authentication with the workload identity.
- Grant a pod in the cluster access to secrets in an Azure key vault.
The process entails:
- Obtain the OpenID Connect (OIDC) issuer URL.
- Create a user assigned managed identity for your application.
- Perform the role assignment on the desired resource.
- Create a Kubernetes service account.
- Set the annotation on the service account.
- Create the federated credential.
- Deploy the application and ensure that:
- The
.spec.serviceAccountName
is set. - The label
azure.workload.identity/use: "true"
is set.
- The
Important
This Azure Red Hat OpenShift feature is currently offered in preview only. Preview features are available on a self-service, opt-in basis. Previews are provided as is and as available, and are excluded from the service-level agreements and limited warranty. Azure Red Hat OpenShift previews are partially covered by customer support on a best-effort basis so those features aren't meant for production use.
Prerequisites
You need an existing managed identity Azure Red Hat OpenShift cluster.
Verify pod-identity-webhook deployment
There's a mutating admission webhook which projects a signed service account token to a well-known path and injects authentication-related environment variables to the application pods. For more information, see Mutating admission webhook.
Verify that the annotation target.workload.openshift.io/management
is set on the pod-identity-webhook deployment in the openshift-cloud-credential-operator
namespace by running the following command:
oc describe deployment pod-identity-webhook -n openshift-cloud-credential-operator | grep 'target.workload.openshift.io/management'
You should see a response like:
Annotations: target.workload.openshift.io/management: {"effect": "PreferredDuringScheduling"}
If you find that the annotation is missing, open a support case.
Export environment variables
Begin by setting environment variables matching your existing managed identity Azure Red Hat OpenShift cluster. Make sure to set the correct RESOURCE_GROUP
, LOCATION
, CLUSTER_NAME
, namespaces, and desired identity names:
export KEYVAULT_NAME="azwi-kv-$(openssl rand -hex 2)"
export KEYVAULT_SECRET_NAME="my-secret"
export KEYVAULT_LOCATION="eastus"
export RESOURCE_GROUP="<ARO_CLUSTER_RESOURCE_GROUP>"
export CLUSTER_NAME="<ARO_CLUSTER_NAME>"
export SUBSCRIPTION="$(az account show --query id --output tsv)"
export USER_ASSIGNED_IDENTITY_NAME="example-user-assigned-identity"
export FEDERATED_IDENTITY_CREDENTIAL_NAME="example-federated-identity"
export SERVICE_ACCOUNT_NAMESPACE="example-project"
export SERVICE_ACCOUNT_NAME="example-workload-identity-sa"
Retrieve the OIDC issuer URL
Obtain the Azure Red Hat OpenShift cluster OIDC issuer URL using OpenShift CLI (OC) and set the environment variable:
export ARO_OIDC_ISSUER="$(oc get authentication cluster -o jsonpath='{.spec.serviceAccountIssuer}')"
Optionally, if you don't have cluster access, get the Azure Red Hat OpenShift cluster OIDC issuer URL by using the Azure CLI:
export ARO_OIDC_ISSUER="$(az aro show --subscription "${SUBSCRIPTION}" \
--name "${CLUSTER_NAME}" \
--resource-group "${RESOURCE_GROUP}" \
--query "clusterProfile.oidcIssuer" \
--output tsv)"
Verify the correct URL is set:
echo $ARO_OIDC_ISSUER
https://eastus.oic.aro.azure.net/00000000-0000-0000-0000-000000000000/11111111-1111-1111-1111-111111111111
By default, the issuer is set to use the base URL https://{region}.oic.aro.azure.net/{tenant_id}/{uuid}
, where the value for {region}
matches the location to which the Azure Red Hat OpenShift cluster is deployed. The value {uuid}
represents the OIDC key, which is an immutable, randomly generated, cluster-specific GUID.
Create an example resource
In this example, a new Microsoft Azure Key Vault with a new secret is created and later accessed via Microsoft Entra Workload ID. Use the Azure az
command line tool to create the key vault that is later accessed.
Ensure the Azure role-based access control (Azure RBAC) Key Vault Secrets Officer role is assigned to yourself.
# If necessary, create the Resource Group
az group create --resource-group "${RESOURCE_GROUP}" --location "${KEYVAULT_LOCATION}"
# Create the Keyvault and set a secret value
az keyvault create --resource-group "${RESOURCE_GROUP}" --location "${KEYVAULT_LOCATION}" --name "${KEYVAULT_NAME}"
az keyvault secret set --vault-name "${KEYVAULT_NAME}" --name "${KEYVAULT_SECRET_NAME}" --value "Hello world"
# Create an environment variable for the key vault URL:
export KEYVAULT_URL="$(az keyvault show --resource-group ${RESOURCE_GROUP} --name ${KEYVAULT_NAME} --query properties.vaultUri --output tsv)"
# Create an environment variable for the key vault Resource ID:
export KEYVAULT_RESOURCE_ID=$(az keyvault show --resource-group "${RESOURCE_GROUP}" --name "${KEYVAULT_NAME}" | jq -r '.id')
Create a managed identity and grant permission to access Azure Key Vault
In the next steps, create a user-assigned managed identity and the corresponding role assignment:
# Create the identity
az identity create --name "${USER_ASSIGNED_IDENTITY_NAME}" --resource-group "${RESOURCE_GROUP}"
# Assign Key Vault Secrets User to the identity
export USER_ASSIGNED_IDENTITY_OBJECT_ID="$(az identity show --name "${USER_ASSIGNED_IDENTITY_NAME}" --resource-group "${RESOURCE_GROUP}" --query 'principalId' -o tsv)"
export USER_ASSIGNED_IDENTITY_CLIENT_ID="$(az identity show --name "${USER_ASSIGNED_IDENTITY_NAME}" --resource-group "${RESOURCE_GROUP}" --query 'clientId' -o tsv)"
az role assignment create --assignee-object-id "${USER_ASSIGNED_IDENTITY_OBJECT_ID}" --role "Key Vault Secrets User" --scope "${KEYVAULT_RESOURCE_ID}" --assignee-principal-type ServicePrincipal
Create a Kubernetes service account
- In OpenShift Container Platform, create the Service Account with the
azure.workload.identity/client-id
set to theUSER_ASSIGNED_IDENTITY_CLIENT_ID
previously created. - For more information about creating service accounts, see Creating service accounts.
Create the new project for this example app:
oc new-project ${SERVICE_ACCOUNT_NAMESPACE}
Create the service account:
cat <<EOF | oc apply -f -
apiVersion: v1
kind: ServiceAccount
metadata:
name: ${SERVICE_ACCOUNT_NAME}
namespace: ${SERVICE_ACCOUNT_NAMESPACE}
annotations:
azure.workload.identity/client-id: ${USER_ASSIGNED_IDENTITY_CLIENT_ID}
EOF
Create the federated identity credential
Create an Azure federated identity credential that links the service account in OpenShift Container Platform to the Azure user-assigned managed identity:
az identity federated-credential create \
--name "${FEDERATED_IDENTITY_CREDENTIAL_NAME}" \
--identity-name "${USER_ASSIGNED_IDENTITY_NAME}" \
--resource-group "${RESOURCE_GROUP}" \
--issuer "${ARO_OIDC_ISSUER}" \
--subject "system:serviceaccount:${SERVICE_ACCOUNT_NAMESPACE}:${SERVICE_ACCOUNT_NAME}"
Deploy the application
The OpenShift Container Platform Service Account is now configured as expected. Note the .spec.serviceAccountName
is set and the label azure.workload.identity/use: "true"
is used:
cat <<EOF | oc apply -f -
apiVersion: v1
kind: Pod
metadata:
name: quick-start
namespace: ${SERVICE_ACCOUNT_NAMESPACE}
labels:
azure.workload.identity/use: "true"
spec:
serviceAccountName: ${SERVICE_ACCOUNT_NAME}
securityContext:
runAsNonRoot: true
seccompProfile:
type: RuntimeDefault
containers:
- image: ghcr.io/azure/azure-workload-identity/msal-go
name: oidc
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop: [ "ALL" ]
env:
- name: KEYVAULT_URL
value: ${KEYVAULT_URL}
- name: SECRET_NAME
value: ${KEYVAULT_SECRET_NAME}
EOF
Verify the deployed workload
In the newly deployed workload, verify that the environment variables and projected volume are both present. Run the following command:
oc describe pod quick-start
See the following example output:
[..]
Environment:
KEYVAULT_URL: https://azwi-kv-45ff.vault.azure.net/
SECRET_NAME: my-secret
AZURE_CLIENT_ID: 00001111-aaaa-2222-bbbb-3333cccc4444
AZURE_TENANT_ID: aaaabbbb-0000-cccc-1111-dddd2222eeee
AZURE_FEDERATED_TOKEN_FILE: /var/run/secrets/azure/tokens/azure-identity-token
AZURE_AUTHORITY_HOST: https://login.microsoftonline.com/
[..]
Volumes:
[..]
azure-identity-token:
Type: Projected (a volume that contains injected data from multiple sources)
TokenExpirationSeconds: 3600
Verify in the logs that the workload was able to access the Microsoft Azure Key Vault using the injected keys:
$ oc logs quick-start
I0816 09:43:37.961113 1 main.go:63] "successfully got secret" secret="Hello world"