Kubernetes Security: The 4Cs, RBAC, Secrets, and Pod Security Admission
Kubernetes security is organized around the 4Cs of Cloud Native Security: Cloud, Cluster, Container, and Code, four nested layers where each inner layer depends on the security of the layers around it. That defense-in-depth frame organizes everything else the KCNA exam asks about security: RBAC and ServiceAccounts grant workloads the least privilege they need, Secrets hold sensitive data but are only base64-encoded by default, Pod Security Admission enforces standards on what Pods may do, securityContext hardens individual containers, NetworkPolicies restrict traffic, and supply-chain practices such as image scanning and signing protect what you ship. The exam stays foundational: it asks what each control is, which layer it belongs to, and which statement about it is true, for example that PodSecurityPolicy was removed in Kubernetes 1.25 and replaced by Pod Security Admission. This lesson covers each control at exactly that recognition depth.
On this page7 sections
- The 4Cs: defense in depth for cloud native systems
- RBAC and ServiceAccounts: least privilege in the cluster
- Secrets vs ConfigMaps: base64 is not encryption
- Pod Security Admission: Privileged, Baseline, Restricted
- Hardening containers with securityContext
- NetworkPolicy as a security control
- Admission control and supply chain security
- Name the 4Cs of Cloud Native Security and explain why they form defense in depth
- Apply least-privilege thinking to RBAC Roles, bindings, and ServiceAccounts
- State how Secrets are stored by default and how encryption at rest is enabled
- Distinguish the Privileged, Baseline, and Restricted Pod Security Standards
- Recognize the core securityContext hardening fields and what each prevents
- Explain how admission control, image scanning, signing, and SBOMs secure the supply chain
The 4Cs: defense in depth for cloud native systems
The 4Cs of Cloud Native Security model a system as four nested layers: Cloud, Cluster, Container, Code. Your code runs inside a container, the container runs inside a cluster, and the cluster runs on a cloud or datacenter. Each layer can only be as secure as the layers outside it allow: flawless application code does not help if the cluster's API server is open to the internet, and a hardened cluster does not help if the cloud account credentials leak.
| Layer | What it covers | Example controls |
|---|---|---|
| Cloud | The infrastructure the cluster runs on | Network perimeter, IAM for cloud accounts, restricting access to control plane machines |
| Cluster | Kubernetes itself and its configuration | RBAC, Pod Security Admission, NetworkPolicies, encrypting Secrets at rest, securing etcd |
| Container | The images and runtime settings of workloads | Image scanning, minimal base images, non-root users, dropped capabilities |
| Code | The application you wrote | Dependency scanning, static analysis, TLS between services, input validation |
The point of the model is defense in depth: no single control is trusted to hold, so each layer adds its own protections and an attacker must defeat several independent barriers. On the exam, the 4Cs appear in two ways: naming the four layers, and classifying a given control into its layer. Practice the second form, because most of the controls in this lesson are Cluster-layer or Container-layer answers.
RBAC and ServiceAccounts: least privilege in the cluster
Every request to the Kubernetes API is first authenticated (who are you?) and then authorized (are you allowed to do this?). The standard authorization mechanism is Role-Based Access Control (RBAC). RBAC has four objects in a clean two-by-two: a Role grants permissions within one namespace, a ClusterRole grants them cluster-wide, and a RoleBinding or ClusterRoleBinding attaches those permissions to subjects: users, groups, or ServiceAccounts. Permissions are expressed as verbs on resources, such as get and list on pods.
RBAC is purely additive: rules only ever allow, and there is no deny rule. Anything not granted is refused. That design makes least privilege the operating principle: grant the narrowest verbs, on the narrowest resources, in the narrowest scope that lets the subject do its job. A deployment pipeline that only updates Deployments in the shop namespace should hold a Role in that namespace, not a ClusterRoleBinding to cluster-admin, which is the canonical example of excessive privilege.
Humans are not the only subjects. A ServiceAccount is the identity a Pod uses when its processes call the Kubernetes API. Every namespace has a default ServiceAccount, and every Pod runs as one, with a token that can be mounted into the container. The security lens: most applications never call the Kubernetes API, so they need no API permissions at all, and mounting the token can be disabled with automountServiceAccountToken: false. Workloads that do need API access should get a dedicated ServiceAccount bound to a minimal Role, so a compromised container yields as little power as possible.
Secrets vs ConfigMaps: base64 is not encryption
Kubernetes offers two objects for injecting configuration into Pods. A ConfigMap holds non-sensitive settings; a Secret holds sensitive data such as passwords, API tokens, and TLS keys. Both can be delivered to containers as environment variables or as files in a mounted volume. The exam's favorite fact sits in the storage column below.
| Aspect | ConfigMap | Secret |
|---|---|---|
| Intended contents | Non-sensitive configuration | Credentials, tokens, keys |
| Storage encoding | Plain text | base64-encoded, not encrypted by default |
| Encryption at rest | Not typical | Possible via EncryptionConfiguration on the API server |
| Delivery to Pods | Env vars or volume files | Env vars or volume files |
base64 is an encoding, not encryption. Anyone who can read the Secret object can decode its values with one command, and by default Secrets sit in etcd unencrypted. Real protection comes from three practices: enable encryption at rest by configuring an EncryptionConfiguration for the kube-apiserver so Secrets are encrypted before they reach etcd; restrict who can get and list Secrets with RBAC; and limit which ServiceAccounts and Pods mount each Secret. Managed clusters often integrate a cloud key management service for the same purpose, and external secret managers such as HashiCorp Vault are common at recognition depth.
Delivery method matters too. Values mounted as volume files are updated in the container when the Secret changes, while environment variables are fixed at container start; environment variables are also easier to leak through logs and diagnostic dumps, so volume mounts are generally preferred for sensitive material.
Pod Security Admission: Privileged, Baseline, Restricted
Some Pod specifications are inherently dangerous: privileged containers, host network access, or host path mounts can hand a workload control of its node. Kubernetes needed a built-in way to refuse such Pods. The original mechanism, PodSecurityPolicy (PSP), proved hard to use and was removed in Kubernetes 1.25. Its replacement is Pod Security Admission (PSA), an admission controller built into the API server that checks Pods against the three Pod Security Standards:
| Level | Meaning | Typical use |
|---|---|---|
| Privileged | Unrestricted; allows known privilege escalations | Trusted infrastructure workloads, such as CNI or storage agents |
| Baseline | Minimally restrictive; blocks known escalations like privileged containers and host namespaces | Ordinary applications with minimal friction |
| Restricted | Heavily restricted; requires hardening such as running as non-root and dropping capabilities | Security-critical applications, hardened namespaces |
PSA is applied per namespace with labels, and each level can be combined with one of three modes: enforce rejects violating Pods, audit records violations in the audit log, and warn returns a warning to the client but admits the Pod. For example, labeling a namespace with pod-security.kubernetes.io/enforce: restricted makes the API server reject any Pod in that namespace that does not meet the Restricted standard. For the exam, memorize the three levels in order of increasing strictness, the three modes, the namespace-label mechanism, and the PSP-removed-in-1.25 fact.
Hardening containers with securityContext
Pod Security Admission decides whether a Pod is admitted; securityContext is where you declare the hardened settings themselves. It appears at two levels of a Pod spec: Pod-level settings apply to all containers, and container-level settings override them for one container. The recurring exam fields are the ones the Restricted standard expects:
securityContext:
runAsNonRoot: true
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
capabilities:
drop:
- ALL
seccompProfile:
type: RuntimeDefault- runAsNonRoot: refuses to start the container if its process would run as root, shrinking the blast radius of a compromise.
- allowPrivilegeEscalation: false: prevents the process from gaining more privileges than its parent, for example via setuid binaries.
- readOnlyRootFilesystem: makes the container's root filesystem immutable, so an intruder cannot write tools or tamper with binaries; writable scratch space comes from explicit volumes.
- capabilities: drop ALL: removes Linux kernel capabilities, granting back only the specific ones a workload truly needs.
- seccompProfile RuntimeDefault: filters which system calls the container may make, using the runtime's default profile.
Scenario: an attacker exploits a vulnerability in a web application container. With this securityContext, the process is not root, cannot escalate, cannot write to its own filesystem, holds no dangerous kernel capabilities, and is restricted in the system calls it can attempt. Each field independently frustrates a step of the attack: defense in depth at the Container layer of the 4Cs.
NetworkPolicy as a security control
Kubernetes networking is default-allow: with no policies in place, every Pod can open connections to every other Pod in the cluster. From a security standpoint that means one compromised workload can probe and attack everything else, a pattern called lateral movement. NetworkPolicy is the control that removes this freedom.
A NetworkPolicy is a namespaced object that selects Pods with a podSelector and lists allowed ingress sources and egress destinations by Pod labels, namespace labels, or IP ranges. The pivotal behavior: a Pod selected by no policy accepts all traffic, but once any policy selects it, traffic in the covered directions is denied unless explicitly allowed. Policies are additive allow-lists; like RBAC, there are no deny rules to write. A policy with an empty podSelector selects every Pod in its namespace, which is how teams apply a default-deny baseline and then add narrow allowances per workload.
Scenario: a payment namespace runs a frontend, an api, and a database. Under default-allow, a compromised frontend can connect straight to the database and attempt to dump it. After a default-deny policy plus rules allowing only frontend-to-api and api-to-database traffic, that path no longer exists: the frontend has no allowed route to the database, so the intrusion is contained at the first hop. Two supporting facts complete the picture for the exam: NetworkPolicies are enforced by the CNI plugin, so a plugin without policy support (such as plain Flannel) silently ignores them, and this control belongs to the Cluster layer of the 4Cs.
Admission control and supply chain security
Admission control is the API server's checkpoint between authorization and persistence: after a request is authenticated and authorized, admission controllers can still mutate it or reject it based on policy. Pod Security Admission is one built-in example. Clusters can also register webhooks that call out to external policy engines, and tools like OPA Gatekeeper and Kyverno use this to enforce custom rules, such as refusing images from unknown registries or requiring resource limits. At KCNA depth, know the concept: admission control is where cluster-wide policy is applied to objects before they are stored.
The supply chain is everything that happens before an image reaches the cluster, spanning the Code and Container layers of the 4Cs. The recognition-level practices:
- Image scanning: tools such as Trivy inspect images for known vulnerabilities (CVEs) in OS packages and application dependencies, ideally in the CI pipeline before push and continuously in the registry.
- Image signing: projects such as Sigstore's cosign attach cryptographic signatures to images, so a cluster can verify an image really came from your pipeline and was not tampered with; verification is typically enforced by an admission webhook.
- SBOM (Software Bill of Materials): a machine-readable inventory of every component inside an artifact, which lets you answer, when the next big vulnerability lands, exactly which images contain the affected library.
Round this out with minimal base images, which carry fewer packages and therefore fewer vulnerabilities, and pulling only from trusted registries. Together these practices ensure that what runs in the cluster is known, verified, and as small as possible.
Tip. KCNA probes security with true-or-false style facts and layer classification: expect stems about Secrets being base64-encoded rather than encrypted, PodSecurityPolicy being removed in 1.25 in favor of Pod Security Admission, and which of the 4Cs a given control belongs to. Trigger words include least privilege, defense in depth, encryption at rest, Privileged, Baseline, Restricted, runAsNonRoot, SBOM, and admission controller. Scenario questions typically describe a risky Pod spec or an over-broad RBAC grant and ask which control or setting fixes it.
- The 4Cs are Cloud, Cluster, Container, Code: nested layers of defense in depth, where each inner layer depends on the security of the layers outside it.
- RBAC is additive and allow-only: Roles and ClusterRoles grant verbs on resources, bindings attach them to subjects, and anything not granted is denied.
- A ServiceAccount is a Pod's API identity; give workloads dedicated minimal ServiceAccounts and disable token automounting when the API is not needed.
- Secrets are base64-encoded, not encrypted, by default; enable encryption at rest with an EncryptionConfiguration and restrict Secret access with RBAC.
- PodSecurityPolicy was removed in Kubernetes 1.25; Pod Security Admission enforces the Privileged, Baseline, and Restricted standards via namespace labels in enforce, audit, or warn mode.
- Core securityContext hardening: runAsNonRoot, allowPrivilegeEscalation: false, readOnlyRootFilesystem, drop ALL capabilities, and a RuntimeDefault seccomp profile.
- NetworkPolicies convert default-allow networking into explicit allow-lists that block lateral movement, and are enforced by the CNI plugin.
- Supply chain security means scanning images for CVEs, signing them for provenance, keeping an SBOM, and using minimal base images from trusted registries.
Frequently asked questions
Are Kubernetes Secrets encrypted by default?
No. By default a Secret's values are only base64-encoded, and base64 is a reversible encoding, not encryption: anyone permitted to read the object can decode it instantly, and the data sits unencrypted in etcd. To protect Secrets you enable encryption at rest by giving the kube-apiserver an EncryptionConfiguration (often backed by a cloud key management service), restrict get and list access with RBAC, and limit which Pods mount each Secret.
What replaced PodSecurityPolicy in Kubernetes?
Pod Security Admission (PSA) replaced PodSecurityPolicy, which was removed in Kubernetes 1.25. PSA is an admission controller built into the API server that evaluates Pods against the three Pod Security Standards: Privileged (unrestricted), Baseline (blocks known privilege escalations), and Restricted (requires hardening such as running as non-root). It is configured with namespace labels, and each level can run in enforce, audit, or warn mode.
What are the 4Cs of cloud native security?
The 4Cs are Cloud, Cluster, Container, and Code: four nested layers running from the infrastructure outward around Kubernetes, the workload images and runtime settings, and finally the application code itself. Each inner layer depends on the security of the layers surrounding it, so weaknesses at an outer layer cannot be fully fixed further in. The model expresses defense in depth: apply appropriate controls at every layer rather than trusting any single one.
What is the difference between a Role and a ClusterRole?
Both grant permissions expressed as verbs on resources, but a Role is namespaced and only grants access within the namespace it lives in, while a ClusterRole is cluster-scoped and can grant access across all namespaces and to cluster-level resources such as nodes. A RoleBinding attaches either kind of role to subjects within one namespace, whereas a ClusterRoleBinding applies a ClusterRole across the whole cluster. Least privilege favors namespaced Roles wherever they suffice.
What is a ServiceAccount used for in Kubernetes?
A ServiceAccount is the identity that a Pod's processes use when calling the Kubernetes API. Every namespace has a default ServiceAccount, and every Pod runs as one, optionally with an API token mounted into its containers. From a security perspective, workloads that never call the API should not have a token mounted (automountServiceAccountToken: false), and workloads that do need API access should use a dedicated ServiceAccount bound to a minimal RBAC Role.
Why use a Secret instead of a ConfigMap?
ConfigMaps are for non-sensitive configuration and are stored as plain text with no path to encryption at rest. Secrets are the designated object for credentials, tokens, and keys: they can be encrypted at rest via the API server's EncryptionConfiguration, their access is conventionally locked down more tightly with RBAC, and Kubernetes features and tooling treat them with extra care. Both deliver data to containers the same ways, as environment variables or mounted files, so the difference is protection, not delivery.
Sign up free to mark lessons complete, bookmark topics and track your exam readiness.