Service Account RBAC

What are Service Accounts in Kubernetes?

Service accounts in Kubernetes are a type of non-human account that provides an identity for processes running in pods. They serve as the Kubernetes equivalent of a system user, enabling applications within your cluster to interact with the Kubernetes API and other services while maintaining proper security boundaries.

Unlike user accounts, which are designed for human operators and administrators, service accounts are specifically intended for pods and the applications running inside them. Every pod that runs in Kubernetes is associated with a service account, using either the default service account in the namespace or a custom one that you create and configure according to your application’s needs.

How Service Accounts Work

When a pod is created in Kubernetes, it is automatically assigned a service account. If not explicitly specified, the pod will use the default service account in its namespace. The service account credentials are automatically mounted into the pod at the path /var/run/secrets/kubernetes.io/serviceaccount/ as a set of files:

  • token: A JSON Web Token (JWT) that authenticates the service account to the Kubernetes API
  • ca.crt: The certificate authority certificate used to validate the API server’s certificate
  • namespace: The current namespace

The Kubernetes control plane automatically manages these credentials, rotating the tokens and ensuring they remain valid for the lifetime of the pod. When applications inside the pod make requests to the Kubernetes API, they can use these credentials to authenticate and authorize their actions.

Role-Based Access Control for Service Accounts

Service accounts gain their permissions through Kubernetes’ Role-Based Access Control (RBAC) system. By creating Roles or ClusterRoles that define specific permissions, and binding them to service accounts via RoleBindings or ClusterRoleBindings, you establish precisely what actions the service account can perform.

This granular control allows you to implement the principle of least privilege, where each service account has only the permissions necessary to perform its function and no more. For example, a monitoring agent might need read-only access to pod metrics, while a deployment controller would need permissions to create and manage pods and other resources.

Why Use Custom Service Accounts?

There are several compelling reasons to create and use custom service accounts instead of relying on the default one:

  1. Security segregation: Using dedicated service accounts for different applications helps maintain clear security boundaries.
  2. Permission management: Custom service accounts can be granted specific permissions through RBAC, allowing fine-grained access control.
  3. Audit trail clarity: Actions performed using distinct service accounts are easier to track in audit logs.
  4. Identity for external services: When integrating with external services like cloud providers, service accounts can serve as clear identities.
  5. Secret access control: Service accounts can be associated with specific Kubernetes secrets, limiting which pods can access sensitive information.

Service Account Example

Here’s an example of a service account definition in YAML:

apiVersion: v1
kind: ServiceAccount
metadata:
  name: app-monitoring
  namespace: production
  labels:
    app: monitoring
    environment: production
  annotations:
    description: "Service account for monitoring applications in production"
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: metrics-reader
  namespace: production
rules:
- apiGroups: [""]
  resources: ["pods", "pods/status"]
  verbs: ["get", "list", "watch"]
- apiGroups: ["metrics.k8s.io"]
  resources: ["pods"]
  verbs: ["get", "list"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: monitoring-metrics-reader
  namespace: production
subjects:
- kind: ServiceAccount
  name: app-monitoring
  namespace: production
roleRef:
  kind: Role
  name: metrics-reader
  apiGroup: rbac.authorization.k8s.io

In this example, we’ve defined a Service Account named app-monitoring in the production namespace. We’ve also created a Role that grants read-only access to pod information and metrics, and a RoleBinding that associates this Role with our service account.

Service Accounts in Modern Kubernetes Environments

In more recent Kubernetes versions, the TokenRequest API is used to create time-bound tokens for service accounts. This improves security by limiting the lifetime of credentials and reducing the risk of token misuse. Additionally, with features like Pod Identity and integration with external identity providers (such as Azure Workload Identity for AKS), service accounts can be used to securely access resources outside the Kubernetes cluster.

Best Practices for Service Account Management

When working with service accounts in production environments, consider these best practices:

  • Create dedicated service accounts for each application or component
  • Apply the principle of least privilege when assigning permissions
  • Regularly audit service account permissions and remove unnecessary access
  • Use time-limited tokens and automated rotation for enhanced security
  • Consider namespace isolation to further separate privileges between environments
  • Document the purpose and permissions of each service account for better operational clarity

Service accounts are a fundamental part of Kubernetes security architecture, providing identity and access control for the workloads running in your cluster. By properly configuring and managing service accounts, you can significantly enhance the security posture of your Kubernetes applications while enabling them to interact securely with the cluster’s resources and external services.

Service Accounts and Entra ID

As we have discussed in previous sections, user access to AKS clusters should be managed through Azure Active Directory (Entra ID) for enhanced security and compliance. Kubernetes Service accounts can’t be created in Entra ID, as they are native Kubernetes resources, however they can leverage Entra ID to authenticate with Azure services using Azure Workload Identity, which we will cover in the next section. This provides a seamless and secure way to access resources without hardcoding credentials in your applications.