Kubernetes security best practices reduce the blast radius of a compromised user, credential, Pod, or application. For a small team, the baseline is straightforward:
least-privilege RBAC → purpose-specific ServiceAccounts → controlled Secrets → Pod Security → restricted network exposure → recurring review
Raff Technologies manages the Kubernetes control plane and private cluster infrastructure, but in-cluster permissions remain a workload responsibility. A managed cluster does not automatically make RBAC least-privilege, prevent a Pod from running with excessive privileges, or decide which workload may read a Secret.
This guide owns the Kubernetes security baseline across RBAC, ServiceAccounts, Secrets, securityContext, and Pod Security Standards. Network segmentation remains in Kubernetes Network Policy, while MSP tenancy boundaries belong in Kubernetes Multi-Tenancy for MSPs.
Kubernetes security should limit four blast-radius layers
Treat Kubernetes security as several independent controls rather than one hardening switch.
| Layer | Main controls | Core question |
|---|---|---|
| API identity | users, ServiceAccounts, RBAC, kubeconfig | What can this identity do through the Kubernetes API? |
| Credentials | Secrets, external secret stores, token lifecycle | Which sensitive values can this workload access? |
| Pod execution | Pod Security Standards, securityContext, admission | What can this container do on the node? |
| Network exposure | private VPC, Services, Gateway/Ingress, NetworkPolicy | Which network paths can reach or leave it? |
These controls are complementary.
RBAC can stop an identity from deleting Deployments but cannot stop an already-running process from making an allowed network connection.
NetworkPolicy can restrict a Pod's traffic but cannot stop a user with cluster-admin from changing the policy.
Pod Security can block privileged containers but does not decide who may read Kubernetes Secrets.
A useful review therefore asks:
If this identity, Secret, or Pod is compromised, what can the attacker do next?
The answer should be narrow and explainable.
RBAC should start from namespace-level least privilege
Kubernetes RBAC authorizes API actions using Roles, ClusterRoles, RoleBindings, and ClusterRoleBindings.
The safest default is:
- grant only required verbs;
- grant only required resources;
- scope access to one namespace where possible;
- prefer RoleBinding over ClusterRoleBinding when cluster-wide access is unnecessary;
- avoid wildcard resources and verbs;
- reserve cluster-admin for exceptional administration.
The four core objects are:
| RBAC object | Scope | Purpose |
|---|---|---|
| Role | one namespace | defines namespaced permissions |
| ClusterRole | cluster-wide definition | cluster resources or reusable permission sets |
| RoleBinding | one namespace | grants a Role or ClusterRole inside one namespace |
| ClusterRoleBinding | whole cluster | grants a ClusterRole cluster-wide |
A ClusterRole is not automatically a cluster-wide grant. Binding determines where its authority applies.
The dangerous convenience is often ClusterRoleBinding.
Before creating one, ask whether the identity truly needs the same permission across every namespace or cluster-scoped resource.
Avoid wildcard permissions
Wildcard rules can silently grow in power as APIs and CRDs are added.
Avoid patterns such as:
verbs: ["*"] resources: ["*"]
unless unrestricted administrative access is genuinely required.
Prefer the smallest permission set the workload needs.
For example, an application controller that only reads ConfigMaps should not also receive create, update, delete, Secret, or RBAC permissions merely because a broader existing role is convenient.
This matters because Kubernetes is extensible. A wildcard today can automatically include resources installed later.
Workload-creation rights are more powerful than they look
A user who cannot directly read a Secret may still be able to expose it if that user can create a Pod in the same namespace and mount the Secret.
Likewise, permission to create Deployments, Jobs, or other workload resources can indirectly grant access to:
- namespace Secrets;
- ConfigMaps;
- PVCs;
- ServiceAccount identities;
- node-level privileges when privileged Pods are allowed.
That means:
create Pod is not a low-risk permission.
When reviewing CI/CD or developer roles, inspect both direct API rights and what those rights allow the user to make Kubernetes run.
For less-trusted users who can create workloads, enforce an appropriate Pod Security Standard rather than relying on RBAC alone.
Audit privileged RBAC regularly
Useful review commands include:
kubectl get clusterrolebindings kubectl get rolebindings -A kubectl get serviceaccounts -A
For one identity, Kubernetes authorization checks can also help validate intended access:
kubectl auth can-i --list --as=<user-or-service-account>
For a ServiceAccount:
kubectl auth can-i --list --as=system:serviceaccount:<namespace>:<service-account>
Review especially:
- cluster-admin bindings;
- system:masters membership;
- wildcard roles;
- Secret access;
- RBAC create/update permissions;
- workload-creation permissions;
- unused identities;
- CI/CD credentials that outlived their purpose.
A security review should be able to explain why every cluster-wide binding exists.
Give each workload an intentional ServiceAccount
Pods use ServiceAccounts as Kubernetes API identities.
A Pod that does not specify a ServiceAccount receives the namespace's default ServiceAccount.
That does not mean the default account should become a shared application identity.
Use a purpose-specific ServiceAccount when a workload needs API access.
For example:
web application → no Kubernetes API access deployment automation → deploy permissions only in target namespace backup controller → only backup-related resources operator → exact CRDs/resources required by the operator
Avoid one powerful ServiceAccount shared across unrelated workloads.
Shared identities increase blast radius and make credential rotation harder.
Disable automatic API tokens when the workload does not need Kubernetes
By default, Kubernetes normally injects credentials for the assigned ServiceAccount into a Pod.
If an application never calls the Kubernetes API, remove that unnecessary credential.
At Pod level:
spec: automountServiceAccountToken: false
Or configure the ServiceAccount accordingly.
Modern Kubernetes uses short-lived projected ServiceAccount tokens via the TokenRequest API for ordinary Pod credentials rather than the older long-lived token Secret pattern.
That is safer, but the best credential is still one the workload does not receive at all when it has no need for it.
Kubernetes Secrets are not encryption by themselves
Kubernetes Secrets are designed for confidential values such as:
- passwords;
- API keys;
- tokens;
- certificates;
- private registry credentials.
But two misconceptions matter.
First:
base64 encoding is not encryption.
Second:
upstream Kubernetes stores Secret objects unencrypted in etcd by default unless encryption at rest is configured.
Managed Kubernetes implementations can differ, so do not assume a provider's etcd encryption model without documented evidence.
Raff's public Kubernetes product documentation currently does not state the exact encryption-at-rest implementation for Kubernetes Secret objects. This guide therefore does not claim one.
If encryption-at-rest or customer-managed keys are a compliance requirement, verify that control explicitly before treating it as part of the architecture.
Secret access deserves tighter RBAC than ordinary configuration
Secret permissions have unusually high impact.
Kubernetes security guidance notes that:
- get exposes a Secret;
- list can expose Secret values for all returned objects;
- watch can expose Secret data over time;
- users who can create Pods may be able to mount Secrets even without direct Secret read permissions.
Therefore:
- avoid broad list/watch on Secrets;
- grant get only when normal workload behavior requires it;
- separate workloads with different Secret trust requirements into namespaces where appropriate;
- expose a Secret only to the containers that need it;
- rotate credentials after access changes;
- avoid logging Secret values;
- never commit base64-encoded production Secret manifests to Git as if encoding made them safe.
For Git-based workflows, tools such as Sealed Secrets or an external secret-management system can help, but they do not replace RBAC and rotation.
Pod Security Standards define the workload privilege baseline
Kubernetes defines three Pod Security Standard profiles:
| Profile | Intent |
|---|---|
| Privileged | unrestricted; suitable only for deliberately trusted infrastructure workloads |
| Baseline | blocks known privilege escalations while remaining broadly compatible |
| Restricted | stronger hardening aligned with current Pod security best practices |
For ordinary application workloads, Restricted is a useful target where compatibility allows.
Restricted includes controls around areas such as:
- running as non-root;
- privilege escalation;
- Linux capabilities;
- seccomp;
- host namespaces and other sensitive PodSpec settings.
Not every system workload can meet Restricted.
Storage, networking, observability, or security agents may need documented exceptions.
The objective is not "Restricted everywhere at any cost."
It is:
ordinary applications should not inherit infrastructure-level privileges because one trusted system component needs them.
Pod Security Admission gives you enforce, audit, and warn
Kubernetes includes Pod Security Admission as a stable built-in admission controller.
It applies Pod Security Standards at namespace level.
The three modes are:
- enforce — reject non-compliant Pods;
- audit — allow the Pod but record violations in audit annotations;
- warn — allow the Pod but warn the user.
A practical rollout is:
- classify namespaces by workload trust;
- apply audit and warn first;
- fix violations;
- enforce the selected profile;
- version-pin the profile when controlled upgrade behavior matters.
Example namespace labels:
metadata: labels: pod-security.kubernetes.io/enforce: restricted pod-security.kubernetes.io/enforce-version: v1.37 pod-security.kubernetes.io/audit: restricted pod-security.kubernetes.io/warn: restricted
Version labels can also use latest, but pinning to a Kubernetes minor version makes policy changes during upgrades more explicit.
Do not leave namespaces unlabeled forever. Kubernetes security guidance treats unevaluated namespaces as gaps in the security model.
securityContext should make application privileges explicit
Pod Security Standards define policy.
securityContext contains the concrete workload settings.
Evaluate controls such as:
securityContext: runAsNonRoot: true allowPrivilegeEscalation: false seccompProfile: type: RuntimeDefault capabilities: drop: - ALL
The exact configuration depends on the application.
Do not add capabilities back unless the process genuinely needs them.
Avoid privileged containers, hostPID, hostNetwork, hostIPC, and hostPath access for ordinary applications unless there is a specific, reviewed requirement.
Every exception increases node blast radius.
Treat cluster-admin kubeconfig as a privileged credential
Raff Kubernetes currently allows users to download a kubeconfig with full cluster-admin access from the dashboard.
That is useful for administration.
It is also a highly privileged credential.
Do not use that kubeconfig as the default credential for:
- normal application Pods;
- every developer;
- CI/CD pipelines;
- third-party tools that need only narrow access.
Instead:
- restrict who receives the administrative kubeconfig;
- store it as a high-value credential;
- create narrower Kubernetes identities for routine workflows;
- remove access when people or automation no longer need it.
Raff account-level IAM can restrict who is allowed to perform platform actions such as retrieving Kubernetes credentials, but that platform IAM is separate from Kubernetes RBAC inside the cluster.
Separate Raff platform security from Kubernetes workload security
Raff currently provides platform-level controls including:
- isolated VPCs;
- automatic DDoS protection on public IPs;
- security groups/firewall controls;
- IAM with granular permissions;
- MFA;
- audit logs.
Raff Kubernetes also places cluster nodes on a private VPC and exposes traffic through a managed public endpoint.
Those controls reduce infrastructure exposure.
They do not automatically configure:
- Kubernetes Roles and RoleBindings;
- ServiceAccount permissions;
- Secret access;
- Pod Security Admission;
- securityContext;
- NetworkPolicy;
- application authentication.
The responsibility boundary is:
| Raff platform | Kubernetes/application team |
|---|---|
| managed control plane | RBAC design |
| private cluster network | ServiceAccounts |
| platform IAM/MFA | Secret access |
| account audit log | Pod Security |
| public-edge/firewall controls | NetworkPolicy |
| DDoS protection | application authorization |
Use Raff Security for platform-level controls and Raff Kubernetes for the current managed-cluster model.
Network security remains a separate layer
RBAC answers:
What Kubernetes API actions can this identity perform?
NetworkPolicy answers:
Which network flows can this Pod send or receive?
Do not use one as a substitute for the other.
A useful application baseline is:
private infrastructure → only required public routes → NetworkPolicy where workload segmentation is needed → least-privilege ServiceAccount → restricted Pod execution → application auth
Use Kubernetes Network Policy for default-deny, DNS, ingress, and egress design.
Multi-tenant clusters need more than namespaces
Namespaces are useful organizational and security boundaries, but they should not be treated as perfect tenant isolation by themselves.
For MSP/customer workloads, review:
- RBAC;
- workload-creation permissions;
- Pod Security;
- NetworkPolicy;
- Secrets;
- storage isolation;
- node placement;
- cluster-admin distribution;
- operational access.
Some customers may justify a separate cluster instead of stronger policy inside a shared one.
Use Kubernetes Multi-Tenancy for MSPs for that architecture decision.
Kubernetes security checklist for small teams
Use this as a baseline review.
RBAC
- cluster-admin is limited to explicit administrators;
- ClusterRoleBindings have a named reason;
- wildcard verbs/resources are avoided;
- Secret permissions are tightly scoped;
- workload-creation rights are treated as privileged;
- stale users and automation identities are removed.
ServiceAccounts
- workloads use dedicated ServiceAccounts when API access is needed;
- default ServiceAccount is not carrying accidental privileges;
- automountServiceAccountToken is disabled where Kubernetes API access is unnecessary;
- powerful ServiceAccounts are not shared across unrelated workloads.
Secrets
- production Secret values are not committed to source control;
- base64 is not treated as encryption;
- get/list/watch permissions are minimized;
- credential rotation has an owner;
- sensitive values are not written to logs;
- encryption-at-rest requirements are explicitly verified.
Pod security
- every application namespace has an evaluated Pod Security policy;
- Restricted is used where compatible;
- exceptions are documented;
- containers run as non-root where possible;
- privilege escalation is disabled;
- unnecessary Linux capabilities are dropped;
- seccomp uses an approved profile.
Network/exposure
- worker infrastructure remains private where possible;
- only required application traffic is public;
- NetworkPolicy is used where east-west segmentation is needed;
- public admin endpoints are avoided.
Operations
- privileged kubeconfigs are controlled;
- access is reviewed after team/vendor changes;
- security exceptions have owners;
- policy compatibility is tested before Kubernetes upgrades;
- incidents trigger a blast-radius review.
Review permissions whenever the workload changes
Security review should not be a one-time launch task.
Revisit it when:
- a new controller/operator is installed;
- CI/CD gains new deployment rights;
- a workload starts calling the Kubernetes API;
- new Secrets are introduced;
- a namespace becomes multi-team or multi-tenant;
- a Pod needs new host privileges;
- a cluster is upgraded;
- a team member or vendor loses access;
- an incident reveals excessive authority.
A small team can maintain a short register of:
- privileged identities;
- cluster-wide bindings;
- Pod Security exceptions;
- privileged workloads;
- high-value Secrets;
- administrative kubeconfig owners.
That list is more useful than a large security document nobody updates.
Final recommendation
Build Kubernetes security around blast-radius reduction.
Use namespace-scoped least-privilege RBAC. Give workloads purpose-specific ServiceAccounts and remove API credentials from Pods that do not need them. Treat Secret read and workload-creation permissions as high-impact rights. Use Pod Security Admission to apply Baseline or Restricted policies deliberately, and make container privileges explicit through securityContext.
Then layer NetworkPolicy, platform IAM, private networking, monitoring, patching, and application authorization around that baseline.
A managed Kubernetes platform can remove control-plane operational work. It cannot decide which privileges your workloads should have.
Continue with Kubernetes Network Policy, Kubernetes Cluster Management, Kubernetes Monitoring, and Kubernetes Multi-Tenancy for MSPs for the adjacent security and operations decisions.