Configure external identity providers with AKS structured authentication (preview)

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

  • 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. To install or update the Azure CLI on your local machine, see Install the Azure CLI.

  • You need to install the aks-preview Azure CLI extension version 18.0.0b41 or later to use structured authentication features.

    • If you don't already have the aks-preview extension, install it using the az extension add command.

      az extension add --name aks-preview
      
    • If you already have the aks-preview extension, update it to make sure you have the latest version using the az extension update command.

      az extension update --name aks-preview
      
    • Verify you have the required version of the aks-preview extension using the [az extension show][az-extension-show] command.

      az extension show --name aks-preview --query version
      
  • An AKS cluster running Kubernetes version 1.30 or later. To create an AKS cluster, see Deploy an Azure Kubernetes Service (AKS) cluster using Azure CLI.

  • kubectl command-line tool to interact with your Kubernetes cluster. To install kubectl locally, 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 kubelogin plugin, install it by following the instructions in the kubelogin setup guide.

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 JWTAuthenticatorPreview feature

  1. Register the JWTAuthenticatorPreview feature using the [az feature register][az-feature-register] command.

    az feature register --name JWTAuthenticatorPreview --namespace Microsoft.ContainerService
    
  2. Check the registration status of the feature using the [az feature show][az-feature-show] command.

    az feature show --name JWTAuthenticatorPreview --namespace Microsoft.ContainerService
    
  3. When the status shows Registered, refresh the resource provider registration for Microsoft.ContainerService using the [az provider register][az-provider-register] command.

    az provider register --namespace Microsoft.ContainerService
    

Set up GitHub Actions OIDC authentication

  1. Ensure your GitHub Actions workflows have the necessary permissions.

  2. Configure the id-token: write permission in your workflow files. For example:

    permissions:
      id-token: write
      contents: read
    
  3. 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 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'"
          }
      ]
    }
    

JWT authenticator configuration elements

The JWT authenticator configuration includes the following key elements: issuer, claimValidationRules, claimMappings, and userValidationRules. Each element serves a specific purpose in defining how AKS validates and processes JWT tokens from the external identity provider.

Issuer configuration

The following table describes the key elements of the issuer configuration:

Issuer configuration element Description
url The OIDC issuer URL that must match the iss claim in JWTs.
audiences List of audiences that JWTs must be issued for (checked against aud claim).
certificateAuthority Optional base64-encoded root certificate bundle for Transport Layer Security (TLS) verification when connecting to the issuer URL.

Claim validation rules configuration

The following table describes the key elements of the claimValidationRules configuration:

Claim validation rule element Description
expression CEL expression that defines the validation logic to apply to JWT claims. The expression must evaluate to true for the token to be accepted.
message Error message returned when the validation rule fails.

Claim mappings configuration

The following table describes the key elements of the claimMappings configuration:

Claim mappings element Description
username CEL expression that defines how to construct the Kubernetes username from JWT claims. Must include the aks:jwt: prefix to prevent conflicts with other authentication methods.
groups CEL expression that defines how to construct Kubernetes group memberships from JWT claims. Must include the aks:jwt: prefix to prevent conflicts with other authentication methods.
uid Optional CEL expression that defines a unique identifier for the user.
extra Optional map of additional user attributes defined by CEL expressions.

User validation rules configuration

The following table describes the key elements of the userValidationRules configuration:

User validation rule element Description
expression CEL expression that defines additional validation logic to apply to the final mapped user information. The expression must evaluate to true for the user to be accepted.
message Error message returned when the user validation rule fails.

Create the JWT authenticator

  • Add the JWT authenticator to your AKS cluster using the [az aks jwtauthenticator add][az-aks-jwtauthenticator-add] command.

    az aks jwtauthenticator add \
        --resource-group $RESOURCE_GROUP \
        --cluster-name $CLUSTER_NAME \
        --name external-auth \
        --config-file jwt-config.json
    

Manage JWT authenticators

List all JWT authenticators

  • List all JWT authenticators on your cluster using the [az aks jwtauthenticator list][az-aks-jwtauthenticator-list] command.

    az aks jwtauthenticator list \
        --resource-group $RESOURCE_GROUP \
        --cluster-name $CLUSTER_NAME
    

Get details for a specific JWT authenticator

  • Get details for a specific JWT authenticator using the [az aks jwtauthenticator show][az-aks-jwtauthenticator-show] command.

    az aks jwtauthenticator show \
        --resource-group $RESOURCE_GROUP \
        --cluster-name $CLUSTER_NAME \
        --name external-auth
    

Set up GitHub Actions OIDC for authentication

  1. Create environment variables for and set the following required repository secrets in your GitHub repository:

    • AKS_SERVER_URL: Your AKS cluster's API server URL.
    • AKS_CA_DATA: Base64-encoded certificate authority data for your AKS cluster.
  2. Create a workflow that obtains an OIDC token and uses it to authenticate with your AKS cluster. The following example workflow gets all pods running on the cluster:

    Note

    The audience value my-api should match the audience configured in your JWT authenticator configuration.

    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
    

Get cluster information for JWT authenticator configuration

  1. Get the API server URL for your cluster using the [az aks show][az-aks-show] command.

    az aks show --resource-group $RESOURCE_GROUP --name $CLUSTER_NAME --query "fqdn" -o tsv | \
      awk '{print "https://" $0 ":443"}'
    
  2. Get the base64-encoded certificate authority data for your cluster using the [az aks get-credentials][az-aks-get-credentials] command.

    # 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}'
    

Test authentication

  1. Trigger the workflow either by pushing to the main branch or manually triggering it from the Actions tab in your repository.

  2. 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, and use the cluster admin credentials to apply these configurations.

  1. Create a file named rbac-config.yaml to configure RBAC bindings for external users. For example:

    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
    
  2. Apply the RBAC configuration using the kubectl apply command:

    kubectl apply -f rbac-config.yaml
    

Verify access with RBAC

  • Verify the external user can now access resources according to the RBAC permissions you configured using the kubectl get nodes and kubectl get pods commands with the --user flag. For example:

    kubectl get nodes --user external-user
    kubectl get pods --user external-user
    

Remove JWT authenticator

  • When you no longer need the JWT authenticator, remove it from your AKS cluster using the [az aks jwtauthenticator delete][az-aks-jwtauthenticator-delete] command.

    az aks jwtauthenticator delete \
        --resource-group $RESOURCE_GROUP \
        --cluster-name $CLUSTER_NAME \
        --name external-auth