One chart for kubeaid-agent and both exporters, plus Kubescape RBAC - #217
Merged
Conversation
… api The exporter now reads Kubescape as an alternative to Trivy. Every rule in this ClusterRole is consumed through a dynamic client, so without the grant the scanner is found through discovery and then fails every collection -- which at least fails loudly, but the feature is inert until this lands. vulnerabilitymanifests carries the per-CVE detail; the summaries kind holds counters only and is deliberately not read. workloadconfigurationscans is the control-scan equivalent of Trivy's three least-privilege report kinds. Unlike Trivy's CRDs these resources come from an aggregated APIService, so they vanish from discovery whenever the kubescape storage pod is down rather than persisting the way a CRD would. The README gains which-scanner-wins and the two fields that differ between them: relevant, which only Kubescape can answer, and os.eosl, which only Trivy can.
Collapses argocd-helm-charts/kubeaid-security-exporter into the agent chart, so a cluster gets both workloads from one Argo CD application instead of two, and there is one chart to maintain rather than two. They remain TWO Deployments with TWO ServiceAccounts. That is the point of the arrangement, not an accident of it: a pod carries a single ServiceAccount, so running the exporter as a sidecar would hand the workload holding the Obmondo mTLS credential the exporter's cluster-wide read across seven API groups -- undoing, one layer down, the separation that splitting them achieved. It also bounds failure: a collection pass holds every VulnerabilityReport in memory at once, and a sidecar OOM would take the agent down with it, silencing the cluster-liveness ping that tells the portal a cluster is alive. The exporter's Service name is pinned to kubeaid-security-exporter rather than derived from the release name. The agent's default appConfig.securityPosture.exporterURL is that literal string, and a release-prefixed Service would leave the agent polling a host that does not resolve -- which fails quietly, because a failed poll only sets a metric and submits nothing. The helper says so, so nobody "fixes" it later. securityExporter.enabled: false runs the agent alone. The agent already tolerates a missing exporter, so that switch and appConfig.securityPosture.enabled stay independent. backup-exporter is deliberately left as its own chart. Its values are some two hundred lines of S3 credentials, RPO policy and four alert blocks for Postgres, Velero, MongoDB and sealed-secrets, none of which the agent has anything to do with; folding it in would make the agent chart mostly backup configuration, and would drag five docs pages and a promtool CI job along with it.
…ity-exporter
Collapses argocd-helm-charts/backup-exporter into the agent chart alongside the
security exporter, so one Argo CD application deploys all three workloads and
there is one chart to maintain instead of three. The security exporter also
loses its kubeaid- prefix, matching backup-exporter's naming.
All three stay SEPARATE Deployments with SEPARATE ServiceAccounts. A pod carries
one ServiceAccount, so running the exporters as sidecars would hand the workload
holding the Obmondo mTLS credential their cluster-wide read -- undoing, one layer
down, the separation that splitting them out achieved.
Two names are pinned rather than release-derived, and both would have failed
silently otherwise:
- backup-exporter. The agent discovers it by listing Deployments AND Services
with app.kubernetes.io/name=backup-exporter
(internal/core/backup/exporter.go). Derived from .Chart.Name that label
would read "kubeaid-agent", the selector would match nothing, and discover()
would return errExporterAbsent -- indistinguishable from "not installed", so
backups would simply stop being reported. Its upstream fullname also fell
back to a bare .Release.Name, which here would have collided head-on with
the agent's own Deployment and Service.
- security-exporter. The agent reaches it at the Service name in
appConfig.securityPosture.exporterURL, which is updated to match.
Both exporters are independently switchable via backupExporter.enabled and
securityExporter.enabled; the agent already tolerates either being absent.
The promtool workflow is repointed at the new chart path and template names, and
the rule fixtures move with it. The backup-exporter guide, monitoring and
backup-restore docs are updated, including re-nesting the guide's values example
under the backupExporter key.
Verified by rendering: three Deployments, three ServiceAccounts, three
ClusterRoles, no name collisions, both exporters carrying the labels the agent
selects on, every enable toggle honoured, and the promtool step reproduced
locally (8 rules, unit tests pass).
Follow-up to the rename. The chart component is called security-exporter now, but several places still named the old one, and the README's values table was outright wrong: it documented the exporterURL default as http://kubeaid-security-exporter while the actual default and the rendered Service are both security-exporter. Anyone setting that value by hand from the table would have pointed the agent at a host that does not resolve, which fails quietly -- a failed poll only sets a metric. Also renames the alert group to match the component, and updates the schema descriptions, values comments and the RBAC comment. The two remaining occurrences are correct and stay: the upstream repository is still EnableIT/kubeaid-security-exporter and the image is still ghcr.io/obmondo/kubeaid-security-exporter. Only the in-chart component was renamed.
The backup exporter cannot start without configuration. Every backend it reports on -- Postgres, Velero, MongoDB, sealed-secrets -- needs S3 credentials and a bucket, and there is no sane default for any of them. Shipping it enabled meant a fresh cluster deployed a pod that could not do its job. The security exporter stays on: it needs no credentials, discovers its sources through the API, and reports "not installed" where none are present. kubeaid-cli has no support for supplying those S3 credentials yet, so until it does, enabling this is a deliberate per-cluster act alongside the backupExporter.exporter.<backend>.s3 settings.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Collapses the three charts that make up a cluster's Obmondo reporting into one, and teaches the
security exporter to read Kubescape as well as Trivy.
One chart, one Argo CD application
argocd-helm-charts/kubeaid-agentnow ships all three workloads.backup-exporterandkubeaid-security-exporterare removed as separate charts, and the security exporter drops itskubeaid-prefix to matchbackup-exporter's naming.kubeaid-agentsecurity-exporter/api/v1/security-posture. Holds cluster-wide read; talks to nothing outside the cluster.backup-exporterThree Deployments with three ServiceAccounts, not sidecars. A pod carries one ServiceAccount, so
co-locating them would hand the workload holding the Obmondo credential the exporters' cluster-wide
read — undoing, one layer down, the separation that splitting them out achieved. It also bounds
failure: a security collection pass holds every VulnerabilityReport in memory at once, and a sidecar
OOM there would take the agent down with it, silencing the cluster-liveness ping.
Each exporter is independently switchable:
securityExporter.enabled,backupExporter.enabled.Two names are pinned, and both would have failed silently
backup-exporter— the agent discovers it by listing Deployments and Services withapp.kubernetes.io/name=backup-exporter(internal/core/backup/exporter.go). Derived from.Chart.Namethat label would readkubeaid-agent, the selector would match nothing, anddiscover()would returnerrExporterAbsent— indistinguishable from "not installed", so backupswould simply stop being reported. Its upstream
fullnamealso fell back to a bare.Release.Name,which here would have collided head-on with the agent's own Deployment and Service.
security-exporter— the agent reaches it at the Service name inappConfig.securityPosture.exporterURL, updated to match.Kubescape as a second vulnerability source
The exporter's
Sourceinterface, discovery-based scanner detection and theRelevantfield alreadyexisted but were never wired to anything. This grants the RBAC that makes Kubescape readable:
spdx.softwarecomposition.kubescape.io(vulnerabilitymanifests,workloadconfigurationscans).Served by an aggregated APIService rather than CRDs, which is why detection uses API discovery — a
CRD-existence check would silently never find it. Exactly one scanner is active at a time, Trivy
first by precedence.
The exporter-side Go implementation is in
EnableIT/kubeaid-security-exporter
on
feat/kubescape-source.Also here
promtoolworkflow repointed at the new chart path and template names; rule fixtures moved with it.backupExporter),monitoring.md,backup-restore.md.comments-indentationwarnings and a missing trailing newline inherited from the oldbackup-exporter values — CI runs
yamllint --strict, where warnings fail.exporterURLdefault, which no longer matched the actual default.Verification
Rendered the chart and checked: three Deployments, three ServiceAccounts, three ClusterRoles, no name
collisions, both exporters carrying the labels the agent selects on, the agent's rendered
exporterURLmatching the rendered Service name, and every enable toggle honoured.helm lintandyamllint --strictclean. The promtool CI step reproduced locally: 8 backup rules + unit tests pass,1 security rule checks.
Before merging
ghcr.io/obmondo/kubeaid-security-exporter:v0.1.0,which does not exist yet. With
securityExporter.enableddefaulting totrue, merging firstgives every cluster an
ImagePullBackOffon the new Deployment. Tag it, or default it tofalseuntil the image ships.backup-exporteras its ownapplication will have that app and this chart both claiming identically-named objects. The old
apps need deleting, and
kubeaid-clineeds to stop creating them — not touched in this PR.