Safeguard
Product•

Kubernetes Posture (KSPM) in Safeguard: CIS, Pod Security, RBAC

Check cluster posture against CIS, Pod Security Standards, RBAC and exposure, then connect Kubernetes to Safeguard read-only for scheduled control tests.

Safeguard Security Team
36 min read

To manage Kubernetes security posture, compare what your clusters are actually running against a written baseline (the CIS Kubernetes Benchmark, the Kubernetes Pod Security Standards and the Kubernetes RBAC good practices), review who can reach what, and repeat the check on a schedule, because clusters drift a little every week. In Safeguard, you do this by connecting each cluster as a Kubernetes compliance connector with a read-only service account. Safeguard then runs automated compliance tests against the cluster and records each result as evidence toward CIS Kubernetes Benchmark recommendations and the controls of the other frameworks the docs list.

This post is written for the platform engineer or security engineer who owns one or more clusters and has been asked a question like "are we CIS aligned?" or "who can create pods in production?" with no easy way to answer it. The first two thirds work with nothing more than kubectl, jq and the free documents from kubernetes.io and CIS. Safeguard enters at "How Safeguard does this", and the post is specific about what the connector reads, what it does not, and what stays your job.

Key takeaways

  • Posture is configuration, checked again and again. Kubernetes security posture management (KSPM) compares cluster settings, workload specs and permissions against a baseline and flags drift. It is not image scanning and it is not runtime detection.
  • Use baselines you did not write. The CIS Kubernetes Benchmark covers control plane and policy settings, the Pod Security Standards define three workload levels (Privileged, Baseline, Restricted), and the Kubernetes RBAC good practices page lists the verbs and resources that quietly grant escalation.
  • Exposure is the multiplier. A permissive role behind no network path matters less than a small mistake behind a public Service. Review Services, host networking and network policy coverage together with RBAC.
  • Kubernetes / KSPM (GA) in Safeguard runs through the Kubernetes compliance connector (GA): a read-only service account, a ClusterRole limited to get and list, and automated compliance tests (GA) that map results to the CIS Kubernetes Benchmark, SOC 2, ISO/IEC 27001, HIPAA Security Rule, PCI DSS and NIST CSF 2.0.
  • Policies and gates (GA) decide what ships toward the cluster, with Block, Warn and Notify as the gate actions and approvals handled through exceptions.
  • Safeguard does not admit or deny pods. Safeguard's own guardrails docs say its Kubernetes admission controller is not published. Enforcement inside the cluster stays with Kubernetes features such as Pod Security Admission.

What Kubernetes security posture management actually covers

The phrase gets used loosely, so here is a working definition you can hold a tool, a script or a consultant to.

KSPM is the repeated comparison of four things against a baseline:

  1. Control plane and node configuration. How the API server, controller manager, scheduler, etcd and kubelets are configured: authentication, authorization mode, audit logging, encryption, certificate handling.
  2. Workload configuration. What each Pod spec asks for: privileged mode, host namespaces, host paths, Linux capabilities, the user it runs as, seccomp, privilege escalation.
  3. Identity and access. Roles, ClusterRoles, their bindings, service accounts and the tokens that represent them.
  4. Exposure. Which workloads and endpoints can be reached, from where: Service types, host networking and ports, network policy coverage, and the API server endpoint itself.

The Kubernetes project's own security checklist frames this well. It is described as a baseline and it groups its items into areas that include authentication and authorization, network security, pod security, logs and auditing, pod placement, secrets, images and admission control. It also says plainly that security is not one size fits all, and that each item should be weighed on its merits. That is the honest starting point for any posture program: you are not chasing a perfect score, you are making deliberate choices and recording why.

What KSPM does not cover is just as important. It will not tell you whether an image contains a vulnerable library, whether a workload is behaving oddly right now, or whether a developer laptop with a kubeconfig on it is compromised. Image and dependency scanning, runtime monitoring and endpoint security sit next to it. A posture program that pretends to cover those ends up covering none of them well.

Why clusters drift

Most clusters start reasonably configured. They drift through ordinary work:

  • A team needs a deploy unblocked on a Friday, so someone binds a broad ClusterRole "for now".
  • A debugging session adds hostNetwork: true to a pod, and the manifest gets committed.
  • A vendor chart creates its own service account with wildcard permissions.
  • A namespace is created for a new service and nobody adds a default deny network policy.
  • An upgrade changes a default, and a flag that used to be explicit is now implicit.

None of these looks like an incident on the day. Together, over months, they produce a cluster whose real posture has little to do with the one that passed review. That is why the word "continuous" matters more than the word "benchmark".

The baselines: CIS, Pod Security Standards and RBAC good practices

You need something written to compare against. Three free sources cover most of what matters.

The CIS Kubernetes Benchmark

The Center for Internet Security publishes a Kubernetes benchmark that it describes as the product of a community consensus process, consisting of secure configuration guidelines for Kubernetes. CIS offers its benchmarks as free PDFs for non-commercial use. On the CIS Kubernetes benchmark page today, the most recent upstream Kubernetes version listed for download is 2.1.0, alongside separate benchmarks for managed distributions (Amazon EKS, Azure AKS, Google GKE, Oracle OKE and Red Hat OpenShift), each with its own version.

Two practical points before you use it:

  • Pick the right document. If you run a managed service, the managed benchmark is the one to start from, because you cannot change most control plane settings yourself and the managed document reflects that split of responsibility. Self-managed clusters use the upstream Kubernetes benchmark.
  • Recommendations are numbered. Every recommendation has a number such as 1.2.1 or 5.1.2. When a tool or an auditor says "5.2.x failed", that number points into a specific version of a specific benchmark. Always record which version you assessed against, because numbering can shift between versions.

This post does not paraphrase recommendation titles, because the benchmark text sits behind the CIS download form. Download the PDF and keep it next to you while you read results.

The Pod Security Standards

The Kubernetes Pod Security Standards define three policy levels for workloads, and the definitions are short enough to quote in spirit:

LevelWhat kubernetes.io says it is for
PrivilegedAn unrestricted policy with the widest level of permissions. It allows known privilege escalations.
BaselineA minimally restrictive policy that prevents known privilege escalations while allowing the default, minimally specified Pod configuration.
RestrictedA heavily restricted policy that follows current Pod hardening best practices.

The Baseline level is where the important "never" items live. Among the controls kubernetes.io lists for Baseline:

  • Privileged containers must be disallowed, because privileged Pods disable most security mechanisms.
  • Host namespaces (host network, host PID, host IPC) must not be shared.
  • HostPath volumes must be forbidden.
  • Host ports should be disallowed or limited to a known list.
  • Added Linux capabilities beyond a small default set must be disallowed.
  • The default AppArmor profile should not be overridden or disabled, setting a custom SELinux user or role is forbidden, the default /proc masks should be required, seccomp must not be set to Unconfined, and unsafe sysctls should be disallowed.
  • Windows HostProcess containers, which give privileged access to the Windows host, are disallowed.

Restricted adds the hardening items on top: limiting volume types, disallowing privilege escalation, requiring containers to run as non-root, requiring a seccomp profile and dropping capabilities.

Kubernetes ships a built-in way to apply these levels per namespace, Pod Security Admission, configured with namespace labels. The label pod-security.kubernetes.io/enforce rejects violating pods, pod-security.kubernetes.io/audit records violations as an audit annotation, and pod-security.kubernetes.io/warn shows the user a warning while still allowing the pod. That is a Kubernetes feature you run yourself; it is mentioned here because a posture review should check whether those labels are present and at which level.

The RBAC good practices

The Kubernetes page on Role Based Access Control good practices is one of the most useful pages in the whole documentation set for posture work, because it lists the permissions that look harmless and are not. Its core advice:

  • Least privilege. Assign permissions at namespace level where possible, and avoid wildcard permissions, especially on all resources. Because Kubernetes is extensible, a wildcard also grants rights to resource types that do not exist yet.
  • Do not use cluster-admin day to day. Administrators should not use cluster-admin accounts except where specifically needed.
  • Keep people out of system:masters. Membership in that group bypasses RBAC checks entirely and cannot be removed by deleting bindings.
  • Minimize privileged tokens. Pods that are granted powerful service accounts should be few, and run with least privilege to limit the blast radius of a container escape.
  • Harden defaults. Review bindings for the system:unauthenticated group and remove them where possible, and avoid default auto mounting of service account tokens by setting automountServiceAccountToken: false.
  • Review periodically. Redundant entries and possible escalations should be looked at on a schedule.

Then it lists the privilege escalation risks by name. These are the ones posture reviews most often miss:

PermissionWhy it matters, per kubernetes.io
list or watch on secretsA list response returns the secret contents, not just names.
Create workloads in a namespaceImplicitly grants access to the secrets, config maps and service accounts that pods in that namespace can mount.
Create persistent volumesA hostPath volume can give a container access to the host filesystem.
get on nodes/proxyGives access to the Kubelet API, so it is not a read only permission.
The escalate verbLets the holder effectively escalate their own privileges.
The bind verbLets the holder create bindings to roles they do not hold.
The impersonate verbLets the holder act as other users.
Create on serviceaccounts/tokenLets the holder issue tokens for existing service accounts.
Control of admission webhooksLets the holder read or change objects admitted to the cluster.
Namespace modificationCan change labels that other policy, such as Pod Security Admission, depends on.

If your review only looks for cluster-admin, you will miss most of this table.

Exposure: the part that turns findings into risk

Benchmarks and RBAC answer "is this configured correctly?" Exposure answers "given this configuration, what can be reached, and by whom?" The second question is what makes a posture finding urgent or not.

Service types

Kubernetes Services come in types, and the type decides reach. The default, ClusterIP, exposes the Service on a cluster internal address only. NodePort exposes it on a static port on every node's address. LoadBalancer asks the cloud provider or an equivalent controller for an external load balancer. ExternalName maps the Service to a DNS name. A Service can also carry externalIPs, which route traffic arriving at those addresses to the Service. Kubernetes marks externalIPs as deprecated since v1.36 and suggests an external load balancer controller or a Gateway API implementation instead, so any you find are worth a migration ticket as well as a review.

A posture review should list every NodePort and LoadBalancer Service and every Service with externalIPs, and for each one record who asked for it and why. Ingress objects and Gateway API routes belong in the same review, because they are the usual front door for HTTP traffic.

Host networking and host ports

A pod with hostNetwork: true shares the node's network namespace, so it can listen on the node's interfaces directly and see traffic the node sees. A container with a hostPort binds a port on the node. Both are Baseline violations under the Pod Security Standards unless explicitly justified, and both create exposure that no Service object will show you.

Network policy coverage

Network policies are the in-cluster firewall, with two caveats from kubernetes.io worth repeating. First, pods are non-isolated by default: until some policy selects a pod, all traffic to and from it is allowed. Second, policies only take effect when the cluster's network plugin supports them. A namespace with zero policies is therefore wide open inside the cluster, and a cluster whose plugin does not enforce policy is open no matter how many policies exist.

The API server endpoint

The API server is the most valuable target in the cluster. Whether its endpoint is public, private, or public with an allowlist is a posture decision in its own right. Keep a note of it per cluster, because it will matter again when you connect any outside tool.

Run a posture review yourself

Here is a practical, tool neutral review you can run this week. The commands use standard kubectl and jq syntax. They were not run against a live cluster for this post, so test them in a non-production cluster first, and adjust for your Kubernetes version.

Step 1: Inventory what you are assessing

Write down, per cluster: the Kubernetes version, whether it is managed or self-managed, which CIS benchmark document and version applies, the network plugin, and how the API server endpoint is exposed. Without that list, findings cannot be compared from one month to the next.

kubectl version
kubectl get nodes -o wide
kubectl get namespaces --show-labels

The last command also shows you which namespaces carry Pod Security Admission labels.

Step 2: Check Pod Security Standards coverage

List namespaces with no enforce label, then look for the Baseline violations that cause the most damage.

# Namespaces without a Pod Security enforce label
kubectl get ns -o json | jq -r '.items[] | select(.metadata.labels["pod-security.kubernetes.io/enforce"] == null) | .metadata.name'

# Pods that run privileged containers
kubectl get pods -A -o json | jq -r '.items[] | select(any(.spec.containers[]; .securityContext.privileged == true)) | "\(.metadata.namespace)/\(.metadata.name)"'

# Pods that share host namespaces
kubectl get pods -A -o json | jq -r '.items[] | select(.spec.hostNetwork == true or .spec.hostPID == true or .spec.hostIPC == true) | "\(.metadata.namespace)/\(.metadata.name)"'

# Pods with hostPath volumes
kubectl get pods -A -o json | jq -r '.items[] | select(any(.spec.volumes[]?; .hostPath != null)) | "\(.metadata.namespace)/\(.metadata.name)"'

A quicker way to see what Restricted would reject in a namespace is a server side dry run of the label, which Kubernetes evaluates and reports as warnings without changing anything:

kubectl label --dry-run=server --overwrite ns payments pod-security.kubernetes.io/enforce=restricted

The kubernetes.io task page on namespace labels uses the same --dry-run=server approach across all namespaces at once. System namespaces such as kube-system often need Privileged. Record that as a deliberate exception rather than leaving it unlabelled.

Step 3: Review RBAC for the high risk permissions

Start with who holds cluster-admin, then work through the table above.

# Everyone bound to cluster-admin
kubectl get clusterrolebindings -o json | jq -r '.items[] | select(.roleRef.name == "cluster-admin") | .metadata.name + " -> " + ([.subjects[]? | .kind + ":" + .name] | join(", "))'

# ClusterRoles with wildcard verbs or resources
kubectl get clusterroles -o json | jq -r '.items[] | select(any(.rules[]?; (.verbs // []) | index("*")) or any(.rules[]?; (.resources // []) | index("*"))) | .metadata.name'

# Bindings that include unauthenticated users
kubectl get clusterrolebindings,rolebindings -A -o json | jq -r '.items[] | select(any(.subjects[]?; .name == "system:unauthenticated")) | .metadata.name'

# What can a given service account do?
kubectl auth can-i --list --as=system:serviceaccount:payments:default -n payments

Expect some wildcard roles to belong to Kubernetes itself and to controllers you rely on. The point is to know which ones exist and to have a reason for each.

Then check the quieter escalations by asking directly:

kubectl auth can-i list secrets -A --as=system:serviceaccount:ci:deployer
kubectl auth can-i get nodes/proxy --as=system:serviceaccount:monitoring:agent
kubectl auth can-i create serviceaccounts/token -n payments --as=system:serviceaccount:ci:deployer
kubectl auth can-i bind clusterroles --as=system:serviceaccount:ci:deployer

Step 4: Find token sprawl

Kubernetes recommends short lived tokens issued through the TokenRequest API over long lived token Secrets. Look for the long lived ones and for pods that mount a token they do not need.

# Long lived service account token Secrets
kubectl get secrets -A --field-selector type=kubernetes.io/service-account-token

# Pods that mount a service account token automatically
kubectl get pods -A -o json | jq -r '.items[] | select(.spec.automountServiceAccountToken != false) | "\(.metadata.namespace)/\(.metadata.name) sa=\(.spec.serviceAccountName)"'

The second list will be long in most clusters. Prioritise pods whose service account holds anything beyond read access in its own namespace.

Step 5: Map exposure

# Services reachable from outside the cluster
kubectl get svc -A -o json | jq -r '.items[] | select(.spec.type == "NodePort" or .spec.type == "LoadBalancer" or (.spec.externalIPs // [] | length) > 0) | "\(.metadata.namespace)/\(.metadata.name) \(.spec.type)"'

# Ingress objects
kubectl get ingress -A

# Namespaces with no network policy at all
comm -23 <(kubectl get ns -o jsonpath='{range .items[*]}{.metadata.name}{"\n"}{end}' | sort) \
         <(kubectl get networkpolicy -A -o jsonpath='{range .items[*]}{.metadata.namespace}{"\n"}{end}' | sort -u)

Join this with Step 3. A workload that is externally reachable and runs under a service account that can create pods or read secrets is your first fix.

Step 6: Check the control plane against CIS

For self-managed clusters, CIS recommendations for the API server, controller manager, scheduler and etcd are mostly about command line flags and file permissions on control plane nodes. Kubeadm style clusters run these components as static pods, so their flags are visible in the pod specs in kube-system:

kubectl -n kube-system get pods -l tier=control-plane -o json | jq -r '.items[] | .metadata.name, (.spec.containers[0].command | join("\n  "))'

For managed clusters, the provider controls most of these settings. Use the managed benchmark and the provider's documentation to see which recommendations are yours.

Step 7: Record decisions, not just failures

For each failed item, write one of three outcomes: fixed, accepted with an owner and an expiry date, or not applicable with a reason. A posture report that is a list of red items with no decisions is not useful to an auditor, and it is demoralising for the team that owns it.

Step 8: Put it on a schedule

Run the same checks on a schedule and when manifests change, and compare against the previous run. Drift is the signal. A failure that appeared this week deserves more attention than one that has been accepted for a year.

A worked example (illustrative)

The following is a constructed example with round, invented details. It is not drawn from any customer.

A team runs one production cluster with ten application namespaces. The review above produces three findings that look minor on their own:

  1. A ci service account holds a ClusterRole that allows create on pods in every namespace. It was added for a migration job that no longer runs.
  2. The payments namespace has no network policy, and its pods run under the default service account with token automount on.
  3. A metrics exporter in the monitoring namespace runs with hostNetwork: true and is exposed through a NodePort Service.

Read together, they form a path. Anyone who obtains the ci token can create a pod in payments, mount whatever that namespace can mount, and reach every other pod in the cluster because nothing restricts traffic. The fixes are small: remove the binding, add a default deny policy to payments and turn off token automount, and move the exporter behind a ClusterIP Service. The value of the review is not any single finding. It is seeing them on one page.

Requirement, check and owner

RequirementHow you check itWho usually owns the fix
CIS control plane recommendationsStatic pod flags, file permissions, or the managed provider's settingsPlatform team, or the provider for managed control planes
Pod Security Standards level per namespaceNamespace labels, server side dry run, pod spec reviewPlatform team sets the level, application teams fix specs
Least privilege RBACBindings to cluster-admin, wildcard rules, auth can-i on escalation verbsPlatform team, with application owners for their namespaces
Token hygieneLong lived token Secrets, automount settingsApplication teams, guided by platform
ExposureService types, Ingress, host networking, network policy coverage, API endpointPlatform and network teams together
Evidence for auditsDated results mapped to controls, with exceptions recordedSecurity or GRC, fed by platform

How Safeguard does this

Safeguard runs Kubernetes posture checks through its compliance connectors. Kubernetes / KSPM (GA) is the capability; the Kubernetes compliance connector (GA) is how you switch it on for a cluster; and automated compliance tests (GA) are what run against the cluster and turn results into evidence toward controls. Everything below comes from docs.safeguard.sh.

What the connector reads

The Kubernetes setup page lists the permissions Safeguard needs, all read only:

  • get and list on clusterrolebindings, clusterroles, roles, rolebindings, namespaces, nodes, pods, serviceaccounts and networkpolicies.
  • get and list on Gatekeeper constraints (constraints.gatekeeper.sh) and Kyverno policies (kyverno.io), if you run either policy engine.

Two things are worth noticing in that list. It covers RBAC, workload specs, namespaces, nodes, service accounts and network policies, which lines up with the posture areas above. And it does not include secrets, so the connector is not granted the ability to read secret values in your cluster. The compliance connectors overview also says Safeguard asks for the narrowest read only grant the vendor offers and only makes read calls with the credential.

What a connection produces

The setup page says a connection produces automated compliance tests, switched on per workspace by the Safeguard team. Safeguard's automated tests read Kubernetes and map to controls in these frameworks:

FrameworkControls the docs list for the Kubernetes tests
SOC 2A1.1, C1.1, CC6.1, CC6.3, CC6.6, CC6.7, CC6.8, CC7.2, CC8.1
ISO/IEC 27001A.5.17, A.8.2, A.8.5, A.8.6, A.8.9, A.8.15, A.8.20, A.8.24, A.8.32
HIPAA Security Rule164.308(a)(4), 164.312(a)(1), 164.312(b), 164.312(d), 164.312(e)(1)
PCI DSS1.3.1, 2.2.1, 3.5.1, 4.2.1, 6.5.1, 7.2.2, 8.6.3, 10.2.1
NIST CSF 2.0DE.CM-09, PR.AA-01, PR.AA-03, PR.AA-05, PR.DS-01, PR.DS-02, PR.IR-01, PR.IR-03, PR.PS-01
CIS Kubernetes BenchmarkRecommendations in the 1.2, 1.3, 1.4, 2, 5.1, 5.2, 5.4 and 5.7 ranges, listed individually on the setup page

For the CIS benchmark, the docs say the numbers are its recommendations. Open the setup page for the exact list and match it against the benchmark PDF you downloaded. The docs are careful about what a pass means: a passing test is evidence toward each control it maps to, not proof on its own that the control is met.

The same page notes that Gatekeeper OPA and Kyverno connect to the same provider as Kubernetes, and the tests run for a connection made through any of them.

Step by step: connect a cluster

These steps follow the Kubernetes setup page. The commands are exactly as the docs show them, apart from the Secret manifest, which the docs describe in words and which is written here in the shape kubernetes.io documents. They were not run for this post.

  1. Create a service account for Safeguard.

    kubectl create serviceaccount safeguard -n kube-system
    
  2. Create a long lived token for it by applying a Secret of type kubernetes.io/service-account-token with the annotation kubernetes.io/service-account.name: safeguard in the same namespace.

    apiVersion: v1
    kind: Secret
    metadata:
      name: safeguard-token
      namespace: kube-system
      annotations:
        kubernetes.io/service-account.name: safeguard
    type: kubernetes.io/service-account-token
    
    kubectl apply -f secret.yaml
    

    Be clear eyed about this step. The Kubernetes service accounts page says that for applications outside the cluster the project recommends avoiding long lived token Secrets, because a leaked bearer token stays valid until someone deletes it. An outside posture tool needs some standing credential, so the practical answer is to contain it: a dedicated service account used for nothing else, a role limited to get and list with no access to secrets, a rotation date in your calendar, and deletion of the Secret the day you disconnect. If you would rather supply a kubeconfig, the connect form accepts one; ask Safeguard support which kubeconfig credential types it supports before you rely on short lived ones.

  3. Read the token.

    kubectl get secret safeguard-token -n kube-system -o jsonpath='{.data.token}' | base64 --decode
    
  4. Create a read only ClusterRole.

    kubectl create clusterrole safeguard-read --verb=get,list --resource=clusterrolebindings,clusterroles,roles,rolebindings,namespaces,nodes,pods,serviceaccounts,networkpolicies
    

    The docs note that resources outside the core API group are written as resource.group, for example replicasets.apps. If you run Gatekeeper or Kyverno and want those policies read, add their resources to the role in the same way, since the permissions list includes them and the one line command does not.

  5. Bind it to the service account.

    kubectl create clusterrolebinding safeguard-read --clusterrole=safeguard-read --serviceaccount=kube-system:safeguard
    
  6. Collect the other values. You need the API server URL (the docs give https://203.0.113.10:6443 as an example form) and, optionally, the cluster CA certificate in PEM form. A service account token Secret also includes the CA in its ca.crt data.

  7. Connect in Safeguard. On Compliance › Connectors, open Kubernetes, click Connect, choose API token, and fill in the API server URL, the service account token, the cluster CA certificate (paste the whole certificate including the BEGIN and END lines) and, optionally, a cluster name. Instead of the separate fields, you can supply a kubeconfig. Click Connect with token.

  8. Check the card status. Safeguard checks the credential with the provider and shows Verified, Not working (with the reason, such as a missing grant) or Unverified (the provider did not answer the last check). Admins can use Re-check, and Collect evidence now starts a collection immediately instead of waiting for the next scheduled run.

  9. Choose what the connector collects. The connector's "What this connector collects" panel lists the tests and evidence checks that read from it, each with a switch. If your workspace starts new connectors with everything off, turn on at least one before you connect.

  10. Read results on the Tests page. Tests run on a schedule, about every six hours, and each test runs as often as it is due, which is daily by default. To run them sooner, use Run now or Run all tests on Compliance › Tests. A newly added test first runs in a settling in period, which the docs say is typically 14 days, during which its results show on the Tests page but do not change any control's status or readiness score and open no tasks. After that period, it counts like any other test.

Credential handling and network reachability

The compliance connectors overview says credentials are encrypted at rest with authenticated encryption and that Safeguard never shows a saved secret again. It also says a self-hosted server must be reachable at a public https:// address, that Safeguard refuses private, loopback and cloud metadata addresses before it sends anything, and that if a vendor restricts API access by IP address, you should ask Safeguard support for the outbound address to allow.

For Kubernetes, that means the cluster's API server needs to be reachable from Safeguard. If your API endpoint is private today, do not make it public just for this. Talk to Safeguard support about the outbound address and use your provider's API server allowlist, so the endpoint stays closed to everyone else.

Several clusters

Connect each cluster separately and give it a clear cluster name so results stay attributable. A dedicated service account, role and binding per cluster also means you can revoke one cluster's access without touching the others.

Rotating and disconnecting

From a connected card you can Test connection, Reconnect after you rotate the token, Rename, Disconnect (which clears the credential, stops the connection's tests and keeps earlier results as history) or Remove the connector entirely. To rotate, create a new token Secret, reconnect with it, confirm the card shows Verified, then delete the old Secret.

Where policies and gates fit

Posture tests tell you about the cluster as it is. Policies and gates (GA) decide what is allowed to move toward it. In Safeguard, a gate evaluates linked policies and takes one of three actions: Block fails the gate, Warn passes it with a warning naming the policy, and Notify passes it and sends a notification. When a team has a legitimate reason to ship despite a failed policy, they request an exception, approvers are notified and decide, and the exception history is kept. The Safeguard CLI (GA) runs safeguard ci scan in your pipeline, which scans the push on Safeguard and can fail the build on vulnerabilities.

Used together, the split is clean: gates in CI stop known bad images and dependencies before they are deployed, and the Kubernetes tests tell you whether the cluster they land in is configured the way your baseline says.

Who sees what

Admins decide which connectors members of the organization can use, under Settings › Connector access or with Manage connectors on the Connectors page. A connector switched off there does not appear for members and the server refuses to connect it. Only the person who connected a connector or an administrator can change its collection switches. For platform teams, that means you can let GRC read results without handing them the ability to change what is collected.

What Safeguard does not do

  • It does not admit or deny pods. Safeguard's guardrails documentation says its Kubernetes admission controller is not published, and warns against installing any chart that claims to be one. Enforcement inside the cluster stays with Kubernetes features you run, such as Pod Security Admission labels and your network plugin's policy enforcement.
  • It does not read your secrets. The documented ClusterRole does not include secrets. That is good for least privilege, and it also means secret contents are outside what these tests see.
  • It does not change your cluster. The connection is read only. Removing a binding, labelling a namespace or adding a network policy is your change to make and review.
  • It does not cover Services and Ingress in the documented grant. The permissions list does not include Services or Ingress objects, so the exposure review in Step 5 stays a job you run yourself, or one you raise with Safeguard support before relying on the connector for it.
  • It does not certify anything. A passing test is evidence toward a control, not proof that the control is met, and it is not a CIS certification of your cluster. Your auditor still decides.
  • It does not decide your exceptions. Whether kube-system runs Privileged, or a monitoring agent keeps host networking, is a risk decision your team owns and records.
  • It does not replace image scanning or runtime monitoring. Posture is configuration. Vulnerable libraries in images and live behaviour are separate questions.
  • This post is not audit advice. It describes how the frameworks and the product work; your auditor and your own reading of each framework decide what you need.

Common mistakes

  • Treating the CIS score as the goal. The benchmark is a baseline. Some recommendations will not fit your environment. Record the decision instead of chasing a number.
  • Using the upstream benchmark on a managed cluster. Most control plane items are the provider's job there. Use the managed benchmark and save yourself a week of false findings.
  • Reviewing only cluster-admin. The escalation verbs, nodes/proxy, secret listing and workload creation rights matter just as much, and they show up in ordinary roles.
  • Leaving namespaces unlabelled. A namespace with no Pod Security label is not "Baseline by default" in any guaranteed sense. Label every namespace explicitly, including the ones that need Privileged.
  • Writing network policies on a plugin that does not enforce them. Check the plugin first.
  • Giving a scanner more than it needs. Any posture tool should get get and list on the resources it reads and nothing else. If a tool asks for cluster-admin, ask why.
  • Making the API server public to connect a tool. Use an allowlist for the tool's outbound address instead.
  • Forgetting the long lived token you created. Any token Secret you create for a tool, including Safeguard's, should be rotated on a schedule and deleted when the connection is removed.
  • Running the review once. Drift is the whole problem. A one time review is out of date within weeks.

FAQ

What is KSPM in Kubernetes?

Kubernetes security posture management is the repeated check of cluster configuration, workload specs, RBAC and exposure against a baseline such as the CIS Kubernetes Benchmark and the Pod Security Standards, with drift flagged and decisions recorded.

Is KSPM the same as CSPM?

No. Cloud security posture management checks the cloud account: storage, identity, networking and managed services. KSPM checks what happens inside the cluster: roles, pods, namespaces and network policies. Most teams need both, and they overlap at the managed control plane.

Which CIS Kubernetes Benchmark should I use?

Use the managed benchmark for your provider if you run EKS, AKS, GKE, OKE or OpenShift, and the upstream Kubernetes benchmark for self-managed clusters. Record the version you assessed against.

Does Safeguard enforce Pod Security Standards?

No. Safeguard reads pods, namespaces and related objects and runs tests that map to controls. Enforcement in the cluster is done by Kubernetes, for example through Pod Security Admission namespace labels.

What permissions does Safeguard need on my cluster?

get and list on cluster role bindings, cluster roles, roles, role bindings, namespaces, nodes, pods, service accounts and network policies, plus Gatekeeper constraints and Kyverno policies if you run them. No write permissions and no access to secrets.

Can I connect a cluster with a private API server?

The connectors docs say Safeguard refuses private and loopback addresses and that you can ask support for Safeguard's outbound address to allow through an IP restriction. Plan for an allowlisted endpoint rather than an open one, and confirm the setup with Safeguard support.

How often does Safeguard check the cluster?

The docs say tests run on a schedule, about every six hours, and each test runs as often as it is due, which is daily by default. You can run them sooner from Compliance › Tests.

Does a passing test mean my cluster is CIS compliant?

No. The docs say a passing result is evidence toward the controls it maps to, not proof on its own that a control is met. Treat it as one input to your assessment.

Can I use Gatekeeper or Kyverno with this?

The docs say Gatekeeper OPA and Kyverno connect to the same provider as Kubernetes and that the tests run for a connection made through any of them. The permissions list includes read access to their policy resources.

How do I stop bad images reaching the cluster?

Use policies and gates in CI. A gate can Block, Warn or Notify, and teams can request an exception that approvers decide on. That runs before deployment; the Kubernetes tests check the cluster after.

Related reading

The cluster tells you where risk can travel; the images and dependencies inside it are where most of that risk comes from. When a posture finding sits next to a vulnerable package in a running workload, closing the package gap is usually the fastest way to shrink the exposure.

Fix it without waiting for upstream

Whatever the vulnerability, most of the risk sits in two gaps. The first is the time between a fix being published and that fix actually running in your production builds. The second, and worse, is the time before any fix exists at all, while a maintainer works out a patch and a release schedule. Waiting through both gaps is a habit, not a requirement. Safeguard gives teams three ways to close them.

1. Autonomous remediation: pull requests, not tickets

When a fixed version exists, Safeguard's Griffin models open a tested, policy gated pull request that moves the affected dependency to the safe version. You can run it on one repository or in bulk across every project that carries the vulnerable version. Remediation categories include dependencies, licenses, security posture and findings, and each one is set separately. Reachability analysis ranks the vulnerable code paths your application actually calls first, so the first pull requests you merge are the ones that matter most. Autonomous remediation ships switched off, with every category set to Manual, so your team decides how much runs on its own and what still needs a human approval.

2. Gold Open Source: the safe version in seconds, free

gold.safeguard.sh is free and needs no login. Search any CVE or package to see affected and fixed versions, CVSS, EPSS, CISA KEV status and a recommended safe version, or use the "Am I affected?" checker. The same data is available through a free read API, README status badges and RSS threat feeds.

3. Gold Registry: start from components that are already fixed

Gold Registry provides hardened, drop in replacements for upstream packages and container images. Every Gold artifact is held continuously to zero exploitable critical or high CVEs and a completed license check, with signed build provenance (signed with Safeguard's key and verifiable with cosign, SLSA Build Level 3 as the design target) and a public evidence page you can hand to an auditor. An artifact loses its Gold badge if it regresses. Teams can point their own package directory at the registry so hardened equivalents resolve without changing how developers install anything.

When upstream has no fix yet, or will not ship one, Safeguard first works to get the fix accepted upstream. If the issue is severe or upstream will not move, Safeguard builds a fork, fixes the vulnerability there and publishes a hardened Gold build, so you are not stuck on a maintainer's release schedule. You can also request a hardened, compatibility tested build of a specific package. Ask which packages it covers before you plan around it.

Your situationWhat to use
A fixed version existsAutonomous remediation opens the upgrade pull request; Gold Open Source confirms the safe version
You need to know today whether you are affectedGold Open Source lookup and "Am I affected?" checker, free and without login
You want vulnerable versions to stop shippingSafeguard policies and gates in CI
Upstream has no fix yet, or will not ship oneA custom Gold request; fork and patch
You want to start clean on new projectsPull hardened components and images from Gold Registry

One honest limit: when the vulnerable code lives in a vendor appliance, a hosted service or an operating system runtime you do not build yourself, the fix still has to come from that vendor or distribution. The steps above apply to the open source dependencies and container images you build and ship, which is where most teams carry the largest and least tracked share of their exposure.

See how Safeguard would help

The first demo is a real Safeguard CLI session: install, open the interactive terminal, and ask it to fix a lodash CVE in a repository. It reads the finding and advisory, asks before any command that changes something, edits package.json, runs the install and tests with approval, and pushes nothing. That is the same CLI that runs safeguard ci scan in the pipeline, where gates decide what reaches your cluster.

Click through it at your own pace, or open it full screen.

The second demo connects Claude to the Safeguard MCP server with OAuth and chooses which tools Claude can use. It does not show the Kubernetes connector itself; it shows how an assistant gets scoped, approved access to your Safeguard data, which is how a platform engineer would ask questions about findings without opening every screen.

Click through it at your own pace, or open it full screen.

Quick check

A service account can get nodes/proxy but has no other rights. Is that a read only permission?

No. The Kubernetes RBAC good practices page says access to the nodes/proxy subresource gives rights to the Kubelet API, so get on nodes/proxy is not a read only permission. Treat it like a privileged grant.

Does Safeguard's Kubernetes connector need access to Secrets to run its tests?

No. The documented ClusterRole grants get and list on RBAC objects, namespaces, nodes, pods, service accounts and network policies, plus Gatekeeper and Kyverno policies. Secrets are not in the list.

Sources

To try it, download Safeguard or read the Safeguard docs.

Last reviewed: 25 October 2026. Product capabilities change; check docs.safeguard.sh for the current state.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.