Skip to content

feat(operator): east-west context provider — identity MMDB + deltas (per-pod, labels), declared-edge deltas#47

Merged
pigri merged 8 commits into
mainfrom
feat/east-west-producers
Jul 3, 2026
Merged

feat(operator): east-west context provider — identity MMDB + deltas (per-pod, labels), declared-edge deltas#47
pigri merged 8 commits into
mainfrom
feat/east-west-producers

Conversation

@pigri

@pigri pigri commented Jun 28, 2026

Copy link
Copy Markdown
Contributor

The operator as the Kubernetes context provider for east-west / identity-aware microsegmentation. The operator holds the live pod→workload state and produces the identity + declared-edge artifacts the agent consumes; the service graph itself is built by the agent (works on-prem, no operator dependency), so the operator's own GraphProducer is dropped and workload classification is folded into the identity output.

Workload identity (MMDB baseline + event-driven deltas)

  • Pod IP → {workload, namespace, app}, uploaded to download-api; event-driven off the Pod informer with coalesced deltas (sub-second freshness) plus a periodic full baseline for cold-start / resync.
  • Per-pod identity for StatefulSet pods, generalized to any ordinal controller (e.g. StrimziPodSet).
  • Pod labels (k8s-internal churn keys filtered out) carried in the MMDB record and the delta, for identity.k8s.{src,dst}_label rules.
  • Workload classification (role / internet-exposed / control-plane), narrowed to true control-plane components, folded into the identity entry.

Declared-edge allow-list (baseline + deltas)

  • Compiles cluster NetworkPolicy into a declared-edge allow-list (workload→workload:port + governed destinations) for the agent's edge.* fields.
  • Event-driven EdgeProducer: on NetworkPolicy / Pod / Namespace change, emits an incremental EdgeDelta (allow-list lines added/removed, tagged epoch/seq for gap detection) to download-api, plus a periodic full baseline.

Rebased onto current main. go build ./..., go vet ./..., and go test ./... all pass.

Consolidation note: supersedes #50 — this adopts the context-only / agent-built-graph architecture and grafts in #50's per-pod identity, pod-label, and edge-delta work. (#50's GraphProducer-in-operator path is intentionally dropped; its NetworkPolicy-port-on-graph-vertices change lived only in the dropped GraphProducer and is not carried over.)

@pigri pigri force-pushed the feat/east-west-producers branch from ccc98cf to 5ce1097 Compare June 28, 2026 18:58
pigri added 8 commits July 3, 2026 09:37
…vice-graph-api

A leader-elected producer (--graph-producer) that uploads workload identities +
NetworkPolicy declared edges to service-graph-api over REST, which writes them
into the Apache AGE service_graph. The operator stays REST-only (no DB),
mirroring the Identity/Edge producers.

Extracts the NetworkPolicy walk into a shared walkPolicyEdges helper so
buildEdgeDoc (agent allow-list) and the graph producer derive edges from one
interpretation (buildEdgeDoc output unchanged). Content-hash gated full
snapshot; stdlib-only (no new deps).
…ontrol-plane)

The GraphProducer now derives node classification from pure Kubernetes state and
sends it on each workload vertex:
- internet_exposed: pod selected by a LoadBalancer/NodePort Service, or by a
  Service referenced from an Ingress backend
- control_plane: kube-system, or a named core component (apiserver/etcd/...)
- role: derived (control-plane > internet-exposed > internal)

Lists Services + Ingresses (RBAC added, read-only); failures degrade gracefully
(identities + declared edges still upload). Unit-tested.
…nents

Was painting all of kube-system control-plane. Now matches only the actual
control plane by name (kube-apiserver / etcd / kube-controller-manager /
kube-scheduler / cloud-controller-manager / ccm); add-ons like cert-manager,
CNI, autoscalers, DNS, kube-proxy are internal.
… drop GraphProducer

The operator no longer builds/writes the service graph (that moves to the
Synapse agent so it works on-prem). It stays a k8s-context provider:

- IdentityProducer now folds internet-exposed (LoadBalancer/NodePort/Ingress)
  and control-plane classification into each identity MMDB record
  (internet_exposed/control_plane), so the agent can fold the declared layer in.
  Lists Services/Ingresses; classification moved to classify.go.
- Remove GraphProducerReconciler + --graph-producer/--service-graph-url wiring.
- EdgeProducer (policy-edges) unchanged.

The agent assembles + uploads the graph from these artifacts + its own observed
flows/fingerprints.
StatefulSet replicas (postgres core-0/1/2, kafka brokers) have stable
per-ordinal identities and talk to each OTHER — DB streaming replication,
inter-broker traffic. Keying them by the set name collapsed all replicas to
one ref, so that traffic became a self-loop and was invisible in the graph.
Key StatefulSet pods per-pod (core-0/core-1/core-2) so replicas are distinct
vertices and their mutual edges are real. Deployments stay aggregated.
…PodSet)

Kafka brokers are owned by Strimzi's StrimziPodSet, not a StatefulSet, so the
StatefulSet-only check missed them. Key per-pod for ANY controller whose pods
are <controller>-<ordinal> (StatefulSet, StrimziPodSet, ...), so kafka brokers
(core-kafka-0/1/2) also become distinct vertices. Deployment pods (random RS
suffix) still aggregate.
Attach each pod's labels (dropping k8s-internal churn keys like
pod-template-hash / controller-revision-hash) to the identity record — written
as a nested map in the MMDB baseline and carried in the delta upserts — so the
agent can evaluate identity.k8s.{src,dst}_label["<key>"] rules.
Mirror the identity delta producer for declared edges. The EdgeProducer becomes
informer-driven: on NetworkPolicy/Pod/Namespace change it emits an incremental
EdgeDelta (allow-list lines added/removed, tagged with epoch/seq for gap
detection) to download-api, alongside a periodic full allow-list baseline for
cold-start/resync. Factor the cluster-state reads into edgeInputs(), shared by
the baseline build (buildAndUpload) and the delta flush (flushDelta).

main.go wires the informer event handlers; tests cover the delta emission.
@pigri pigri force-pushed the feat/east-west-producers branch from e3f5081 to 2b8622a Compare July 3, 2026 07:39
@pigri pigri changed the title feat(operator): east-west producers — identity MMDB, declared edges, AGE service_graph feat(operator): east-west context provider — identity MMDB + deltas (per-pod, labels), declared-edge deltas Jul 3, 2026
@pigri pigri merged commit ff87a2e into main Jul 3, 2026
2 checks passed
@pigri pigri deleted the feat/east-west-producers branch July 3, 2026 07:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant