Security

Stop the second step.

Getting into one container is step one. Reaching the database, the namespace next door or the open internet is step two, and step two is what turns an incident into a breach. KubeAid ships the controls that make step two fail. It also reports, pod by pod, whether those controls are on.

Where a control is opt-in rather than on by default, this page says so.

Ciliumon every cluster kubeaid-cli builds
Ingress + egressdefault-deny, opt-in per namespace
Per podenforcement reported, not assumed
AGPL-3.0every policy is public
The second step

What an attacker reaches for next, and what is in the way.

One compromised pod, four moves. Each move meets a control that ships with the cluster.

01 · Move

A pod gets compromised

A vulnerable dependency, a leaked token, a bad base image. Assume it happens.

In the way

Trivy Operator scans what is running rather than what was pushed, so that image already has a report in the cluster: CVSS score, installed version, fixed version, advisory link. version-checker says whether a newer tag exists upstream.

02 · Move

It looks around the namespace

The database, and the admin service two pods over.

In the way

Under the default-deny policy the namespace refuses ingress and egress for every pod in it. The one exception is DNS to kube-dns. Nothing else answers, and nobody had to put anything on a blocklist first.

03 · Move

It calls out to the internet

To pull the second stage, or to ship your data somewhere.

In the way

The same policy denies egress, and the block is also the detection. Cilium exports every drop as a Hubble metric, and a sustained run of policy-denied drops raises an alert, so a workload reaching for something it should not is something you hear about rather than something you find months later.

04 · Move

It runs something on the node

A shell, a miner, or a read of a file it has no business reading.

In the way

Tetragon or KubeArmor sees the exec in the kernel. eBPF reports the event, and Linux Security Module hooks can refuse the operation before it runs. On bare metal the Cilium host firewall also limits what the node answers at all.

What ships

Six layers, every one of them a chart you can read.

Nothing here is a KubeAid invention you have to take on faith. We configure upstream open source, version it in your repository, and update it weekly.

Network

Every cluster kubeaid-cli builds runs Cilium. The kubeaid-addons chart renders a default-deny CiliumNetworkPolicy per namespace, which turns ingress and egress off for every pod in it and allows DNS to kube-dns. Where a workload needs more, you name the pods that get it. Platform components carry their own policies: Argo CD, Harbor, SonarQube, PostgreSQL.

Ships ascilium · kubeaid-addons · CiliumNetworkPolicy

Runtime

Tetragon or KubeArmor, one per cluster. Tetragon reads process execution, network activity and file access as kernel events over eBPF. KubeArmor enforces at the Linux Security Module hook and denies an operation before it executes. Both install observing. Arming enforcement is a value you set.

Ships astetragon · kubearmor · eBPF + LSM

Supply chain

Trivy Operator or Kubescape scans every image in the cluster and keeps the findings as report objects rather than a lossy metric. Kubescape adds relevancy, meaning whether the vulnerable code ever loaded at runtime. version-checker watches upstream tags, and a Kyverno policy can route image pulls through a Harbor proxy cache instead of straight to a public registry.

Ships astrivy-operator · kubescape · version-checker · harbor

Secrets

Secrets live in your Git repository encrypted, sealed to the key of the cluster that may open them, and only the controller inside that cluster can decrypt them. kubeaid-cli installs that controller while it builds the cluster. cert-manager issues the public certificates, and step-ca can run as an internal CA for the private ones.

Ships assealed-secrets · cert-manager · step-ca

Access

NetBird carries access as an overlay network rather than an open port on the internet, with Keycloak as the SSO in front of it. That is the current access layer. Clusters set up earlier front it with Teleport instead, which issues short-lived certificates and records the session, so no long-lived kubeconfig circulates either way.

Ships asnetbird · keycloak · teleport

Recovery

Velero backs the cluster up, and kubeaid-cli takes the first Velero and sealed-secret backups while it builds the cluster. The cluster itself is declared in your own repository, so you re-apply it instead of rebuilding it from memory.

Ships asvelero · argocd · cluster-api
Read the chart docs
Measured

A policy that exists is not a policy that is enforced.

A workload can ship a NetworkPolicy whose selector matches nothing. It looks protected in Git and is wide open in the cluster, and every tool that counts policies will tell you it is fine. So we do not count policies. We read what Cilium computed for the pod itself and report enforcement per workload.

kubeaid-security-exporter collects it inside the cluster. It creates nothing, changes nothing, and talks to nothing outside the cluster. Where the endpoint status has not been populated, the answer is null, and we never round that up to "unprotected".

Your cluster sends that snapshot to Obmondo over mTLS, and it carries workload names, the images they run with their findings, and the enforcement flags below. No application data, no logs, no secret contents.

One workload from /api/v1/security-posture
{ "namespace": "demo", "kind": "Deployment", "name": "api", "app": "demo-api", "ships_policy": true, "ingress_enforced": true, "egress_enforced": null, "policies": ["demo/demo-api-allow"]}
  • ships_policy is true when the application manifests include a policy
  • ingress_enforced is true when Cilium enforces ingress on every endpoint
  • egress_enforced of null means unknown, not off
The node

The host has a firewall too, and it is a file in your repository.

Cilium host firewall renders a cluster-wide policy for the nodes themselves. It is for bare metal, where the public NIC needs the filter; on cloud clusters the provider security groups do that job and it stays off. SSH answers only the sources you list, and listing none leaves it open, so that list is the control. It is a diff you review, not a console you click, and it rolls out canary-first, because a bad rule set here takes the cluster with it.

The same review path covers every other control on this page. If it is not in Git, it is not running.

values-cilium.yaml, in your config repository
hostNetworkPolicy: enabled: true allowSshFrom: - 203.0.113.10/32 - 203.0.113.11/32 publicPorts: [80, 443] apiserverSourceCIDRs: - 198.51.100.21/32 - 198.51.100.22/32
Straight answers

What we do not claim.

Security pages usually read as if every switch were already on. Here is where ours are not.

01

Default-deny is opt-in, namespace by namespace

Turning it on is one value in your config repository, and we turn it on with you rather than for you. Flipping a running namespace to deny-all without knowing its egress is how you cause the outage you were trying to prevent.

02

Runtime engines install observing

KubeArmor ships in audit. It logs violations and blocks nothing until you set a posture to block. We would rather tell you that than let you assume an enforcement you do not have.

03

Unknown is reported as unknown

Where Cilium has not computed enforcement for a pod, the posture says null. Calling that unprotected inflates the problem; calling it protected hides one.

04

All of it is open source you can audit

Every control on this page is upstream open source under AGPL-3.0, configured in charts you can read, running in your cluster against your repository. Cancel the subscription and all of it keeps running.

Inspection

Mapped to the controls an auditor asks about.

The defaults map to ISO 27001:2022 and cover GDPR and NIS2 goals, with DORA and CIS 18 in scope. Obmondo publishes the mapping control by control, including where we judge the standard control to be the wrong tool and say what we do instead.

ISO 27001:2022GDPRNIS2DORACIS 18

Bring us the cluster you are worried about.

A 30-minute call with an engineer who runs this stack in production. We will look at what is enforced today, not at what a datasheet says should be.