When deploying applications to Kubernetes, it's important to ensure they have only the permissions they actually need. This is where ServiceAccounts and RBAC (Role-Based Access Control) come into play.
In our case, the ServiceAccount is required for the Agentic CLI to authenticate with the AKS cluster when running in cluster mode.
What is a ServiceAccount?
A ServiceAccount is an identity used by applications running inside a Kubernetes cluster. Unlike user accounts, which are intended for administrators and developers, ServiceAccounts allow pods to securely authenticate with the Kubernetes API.
Applications commonly use a ServiceAccount to:
- Read Pods
- Create Jobs
- Access ConfigMaps and Secrets
- Watch Deployments
- Integrate with cloud identity providers (Azure Workload Identity, AWS IAM Roles for Service Accounts, OCI Workload Identity)
Rather than granting broad cluster-wide permissions, Kubernetes lets you assign only the permissions an application requires, following the Principle of Least Privilege.
Default ServiceAccount
Every Kubernetes namespace includes a default ServiceAccount.
kubectl get sa
Example output:
NAME SECRETS AGE
default 0 10d
If no ServiceAccount is specified in a Pod or Deployment, Kubernetes automatically uses the default ServiceAccount.
Creating a ServiceAccount
Create a file named serviceaccount.yaml:
apiVersion: v1
kind: ServiceAccount
metadata:
name: my-app-sa
namespace: alpha
Apply it:
kubectl apply -f serviceaccount.yaml
Verify it exists:
kubectl get sa -n alpha
Using a ServiceAccount in a Pod or Deployment
Reference the ServiceAccount using the serviceAccountName field.
apiVersion: v1
kind: Pod
metadata:
name: nginx
spec:
serviceAccountName: my-app-sa
containers:
- name: nginx
image: nginx
Any pod using this ServiceAccount will authenticate to the Kubernetes API as my-app-sa.
A ServiceAccount Has No Permissions by Default
Creating a ServiceAccount does not automatically grant access to Kubernetes resources.
Permissions are assigned using RBAC:
- Role + RoleBinding → Namespace-scoped permissions
- ClusterRole + ClusterRoleBinding → Cluster-wide permissions
Creating a Role
The following Role allows read-only access to Pods, Services, and Endpoints.
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
namespace: dev
name: endpoints-reader
rules:
- apiGroups: [""]
resources:
- pods
- services
- endpoints
verbs:
- get
- list
- watch
Binding the Role to the ServiceAccount
Next, bind the Role to the ServiceAccount.
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: read-access
namespace: dev
subjects:
- kind: ServiceAccount
name: my-app-sa
namespace: dev
roleRef:
kind: Role
name: endpoints-reader
apiGroup: rbac.authorization.k8s.io
After applying the Role and RoleBinding, the ServiceAccount can:
- Get Pods
- List Pods
- Watch Pods
- Get Services
- List Services
- Watch Services
- Get Endpoints
- List Endpoints
- Watch Endpoints
Nothing more.
Verifying the Role
Describe the Role to verify its permissions.
kubectl describe role endpoints-reader -n test-magik
Example output:
Name: endpoints-reader
PolicyRule:
Resources Verbs
--------- ----------------
endpoints get, list, watch
pods get, list, watch
services get, list, watch
You can also verify what a ServiceAccount is allowed to do:
kubectl auth can-i list pods \
--as=system:serviceaccount:dev:my-app-sa \
-n dev
If configured correctly, Kubernetes will return:
yes
Why This Matters
Giving every application cluster-admin privileges is a significant security risk.
Using ServiceAccounts together with RBAC enables you to:
- Grant only the permissions an application requires
- Reduce the impact of compromised workloads
- Improve Kubernetes security
- Follow the Principle of Least Privilege
- Support secure authentication for tools such as the Agentic CLI running in AKS cluster mode
Properly configured ServiceAccounts are a foundational security practice for any production Kubernetes environment.
Top comments (0)