Skip to content

Tighten resource attribution in the Stackdriver event sink#1186

Open
erain wants to merge 1 commit into
GoogleCloudPlatform:masterfrom
erain:event-resource-attribution-hardening
Open

Tighten resource attribution in the Stackdriver event sink#1186
erain wants to merge 1 commit into
GoogleCloudPlatform:masterfrom
erain:event-resource-attribution-hardening

Conversation

@erain
Copy link
Copy Markdown
Contributor

@erain erain commented May 12, 2026

Summary

When the event-exporter maps a corev1.Event onto a Stackdriver MonitoredResource, the Pod/Node labels are taken from the event's involvedObject reference. These reference fields are not cross-checked against the event's own metadata.namespace, which is the value the API server validates when an event is created.

This change adds that cross-check inside resourceFromEvent:

  • Pod events must satisfy event.Namespace != \"\" and event.Namespace == event.InvolvedObject.Namespace. When the check passes, namespace_name is sourced from event.Namespace directly. Otherwise the entry falls back to the default cluster-scoped resource.
  • Node events (which have no per-event namespace to compare against) are attributed to k8s_node only when the event originates from one of default, kube-system, or kube-node-lease. Otherwise the entry falls back to the default cluster-scoped resource.

The fallback preserves the log content under the cluster resource, so events that don't pass the check are still exported and inspectable; they just stop being attributed to the workload they reference.

Test plan

  • go test -mod=vendor ./... in event-exporter/ is green.
  • monitored_resource_factory_test.go gains coverage for: pod event whose event namespace disagrees with the involved object, pod event with empty event namespace, node event in trusted namespace, node event in untrusted namespace.
  • log_entry_factory_test.go cases updated to populate event.Namespace consistent with the new requirement; pod-label enrichment path still exercised end-to-end.

@erain
Copy link
Copy Markdown
Contributor Author

erain commented May 13, 2026

Pushed f85462c to address the review feedback:

  • Dropped default from the trusted set in monitored_resource_factory.go; only kube-system and kube-node-lease now produce a node-scoped MonitoredResource. Pod attribution is unchanged (still requires event.Namespace != "" and event.Namespace == event.InvolvedObject.Namespace, with namespace_name sourced from event.Namespace).
  • monitored_resource_factory_test.go: the previous defaultk8s_node case now asserts the cluster fallback; a kube-node-leasek8s_node case is added so both trusted namespaces are covered.
  • log_entry_factory_test.go: node fixtures switched from default to kube-system so the trusted-namespace path is still exercised.

go test -mod=vendor ./... from event-exporter/:

?   	github.com/GoogleCloudPlatform/k8s-stackdriver/event-exporter	[no test files]
ok  	github.com/GoogleCloudPlatform/k8s-stackdriver/event-exporter/kubernetes/podlabels	(cached)
?   	github.com/GoogleCloudPlatform/k8s-stackdriver/event-exporter/kubernetes/watchers	[no test files]
ok  	github.com/GoogleCloudPlatform/k8s-stackdriver/event-exporter/kubernetes/watchers/events	(cached)
?   	github.com/GoogleCloudPlatform/k8s-stackdriver/event-exporter/sinks	[no test files]
ok  	github.com/GoogleCloudPlatform/k8s-stackdriver/event-exporter/sinks/stackdriver	0.820s
?   	github.com/GoogleCloudPlatform/k8s-stackdriver/event-exporter/utils	[no test files]

@JeffLuoo
Copy link
Copy Markdown
Contributor

/lgtm
/approve

When mapping a corev1.Event onto a Stackdriver MonitoredResource with
InvolvedObject.Kind == "Pod", only emit a k8s_pod resource when the
event's own metadata.namespace is set and equals
event.InvolvedObject.Namespace. Use event.Namespace (the value the API
server validates against RBAC at event creation time) to populate the
namespace_name label. Events that fail the check fall back to the
default cluster-scoped resource so the log content is still exported.

Node attribution is intentionally unchanged in this PR; it will be
addressed separately.

Updates the existing pod test to populate event.Namespace and adds
cases that cover the new fallback paths.
@erain erain force-pushed the event-resource-attribution-hardening branch from f85462c to 208ca39 Compare May 22, 2026 20:21
@erain
Copy link
Copy Markdown
Contributor Author

erain commented May 22, 2026

Force-pushed 208ca39 to scope this PR strictly to Pod attribution:

  • Removed trustedNodeEventNamespaces and reverted resourceFromEvent so the Node case goes straight to buildNodeMonitoredResource(event) exactly as on master. Node attribution will be addressed in a follow-up PR.
  • Kept the Pod fix: k8s_pod is emitted only when event.Namespace != "" and event.Namespace == event.InvolvedObject.Namespace; namespace_name is sourced from event.Namespace; otherwise fall back to the cluster resource.
  • monitored_resource_factory_test.go: keeps the matching-namespace pod case, adds mismatched-namespace and empty-event-namespace fallback cases; node-allowlist cases removed.
  • log_entry_factory_test.go: only the pod fixture gains ObjectMeta.Namespace; node fixtures are back to their original (no namespace) form.

go test -mod=vendor ./... from event-exporter/:

?   	github.com/GoogleCloudPlatform/k8s-stackdriver/event-exporter	[no test files]
ok  	github.com/GoogleCloudPlatform/k8s-stackdriver/event-exporter/kubernetes/podlabels	(cached)
?   	github.com/GoogleCloudPlatform/k8s-stackdriver/event-exporter/kubernetes/watchers	[no test files]
ok  	github.com/GoogleCloudPlatform/k8s-stackdriver/event-exporter/kubernetes/watchers/events	(cached)
?   	github.com/GoogleCloudPlatform/k8s-stackdriver/event-exporter/sinks	[no test files]
ok  	github.com/GoogleCloudPlatform/k8s-stackdriver/event-exporter/sinks/stackdriver	0.829s
?   	github.com/GoogleCloudPlatform/k8s-stackdriver/event-exporter/utils	[no test files]

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.

2 participants