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 you how to configure external identity providers for Azure Kubernetes Service (AKS) control plane authentication using structured authentication. You learn how to create JSON Web Token (JWT) authenticators, configure claim validation and mapping, and test the authentication flow.
Important
AKS preview features are available on a self-service, opt-in basis. Previews are provided "as is" and "as available," and they're excluded from the service-level agreements and limited warranty. AKS previews are partially covered by customer support on a best-effort basis. As such, these features aren't meant for production use. For more information, see the following support articles:
Prerequisites
- Read conceptual overview for authentication to AKS using external identity provider.
If you prefer to run CLI reference commands locally, install the Azure CLI. If you're running on Windows or macOS, consider running Azure CLI in a Docker container. For more information, see How to run the Azure CLI in a Docker container.
If you're using a local installation, sign in to the Azure CLI by using the az login command. To finish the authentication process, follow the steps displayed in your terminal. For other sign-in options, see Sign in with the Azure CLI.
When you're prompted, install the Azure CLI extension on first use. For more information about extensions, see Use extensions with the Azure CLI.
Run az version to find the version and dependent libraries that are installed. To upgrade to the latest version, run az upgrade.
- This article requires version 2.77.0 or later of the Azure CLI.
- You need to install the
aks-previewAzure CLI extension version 18.0.0b41 or later to use structured authentication features.- If you don't already have the
aks-previewextension, install it using theaz extension addcommand:az extension add --name aks-preview - If you already have the
aks-previewextension, update it to make sure you have the latest version using theaz extension updatecommand:az extension update --name aks-preview - Verify you have the required version:
az extension show --name aks-preview --query version
- If you don't already have the
- An AKS cluster running Kubernetes version 1.30 or later. To create an AKS cluster, see Quickstart: Deploy an Azure Kubernetes Service (AKS) cluster using Azure CLI.
kubectlcommand-line tool to interact with your Kubernetes cluster. To installkubectllocally, use the az aks install-cli command.az aks install-cli- An external identity provider that supports OpenID Connect (OIDC).
- Network connectivity from cluster nodes to your identity provider.
- If you plan to use the
kubeloginplugin, install it using these setup instructions
Set environment variables
Set the following environment variables for your resource group and cluster name:
export RESOURCE_GROUP="<your-resource-group-name>"
export CLUSTER_NAME="<your-cluster-name>"
Register the preview feature
If you're using a subscription without the feature registered, register the JWTAuthenticatorPreview feature:
az feature register --name JWTAuthenticatorPreview --namespace Microsoft.ContainerService
Check the registration status:
az feature show --name JWTAuthenticatorPreview --namespace Microsoft.ContainerService
When the status shows Registered, refresh the resource provider registration:
az provider register --namespace Microsoft.ContainerService
Set up your identity provider
Configure your external identity provider to support OIDC authentication. Select your identity provider for specific setup instructions:
GitHub Actions OIDC Setup
- Ensure your GitHub Actions workflows have the necessary permissions.
- Configure the
id-token: writepermission in your workflow files:permissions: id-token: write contents: read - Set up appropriate repository and organization settings for OIDC token access. Configure repository OIDC settings and organization security policies for token usage.
Create JWT authenticator configuration
Create a JSON configuration file that defines how to validate and process tokens from your identity provider. Select your identity provider for specific configuration examples:
GitHub Configuration
For GitHub Actions OIDC, create a file named jwt-config.json with the following configuration:
{
"issuer": {
"url": "https://token.actions.githubusercontent.com",
"audiences": [
"my-api"
]
},
"claimValidationRules": [
{
"expression": "has(claims.sub)",
"message": "must have sub claim"
}
],
"claimMappings": {
"username": {
"expression": "'aks:jwt:github:' + claims.sub"
}
},
"userValidationRules": [
{
"expression": "has(user.username)",
"message": "must have username"
},
{
"expression": "!user.username.startsWith('aks:jwt:github:system')",
"message": "username must not start with 'aks:jwt:github:system'"
}
]
}
Configuration elements
- issuer: The OIDC issuer configuration.
- url: The OIDC issuer URL that must match the
issclaim in JWTs. - audiences: List of audiences that JWTs must be issued for (checked against
audclaim). - certificateAuthority: Optional base64-encoded root certificate bundle for Transport Layer Security (TLS) verification.
- url: The OIDC issuer URL that must match the
- claimValidationRules: Array of validation rules using CEL expressions to validate JWT claims.
- expression: CEL expression that must evaluate to true.
- message: Error message displayed when validation fails.
- claimMappings: Defines how JWT claims map to Kubernetes user information.
- username: CEL expression defining how to construct the username from claims.
- groups: CEL expression defining how to construct group memberships from claims.
- uid: Optional CEL expression for user identifier.
- extra: Optional map of more user attributes.
- userValidationRules: Array of validation rules applied to the final user information.
- expression: CEL expression that must evaluate to true for the mapped user.
- message: Error message displayed when user validation fails.
Important
All username and group mappings must include the aks:jwt: prefix to prevent conflicts with other authentication methods.
Create the JWT authenticator
Add the JWT authenticator to your AKS cluster:
az aks jwtauthenticator add \
--resource-group $RESOURCE_GROUP \
--cluster-name $CLUSTER_NAME \
--name external-auth \
--config-file jwt-config.json
Verify the authenticator
List all JWT authenticators on your cluster:
az aks jwtauthenticator list \
--resource-group $RESOURCE_GROUP \
--cluster-name $CLUSTER_NAME
Get details of a specific authenticator:
az aks jwtauthenticator show \
--resource-group $RESOURCE_GROUP \
--cluster-name $CLUSTER_NAME \
--name external-auth
Set up client for authentication
Configure your client to authenticate with your external identity provider. Select your identity provider for specific configuration:
GitHub Actions Workflow Authentication
For GitHub Actions OIDC, create a workflow that obtains an OIDC token and uses it to authenticate with your AKS cluster. Here's an example workflow that gets all pods running on the cluster:
name: AKS Access with GitHub OIDC
on:
workflow_dispatch:
push:
branches: [main]
permissions:
id-token: write
contents: read
jobs:
aks-access:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Install kubectl
uses: azure/setup-kubectl@v3
with:
version: 'latest'
- name: Get GitHub OIDC token
id: get_token
run: |
TOKEN=$(curl -H "Authorization: Bearer $ACTIONS_ID_TOKEN_REQUEST_TOKEN" \
"$ACTIONS_ID_TOKEN_REQUEST_URL&audience=my-api" | \
jq -r '.value')
echo "::add-mask::$TOKEN"
echo "oidc_token=$TOKEN" >> $GITHUB_OUTPUT
- name: Create kubeconfig with OIDC token
run: |
cat <<EOF > kubeconfig
apiVersion: v1
kind: Config
clusters:
- cluster:
certificate-authority-data: ${{ secrets.AKS_CA_DATA }}
server: ${{ secrets.AKS_SERVER_URL }}
name: aks-cluster
contexts:
- context:
cluster: aks-cluster
user: github-oidc-user
name: aks-context
current-context: aks-context
users:
- name: github-oidc-user
user:
token: ${{ steps.get_token.outputs.oidc_token }}
EOF
- name: List all pods in the cluster
run: |
export KUBECONFIG=./kubeconfig
kubectl get pods --all-namespaces
Required repository secrets and variables
Set up these secrets in your GitHub repository:
Secrets:
AKS_SERVER_URL: Your AKS cluster's API server URL.AKS_CA_DATA: Base64-encoded certificate authority data for your AKS cluster.
Note
The audience value my-api should match the audience configured in your JWT authenticator configuration.
Getting AKS cluster information
To get the required cluster information, run:
# Get cluster info
az aks show --resource-group $RESOURCE_GROUP --name $CLUSTER_NAME --query "fqdn" -o tsv | \
awk '{print "https://" $0 ":443"}'
# Get CA data (base64 encoded)
az aks get-credentials --resource-group $RESOURCE_GROUP --name $CLUSTER_NAME --file - --format exec | \
grep certificate-authority-data | awk '{print $2}'
Method 2: Using static token
If you have a JWT token, you can use it directly:
users:
- name: external-user
user:
token: eyJhbGciOiJSUzI1NiIs...
Test authentication
You can trigger the workflow by:
- Pushing to the main branch
- Manually triggering it from the Actions tab in your repository
Monitor the workflow execution in the Actions tab to verify authentication is working.
Expected output for first-time setup before Role-Based Access Control (RBAC) configuration:
Error from server (Forbidden): nodes is forbidden: User "aks:jwt:github:your-sub" cannot list resource "nodes" in API group "" at the cluster scope
This error indicates successful authentication but lack of authorization.
Configure Kubernetes Role-Based Access Control (RBAC)
Create appropriate RBAC bindings for your external users. Use the cluster admin credentials to apply these configurations. Select your identity provider for provider-specific examples:
Create a sample role and binding
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: external-user-role
rules:
- apiGroups: [""]
resources: ["pods", "services", "nodes"]
verbs: ["get", "list"]
- apiGroups: ["apps"]
resources: ["deployments", "replicasets"]
verbs: ["get", "list"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: external-user-binding
subjects:
- kind: User
# This matches the username expression in claim mappings for GitHub; example of GitHub subject is "repo:<organization-name>/<repository-name>:ref:refs/heads/main"
name: aks:jwt:github:your-github-sub
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: ClusterRole
name: external-user-role
apiGroup: rbac.authorization.k8s.io
Apply the RBAC configuration:
kubectl apply -f rbac-config.yaml
Verify access
Test that the external user can now access resources:
kubectl get nodes --user external-user
kubectl get pods --user external-user
Remove JWT authenticator
Delete an authenticator when no longer needed:
az aks jwtauthenticator delete \
--resource-group $RESOURCE_GROUP \
--cluster-name $CLUSTER_NAME \
--name external-auth