Give applications and automation the permissions their work requires, rather than distributing the administrator kubeconfig. This part treats API authorization, Pod network access, and container execution settings as separate controls, then tests each boundary in the lab.
Table of Contents
1. Read-only ServiceAccount·Role
Save it as ~/k8s-lab/app/rbac-reader.yaml in cp01. ServiceAccount is the API subject used by workloads, etc., and this account does not use automatic token mount.
apiVersion: v1
kind: ServiceAccount
metadata:
name: lab-reader
namespace: lab
automountServiceAccountToken: false
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: workload-reader
namespace: lab
rules:
- apiGroups: [""]
resources: [pods, services]
verbs: [get, list, watch]
- apiGroups: [apps]
resources: [deployments]
verbs: [get, list, watch]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: lab-reader-binding
namespace: lab
subjects:
- kind: ServiceAccount
name: lab-reader
namespace: lab
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: workload-reader
kubectl apply -f ~/k8s-lab/app/rbac-reader.yaml
kubectl auth can-i list pods -n lab \
--as=system:serviceaccount:lab:lab-reader
kubectl auth can-i get secrets -n lab \
--as=system:serviceaccount:lab:lab-reader
kubectl auth can-i delete deployments -n lab \
--as=system:serviceaccount:lab:lab-reader
Check if the output is yes, no, then no. This is a test in which the administrator checks authority judgment through impersonation. We have not tested the authentication process of actually logging in with the ServiceAccount token. To read the log, you also need separate permissions for subresources such as pods/log.
Role is namespace scoped and ClusterRole is also used to define cluster scoped permissions. You can also connect ClusterRole to a namespace using RoleBinding. Don’t just look at the name, but see what binding connects where. Reading Secrets or creating Pods can lead to privilege escalation, so grant only the scope you need.
2. Automatic token unmount
Static web servers do not need access to the Kubernetes API. Add the value below to spec.template.spec of web-deployment.yaml and apply again.
automountServiceAccountToken: false
kubectl apply -f ~/k8s-lab/app/web-deployment.yaml
kubectl -n lab rollout status deployment/web --timeout=180s
For automation that requires API access, TokenRequest-based short-lived tokens and necessary roles are used. We don’t put admin kubeconfig or non-expiring legacy tokens into Pods by default. Tokens are not recorded in public examples, issues, or terminal history.
3. Ingress NetworkPolicy
The policy limits incoming connections to the app=web Pod. Windows NodePort may also be blocked after application. Since this is an intentional blocking test, we will continue to check permission and organize policies below. During this process, Calico applies rules to the Pod’s packet paths.
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: web-default-deny
namespace: lab
spec:
podSelector:
matchLabels:
app: web
policyTypes: [Ingress]
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: web-allow-trusted
namespace: lab
spec:
podSelector:
matchLabels:
app: web
policyTypes: [Ingress]
ingress:
- from:
- podSelector:
matchLabels:
role: trusted
ports:
- protocol: TCP
port: 8080
Save it as web-networkpolicy.yaml and run it. Just use from’s podSelector to select from the same namespace. NetworkPolicy’s allow rules are combined, so connections allowed by other policies are not canceled by the default blocking policy.
kubectl apply -f ~/k8s-lab/app/web-networkpolicy.yaml
kubectl -n lab run trusted --image=busybox:1.37.0 \
--labels=role=trusted --restart=Never --command -- sleep 3600
kubectl -n lab run stranger --image=busybox:1.37.0 \
--restart=Never --command -- sleep 3600
kubectl -n lab wait --for=condition=Ready pod/trusted pod/stranger --timeout=120s
kubectl -n lab exec trusted -- wget -T 3 -qO- http://web/
kubectl -n lab exec stranger -- wget -T 3 -qO- http://web/
Test with a new connection instead of an existing connection to see if the trusted receives the page and the stranger fails to connect within the timeout period. The example limits only Ingress. If you add default egress blocking later, you will need to allow CoreDNS’s UDP/TCP 53 and external dependencies separately. Policy enforcement depends on CNI support, in this case Calico.
4. Policy Organization and Pod Security
kubectl -n lab delete pod trusted stranger
kubectl -n lab delete networkpolicy web-default-deny web-allow-trusted
Now check the NodePort connection on Windows again. The next level of restriction policy is based on Pods with non-privileged execution conditions, like Web Deployment in Part 5. If you reverse the order and apply them first, the default busybox check Pod creation you just used may be rejected.
kubectl label namespace lab \
pod-security.kubernetes.io/enforce=restricted \
pod-security.kubernetes.io/enforce-version=v1.36 \
pod-security.kubernetes.io/warn=restricted \
pod-security.kubernetes.io/warn-version=v1.36 \
--overwrite
kubectl apply --dry-run=server -f ~/k8s-lab/app/volume-check.yaml
The restricted criteria restricts the use of host namespaces, privilege elevation, capabilities, etc. Instead of terminating the existing Pod immediately, it inspects the next create/change request. This is tested only in the lab as batch application to the system namespace may block required components.
5. Differences in authority, communication, and execution restrictions
| device | controlling | Confirmation of this exercise |
|---|---|---|
| RBAC | What you can do with the API | Pod lookup yes, Secret lookup no |
| NetworkPolicy | L3/L4 communication of selected Pod | Only trusted access to Web 8080 |
| Pod Security Admission | Security conditions when creating a pod | Verification of non-privileged execution conditions |
RBAC grants API permissions and NetworkPolicy restricts communication. They do not protect against app vulnerabilities or administrator credential leaks. Identifying which restrictions are applied to which path is also helpful when diagnosing connection failures.
reference material
- RBAC Permission Design
- RBAC Operational Recommendations
- NetworkPolicy
- Pod Security Standards
- ServiceAccount and API access
official documents and distribution files confirmed: October 18, 2026. The output is an example to determine completion and may vary depending on the environment.



