<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Kubernetes Service Accounts on Digi Hunch</title><link>https://static.digihunch.com/tag/kubernetes-service-accounts/</link><description>Recent content in Kubernetes Service Accounts on Digi Hunch</description><generator>Hugo -- gohugo.io</generator><language>en-US</language><lastBuildDate>Wed, 02 Apr 2025 10:24:36 -0400</lastBuildDate><atom:link href="https://static.digihunch.com/tag/kubernetes-service-accounts/index.xml" rel="self" type="application/rss+xml"/><item><title>Workload Identity on Kubernetes 2 of 2 – EKS</title><link>https://static.digihunch.com/2024/01/workload-identity-on-kubernetes-2-of-2-eks-and-rosa-on-aws/</link><pubDate>Mon, 08 Jan 2024 00:05:00 -0400</pubDate><guid>https://static.digihunch.com/2024/01/workload-identity-on-kubernetes-2-of-2-eks-and-rosa-on-aws/</guid><description>&lt;img src="https://static.digihunch.com/wp-content/uploads/2025/04/feature-workload-identity-eks.webp" alt="Featured image of post Workload Identity on Kubernetes 2 of 2 – EKS" /&gt;&lt;p class="wp-block-paragraph"&gt;I discussed in my &lt;a href="https://static.digihunch.com/2023/12/workload-identity-on-kubernetes-1-of-2-aks/"&gt;previous post&lt;/a&gt; on workload identity and dived into how it works in AKS (Azure Kubernetes Service). In this post I will continue the topic with AWS as the example. From the perspective of CSP, we consider any running process on the cloud resource as workload. Therefore, I&amp;#8217;ll start with control plan and node identities. From the perspective of a Kubernetes platform, the term workload mostly refers to applications running in Pods. So later in this article I&amp;#8217;ll distinguish two mechanisms for Pod Identity: IRSA and EKS Pod Identity. &lt;/p&gt;&#10;&lt;h2 class="wp-block-heading"&gt;EKS Control Plane and Node Identity&lt;/h2&gt;&#10;&lt;p class="wp-block-paragraph"&gt;AWS directly associate an IAM role with EKS control plane and an IAM role with each node group. We don&amp;#8217;t need an extra step of assigning a &amp;#8220;managed identity&amp;#8221; (as in Azure) to a cluster or to a node group ( and then bind a role to the identity). You can find this pattern from Terraform &lt;a href="https://github.com/digihunch/cloudkube/tree/main/eks"&gt;code&lt;/a&gt;. Each &lt;code&gt;aws_eks_node_group&lt;/code&gt; resource has a &lt;code&gt;node_role_arn&lt;/code&gt; attribute to link to its IAM role, and a &lt;code&gt;cluster_name&lt;/code&gt; attribute to link to the cluster. Each &lt;code&gt;aws_eks_cluster&lt;/code&gt; resource has a &lt;code&gt;role_arn&lt;/code&gt; attribute for cluster&amp;#8217;s permission. &lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;The cluster&amp;#8217;s IAM role is usually bound to managed policies like &lt;code&gt;AmazonEKSVPCResourceController&lt;/code&gt; and &lt;code&gt;AmazonEKSClusterPolicy&lt;/code&gt;. The IAM role that is assigned to the node group is the exact IAM role of the instance profile of each node. The kubelet process on the nodes are the main users of this role and the permission should not be broader than what it needs to do. This role usually have a few managed policies such as &lt;code&gt;AmazonEKSWorkerNodePolicy&lt;/code&gt;, &lt;code&gt;AmazonEKS_CNI_Policy&lt;/code&gt;, &lt;code&gt;AmazonSSMManagedInstanceCore&lt;/code&gt; and &lt;code&gt;AmazonEC2ContainerRegistryReadOnly&lt;/code&gt;. &lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;The node role applies to self-managed node and managed node. When using Fargate to provide computing capacity, each Fargate profile will use its own IAM role, to connect to the cluster and pull container images. This IAM role is known as Pod Execution Role. For a private cluster, the place to run the command would be a bastion host with connectivity to the cluster&amp;#8217;s API endpoint. Refer to &lt;a href="https://static.digihunch.com/2023/06/connect-kubectl-to-private-kubernetes-cluster-in-eks-and-aks/"&gt;this&lt;/a&gt; post about the connectivity to private cluster.&lt;/p&gt;&#10;&lt;h2 class="wp-block-heading"&gt;IAM Role for Service Account (IRSA)&lt;/h2&gt;&#10;&lt;p class="wp-block-paragraph"&gt;When AWS launched EKS in 2018, &lt;a href="https://github.com/uswitch/kiam"&gt;Kiam&lt;/a&gt; was a popular open-source project to grant Pods access to AWS resources. In 2019, AWS &lt;a href="https://aws.amazon.com/blogs/opensource/introducing-fine-grained-iam-roles-service-accounts/"&gt;introduced the official mechanism&lt;/a&gt;, IRSA (IAM Role for Service Account). IRSA ties a Kubernetes identity (in the form of Service Account) to an IAM role in AWS. IAM allows creation of web identity based on OIDC. EKS can act as an OIDC issuer. &lt;/p&gt;&#10;&lt;div class="wp-block-image"&gt;&#10;&lt;figure class="aligncenter size-full is-resized"&gt;&lt;img loading="lazy" decoding="async" width="1024" height="545" src="https://static.digihunch.com/wp-content/uploads/2024/01/eks-oidc.webp" alt="" class="wp-image-12976" style="width:458px;height:auto" srcset="https://static.digihunch.com/wp-content/uploads/2024/01/eks-oidc.webp 1024w, https://static.digihunch.com/wp-content/uploads/2024/01/eks-oidc-300x160.webp 300w, https://static.digihunch.com/wp-content/uploads/2024/01/eks-oidc-768x409.webp 768w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /&gt;&lt;/figure&gt;&#10;&lt;/div&gt;&#10;&lt;p class="wp-block-paragraph"&gt;This requires a few points of configurations, via the cluster API and via cloud the endpoint. The &lt;code&gt;eksctl&lt;/code&gt; utility makes it simple with two commands:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;$ eksctl utils associate-iam-oidc-provider \&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; --cluster $CLUSTER_NAME \&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; --approve&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;$ eksctl create iamserviceaccount \&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; --cluster=$CLUSTER_NAME \&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; --namespace=kube-system \&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; --name=aws-load-balancer-controller \&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; --role-name AmazonEKSLoadBalancerControllerRole \&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; --attach-policy-arn=arn:aws:iam::112233445566:policy/AWSLoadBalancerControllerIAMPolicy \&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; --approve&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p class="wp-block-paragraph"&gt; The first command creates an OIDC web identity integrated with the EKS cluster, and the second creates a Service Account in Kubernetes and links it to the identity, and assign an IAM policy. These two commands must run under certain conditions. The AWS CLI identity for first command requires the the permission to add OIDC provider. The second needs the permission to create an IAM role. In addition, it requires kube API access to the cluster. So the command needs to run from an environment that can access both the cluster&amp;#8217;s API and AWS API. &lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;The IAM identity provider is somewhat similar to a managed identity with OIDC federated credential in Azure. However, unlike managed identity, here in AWS we cannot create the OIDC identity until after the cluster creation. In other words, the OIDC web identity&amp;#8217;s lifecycle does not decouple with the cluster lifecycle. We have to create a new web identity every time we create a new EKS cluster. In large organizations, the permission to create a new web identity is highly restricted.&lt;/p&gt;&#10;&lt;h2 class="wp-block-heading"&gt;EKS Pod Identity&lt;/h2&gt;&#10;&lt;p class="wp-block-paragraph"&gt;There are a few other limitations with IRSA. As &lt;a href="https://aws.amazon.com/blogs/containers/amazon-eks-pod-identity-a-new-way-for-applications-on-eks-to-obtain-iam-credentials/"&gt;this&lt;/a&gt; blog post suggests:&lt;/p&gt;&#10;&lt;blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow"&gt;&#10;&lt;p class="wp-block-paragraph"&gt;Further, cluster administrators have to update the IAM role trust policy each time the role is used in a new cluster during scenarios like blue-green upgrades or failover testing. Additionally, as customers grow their EKS cluster footprint, due to the per cluster OIDC provider requirement in IRSA, customers run into the per account OIDC provider limit. Similarly, as they scale the number of clusters or Kubernetes namespaces in which an IAM role is used, they run into IAM trust policy size limit, which makes them duplicate the IAM roles to overcome the trust policy size limit.&lt;/p&gt;&#10;&lt;/blockquote&gt;&#10;&lt;p class="wp-block-paragraph"&gt;AWS brings the new mechanism &amp;#8220;&lt;em&gt;&lt;a href="https://docs.aws.amazon.com/eks/latest/userguide/pod-identities.html"&gt;EKS Pod Identity&lt;/a&gt;&lt;/em&gt;&amp;#8221; at reInvent 2023. In this mechanism, user can hook up an IAM role directly to a Kubernetes service account, without having to resort to a web identity and OIDC integration. Users just need to create a Pod Identity Association, using the CreatePodIdentityAssociation API, with the following parameters:&lt;/p&gt;&#10;&lt;ul class="wp-block-list"&gt;&#10;&lt;li&gt;Cluster name&lt;/li&gt;&#10;&lt;li&gt;Namespace&lt;/li&gt;&#10;&lt;li&gt;ARN of the IAM role&lt;/li&gt;&#10;&lt;li&gt;serviceAccount &lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p class="wp-block-paragraph"&gt;Both &lt;a href="https://docs.aws.amazon.com/cli/latest/reference/eks/create-pod-identity-association.html"&gt;AWS CLI&lt;/a&gt; and &lt;a href="https://eksctl.io/usage/pod-identity-associations/"&gt;ekscli&lt;/a&gt; already support the CreatePodIdentityAssociation API. Before creating a Pod Identity Association, we need to install the add-on &amp;#8220;Amazon EKS Pod Identity Agent&amp;#8221;, and ensure that the &lt;a href="https://docs.aws.amazon.com/eks/latest/userguide/pod-id-agent-setup.html"&gt;node roles&lt;/a&gt; have the permission. That is because the agent needs to use AssumeRoleForPodIdentity API. We also need an IAM role, with the trust policy principal being &amp;#8220;&lt;em&gt;&lt;strong&gt;pods.eks.amazonaws.com&lt;/strong&gt;&lt;/em&gt;&amp;#8221; and our own choice of &lt;a href="https://docs.aws.amazon.com/IAM/latest/UserGuide/access_tags.html"&gt;resource tags&lt;/a&gt; as condition. Note that another implicit prerequisite is that the programming running in the Pod use a newer version of AWS SDK to access cloud resource. &lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;&lt;a href="https://aws.amazon.com/blogs/containers/amazon-eks-pod-identity-a-new-way-for-applications-on-eks-to-obtain-iam-credentials/"&gt;This&lt;/a&gt; blog post has good details, including a diagram and a walk-through. &lt;/p&gt;&#10;&lt;h2 class="wp-block-heading"&gt;Comparison&lt;/h2&gt;&#10;&lt;p class="wp-block-paragraph"&gt;Both EKS Pod Identity and IRSA are here to stay. I&amp;#8217;m afraid this is going to create confusions. I put the following table for their comparision:&lt;/p&gt;&#10;&lt;figure class="wp-block-table is-style-stripes"&gt;&lt;table class="has-white-background-color has-background"&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;&lt;/th&gt;&lt;th&gt;IRSA&lt;/th&gt;&lt;th&gt;EKS Pod Identity&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;Pros&lt;/td&gt;&lt;td&gt;&amp;#8211; in use since 2019&lt;br&gt;&amp;#8211; support EKS, EKS-A, ROSA&lt;br&gt;&amp;#8211; support all EKS versions&lt;/td&gt;&lt;td&gt;&amp;#8211; support role session tags&lt;br&gt;&amp;#8211; no dependency on OIDC identity provider&lt;br&gt;&amp;#8211; create an IAM role once for all clusters. the role can be created before cluster&lt;br&gt;&amp;#8211; cross account access through resource policies and chained AssumeRole operation&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Cons&lt;/td&gt;&lt;td&gt;&amp;#8211; Cannot create OIDC identity provider, until the cluster is ready&lt;br&gt;&amp;#8211; One OIDC provider per cluster, with the risk of hitting quota&lt;br&gt;&amp;#8211; Trust policy sprawl as more clusters are created&lt;/td&gt;&lt;td&gt;&amp;#8211; the program has to use newer version of SDK. &lt;br&gt;&amp;#8211; ony support EKS&lt;br&gt;&amp;#8211; Pod Identity Agent (DaemonSet) can&amp;#8217;t run on Fargate&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;figcaption class="wp-element-caption"&gt;Compairing IRSA with EKS Pod Identity&lt;/figcaption&gt;&lt;/figure&gt;&#10;&lt;p class="wp-block-paragraph"&gt;The blog &lt;a href="https://aws.amazon.com/blogs/containers/amazon-eks-pod-identity-a-new-way-for-applications-on-eks-to-obtain-iam-credentials/"&gt;post&lt;/a&gt; also contains a long table for their comparison. In the near future, I will have to check the &lt;a href="https://docs.aws.amazon.com/eks/latest/userguide/pod-id-minimum-sdk.html"&gt;SDK version&lt;/a&gt; of a workload in order to assess whether EKS Pod Identity will function. This is a restriction because it depends upon software builder disclosing the SDK version used. The EKS cluster also needs to host daemonSet on a node agent. On the other hand, go with IRSA if portability between EKS and EKS-A and &lt;a href="https://static.digihunch.com/2023/06/kubernetes-paas-and-red-hat-openshift/"&gt;ROSA&lt;/a&gt; is of concern, because the IAM service principal &lt;em&gt;pods.eks.amazonaws.com&lt;/em&gt; is dedicated to EKS. &lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;The blog post also gives the migration step as follows:&lt;/p&gt;&#10;&lt;ol class="wp-block-list"&gt;&#10;&lt;li&gt;Ensure EKS cluster is above 1.24, and install the add-on for EKS pod identity agent. &lt;/li&gt;&#10;&lt;li&gt;Ensure the SDK running in pod meets the version requirement. &lt;/li&gt;&#10;&lt;li&gt;Update the IAM role&amp;#8217;s trust policy with the new principal &amp;#8220;pods.eks.amazonaws.com&amp;#8221;&lt;/li&gt;&#10;&lt;/ol&gt;&#10;&lt;p class="wp-block-paragraph"&gt;So the EKS Pod Identity mechanism still requires an IAM role. It does not required an OIDC identity. The service account connects to IAM role via an agent on the node. &lt;/p&gt;&#10;&lt;h2 class="wp-block-heading"&gt;Summary&lt;/h2&gt;&#10;&lt;p class="wp-block-paragraph"&gt;A good design concerns not only functionality, but also streamlined configuration experience. EKS Pod Identity is a great improvement over IRSA heading the right direction. It just came out two months ago so still too early to adopt, especially without knowing the workload details. For now I tend to use pod identity as a backup mechanism when IRSA isn&amp;#8217;t available for some reason. However, I recommend starting to introduce the Pod Identity mechanism for all new EKS clusters and new workloads.&lt;/p&gt;&#10;&lt;nav class="wp-post-navigation" aria-label="Post navigation"&gt;&#10;&lt;a rel="prev" href="https://static.digihunch.com/2023/12/workload-identity-on-kubernetes-1-of-2-aks/"&gt;&lt;span class="wp-post-navigation-label"&gt;Previous Post&lt;/span&gt;&lt;strong class="wp-post-navigation-title"&gt;Workload Identity on Kubernetes 1 of 2 – AKS&lt;/strong&gt;&lt;/a&gt;&#10;&lt;a rel="next" href="https://static.digihunch.com/2024/02/public-key-infrastructure-1-of-3-basics/"&gt;&lt;span class="wp-post-navigation-label"&gt;Next Post&lt;/span&gt;&lt;strong class="wp-post-navigation-title"&gt;Public Key Infrastructure 1 of 3 – Basics&lt;/strong&gt;&lt;/a&gt;&#10;&lt;/nav&gt;&#10;</description></item><item><title>Workload Identity on Kubernetes 1 of 2 – AKS</title><link>https://static.digihunch.com/2023/12/workload-identity-on-kubernetes-1-of-2-aks/</link><pubDate>Sat, 23 Dec 2023 16:43:00 -0400</pubDate><guid>https://static.digihunch.com/2023/12/workload-identity-on-kubernetes-1-of-2-aks/</guid><description>&lt;img src="https://static.digihunch.com/wp-content/uploads/2025/04/feature-workload-identity-aks.webp" alt="Featured image of post Workload Identity on Kubernetes 1 of 2 – AKS" /&gt;&lt;p class="wp-block-paragraph"&gt;As applications are moved to the cloud, the application workload hosted on virtual machines need to interact with cloud resources. For this, we need an IAM solution with two mechanisms:&lt;/p&gt;&#10;&lt;ul class="wp-block-list"&gt;&#10;&lt;li&gt;a (non-human) identity in the cloud service platform (CSP), to represent the application;&lt;/li&gt;&#10;&lt;li&gt;a way to grant permission to this identity, so it can manage resources&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p class="wp-block-paragraph"&gt;CSPs such as Azure and AWS have their own implementations of the two mechanism. In Azure, we have Entra workload identity (including service principal and managed identity) for the first mechanism, and Azure roles for the second. On AWS, they are the identity pool capability of Amazon Cognito and IAM role. Next, what about the workload on managed Kubernetes service? Essentially, we will need to more mechanisms:&lt;/p&gt;&#10;&lt;ol class="wp-block-list"&gt;&#10;&lt;li&gt;a native Kubernetes identity to represent the workload (Pod);&lt;/li&gt;&#10;&lt;li&gt;a way to map the Kubernetes identity to the identity in CSP&lt;/li&gt;&#10;&lt;/ol&gt;&#10;&lt;p class="wp-block-paragraph"&gt;Kubernetes Service Account is designed for the first item. The second mechanism is for the CSP to address. In this post, let&amp;#8217;s examine this in Azure. Specifically, how does Azure manage workload identity with Azure Kubernetes Service (AKS). &lt;/p&gt;&#10;&lt;h2 class="wp-block-heading"&gt;Node Identity and Cluster Identity in AKS&lt;/h2&gt;&#10;&lt;p class="wp-block-paragraph"&gt;Let&amp;#8217;s define what exactly is a workload identity. In Azure we think of it as one type of non-human identity. In our context, workload identity in the broader sense contains:&lt;/p&gt;&#10;&lt;ol class="wp-block-list"&gt;&#10;&lt;li&gt;the identity that represents the control plane (or the whole cluster)&lt;/li&gt;&#10;&lt;li&gt;the identity that represents the node (or kubelet process)&lt;/li&gt;&#10;&lt;li&gt;the identity that represents the application in a Pod (workload identity in the narrow sense);&lt;/li&gt;&#10;&lt;/ol&gt;&#10;&lt;p class="wp-block-paragraph"&gt;So it is important not to confuse these identities. In this section, I&amp;#8217;ll focus on 1 and 2 since they are part of workload identity in the broad sense. In the rest of the sections, I&amp;#8217;ll discuss 3, and use the narrow sense of workload identity. &lt;/p&gt;&#10;&lt;figure class="wp-block-image size-full"&gt;&lt;img loading="lazy" decoding="async" width="934" height="322" src="https://static.digihunch.com/wp-content/uploads/2023/12/aks-identity.webp" alt="" class="wp-image-12970" srcset="https://static.digihunch.com/wp-content/uploads/2023/12/aks-identity.webp 934w, https://static.digihunch.com/wp-content/uploads/2023/12/aks-identity-300x103.webp 300w, https://static.digihunch.com/wp-content/uploads/2023/12/aks-identity-768x265.webp 768w" sizes="auto, (max-width: 934px) 100vw, 934px" /&gt;&lt;/figure&gt;&#10;&lt;p class="wp-block-paragraph"&gt;When we create an AKS cluster, we create both a cluster control plane and a node pool. Both the control plane and the nodes need to provision cloud resources using Cloud API from Azure. For example, if we use Terraform&amp;#8217;s AzureRM provider to create an &lt;code&gt;azurerm_kubernetes_cluster&lt;/code&gt; resource, then we specify the cluster&amp;#8217;s identity using &lt;code&gt;service_principal&lt;/code&gt; or &lt;code&gt;identity&lt;/code&gt; block. We specify the nodes&amp;#8217; identity using the &lt;code&gt;kubelet_identity&lt;/code&gt; block, because &lt;code&gt;kubelet&lt;/code&gt; is the process that runs on each node. &lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;Even though a cluster builder might be tempted to assign the same identity to both Control plane and kubelet, the security best practice is to keep them separated. It is also the responsibility of the cluster builder to distinguish activities by the control plane and by kubelet process on each node, and attache an Azure Role with minimum privilege to each of the identities.&lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;These two types of identities (control plane and kubelet) are relatively straightforward. In order to use them, we don&amp;#8217;t have to play with Kubernetes objects. In the next section, we&amp;#8217;ll continue to discuss the identities that represents each Pod in Azure. We now refer to them as workload identities, but the first available technology was pod managed identity.&lt;/p&gt;&#10;&lt;h2 class="wp-block-heading"&gt;Pod Managed Identity in AKS&lt;/h2&gt;&#10;&lt;p class="wp-block-paragraph"&gt;When I first worked on &lt;a href="https://static.digihunch.com/2021/12/aks-lessons-learned-2-of-2/"&gt;Azure Kubernetes&lt;/a&gt;, Pod managed identity was in preview and was the recommendation. However, Microsoft renamed it (to &lt;a href="https://learn.microsoft.com/en-us/azure/aks/use-azure-ad-pod-identity"&gt;Microsoft Entra pod-managed identities&lt;/a&gt;) and then deprecated it after a couple years of preview. As of Oct 2022, the recommended mechanism becomes Microsoft Entra Workload ID. For simplicity, we refer to the deprecated mechanism as &amp;#8220;Pod Identity&amp;#8221;. We discuss pod identity only for the purpose of understanding why it is no longer recommended and what is missing in it. For new workload deployment, we should always use workload identity. &lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;For Pod Identity to work, a&lt;a href="https://learn.microsoft.com/en-us/azure/aks/use-azure-ad-pod-identity#register-the-enablepodidentitypreview-feature-flag"&gt; feature flag&lt;/a&gt; &lt;code&gt;EnablePodIdentityPreview&lt;/code&gt; must turn on. Pod Managed Identity &lt;a href="https://learn.microsoft.com/en-us/azure/aks/use-azure-ad-pod-identity#operation-mode-options"&gt;operates&lt;/a&gt; on a Kubernetes &lt;a href="https://static.digihunch.com/2022/04/kubernetes-operator/"&gt;controller&lt;/a&gt; called MIC (Managed Identity Controller) and a DaemonSet called NMI (Node Managed identity). You start with an Azure managed identity with appropriate roles. Once you installed Pod Identity, there will be two CRDs &lt;code&gt;AzureIdentity&lt;/code&gt; and &lt;code&gt;AzureIdentityBinding&lt;/code&gt;. To grant Azure permissions to a Pod, you create a CR for each CRD. The &lt;code&gt;AzureIdentity&lt;/code&gt; CR connects to your Azure managed identity. You also create an &lt;code&gt;AzureIdentityBindign&lt;/code&gt; CR. When declaring a Pod, you link to AzureIdentityBinding by using the label aadpodidbinding. &lt;/p&gt;&#10;&lt;div class="wp-block-image"&gt;&#10;&lt;figure class="aligncenter size-full is-resized"&gt;&lt;img loading="lazy" decoding="async" width="1024" height="508" src="https://static.digihunch.com/wp-content/uploads/2023/12/aks-pod-mgd-identity.webp" alt="" class="wp-image-12971" style="width:663px;height:auto" srcset="https://static.digihunch.com/wp-content/uploads/2023/12/aks-pod-mgd-identity.webp 1024w, https://static.digihunch.com/wp-content/uploads/2023/12/aks-pod-mgd-identity-300x149.webp 300w, https://static.digihunch.com/wp-content/uploads/2023/12/aks-pod-mgd-identity-768x381.webp 768w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /&gt;&lt;/figure&gt;&#10;&lt;/div&gt;&#10;&lt;p class="wp-block-paragraph"&gt;There are two problems with pod managed identity. First, there is a &lt;a href="https://learn.microsoft.com/en-us/azure/aks/use-azure-ad-pod-identity#using-kubenet-network-plugin-with-microsoft-entra-pod-managed-identities"&gt;vulnerability&lt;/a&gt; when it works with kubenet as network plugin. This vulnerability requires an additional &lt;a href="https://learn.microsoft.com/en-us/azure/aks/use-azure-ad-pod-identity#mitigation"&gt;mitigation step&lt;/a&gt;. Second, it does not make use of Kubernete&amp;#8217;s Service Account. Let&amp;#8217;s discuss in the next section why it&amp;#8217;s favourable to use Kubernetes&amp;#8217; ServiceAccount. &lt;/p&gt;&#10;&lt;h2 class="wp-block-heading"&gt;Kubernetes Service Account&lt;/h2&gt;&#10;&lt;p class="wp-block-paragraph"&gt;In Kubernetes RBAC model, &lt;a href="https://kubernetes.io/docs/concepts/security/service-accounts/"&gt;Service Account&lt;/a&gt; can bind to Roles to gain access to other Kubernetes resources. The most common use case is allowing the running application in a Pod to access other Kubernetes resources. When it comes to letting an application in Pod access cloud resources in the CSP, it makes sense to use Service Account, for a a consistent pattern.&lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;A service account must carry a token to function. Each namespace has a default service account with the token mounted automatically. Each Pod created in a namespace uses the default service account of the namespace, unless otherwise specified. However, many security organizations do not considered this default behaviour as the best practice. For example, CIS Kubernetes &lt;a href="https://www.cisecurity.org/benchmark/kubernetes"&gt;benchmark&lt;/a&gt; 1.8 has these two recommendations:&lt;/p&gt;&#10;&lt;ul class="wp-block-list"&gt;&#10;&lt;li&gt;Ensure that the default service accounts are not actively used (5.1.5)&lt;/li&gt;&#10;&lt;li&gt;Ensure that Service Account Tokens are only mounted where necessary (5.1.6)&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p class="wp-block-paragraph"&gt;In other words, we should create non-default service account with &lt;strong&gt;automountServiceAccountToken&lt;/strong&gt; set to false. Then when declaring a Pod, we explicitly specify the service account and where to grab the token for the service account. One way to pass ServiceAccount token is through &lt;a href="https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/#serviceaccount-token-volume-projection"&gt;volume projection&lt;/a&gt;. &lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;To allow a Pod to access Azure resources, we use the combination of Kubernetes Service Account and Microsoft Entra workload identity. &lt;/p&gt;&#10;&lt;h2 class="wp-block-heading"&gt;Workload Identity for AKS&lt;/h2&gt;&#10;&lt;p class="wp-block-paragraph"&gt;Microsoft introduced Entra Workload Identities in late 2022 to address IAM issues around machine identities. It comes with some modern features such as conditional access (e.g. location-based access, anomaly sign-in detection, etc). A &lt;a href="https://learn.microsoft.com/en-us/entra/workload-id/workload-identities-overview"&gt;workload identity&lt;/a&gt; can be:&lt;/p&gt;&#10;&lt;ul class="wp-block-list"&gt;&#10;&lt;li&gt;application: an abstract entity as the global representation of your application for use across all tenants;&lt;/li&gt;&#10;&lt;li&gt;service principal: the local representation of a global application object in a specific tenants;&lt;/li&gt;&#10;&lt;li&gt;managed identity: a special type of service principal that eliminates the need for developers to manage credentials&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p class="wp-block-paragraph"&gt;In our use case for AKS workload, we also make use of Azure&amp;#8217;s Managed Identity. This part is the same as the pod identity mechanism. However, here we create a federated identity credential for managed identity. The OIDC federated identity credential is issued by the AKS cluster. Within the AKS, the service account references the identity by client_id. &lt;a href="https://learn.microsoft.com/en-us/azure/aks/workload-identity-deploy-cluster"&gt;Here&lt;/a&gt; is the documentation for the whole process.&lt;/p&gt;&#10;&lt;figure class="wp-block-image size-full"&gt;&lt;img loading="lazy" decoding="async" width="1024" height="588" src="https://static.digihunch.com/wp-content/uploads/2023/12/aks-workload-identity.webp" alt="" class="wp-image-12972" srcset="https://static.digihunch.com/wp-content/uploads/2023/12/aks-workload-identity.webp 1024w, https://static.digihunch.com/wp-content/uploads/2023/12/aks-workload-identity-300x172.webp 300w, https://static.digihunch.com/wp-content/uploads/2023/12/aks-workload-identity-768x441.webp 768w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /&gt;&lt;/figure&gt;&#10;&lt;p class="wp-block-paragraph"&gt;One of the improvements in Entra workload identity for AKS, is the use of service account, which obviates the use of CRDs. Another improvement is the use of federated identity, whose lifecycle is tied to the cluster. This pattern is not only neater, but also standard. We map a service account to a managed identity with federated credential. &lt;/p&gt;&#10;&lt;h2 class="wp-block-heading"&gt;Summary&lt;/h2&gt;&#10;&lt;p class="wp-block-paragraph"&gt;On managed Kubernetes services, we need an integration mechanism to grant Kubernetes workload access to cloud resources. We discussed what&amp;#8217;s needed in this integration mechanism and looked at Azure Kubernetes as an example. In the next post, we&amp;#8217;ll discuss how this issue is addressed in Elastic Kubernetes Service on the AWS side.&lt;/p&gt;&#10;&lt;nav class="wp-post-navigation" aria-label="Post navigation"&gt;&#10;&lt;a rel="prev" href="https://static.digihunch.com/2023/11/wordpress-security/"&gt;&lt;span class="wp-post-navigation-label"&gt;Previous Post&lt;/span&gt;&lt;strong class="wp-post-navigation-title"&gt;WordPress Security Basics&lt;/strong&gt;&lt;/a&gt;&#10;&lt;a rel="next" href="https://static.digihunch.com/2024/01/workload-identity-on-kubernetes-2-of-2-eks-and-rosa-on-aws/"&gt;&lt;span class="wp-post-navigation-label"&gt;Next Post&lt;/span&gt;&lt;strong class="wp-post-navigation-title"&gt;Workload Identity on Kubernetes 2 of 2 – EKS&lt;/strong&gt;&lt;/a&gt;&#10;&lt;/nav&gt;&#10;</description></item></channel></rss>