Skip to content

feat: node → controller profile transport + join (ADR 0011, slice 5.5) - #31

Merged
kfeofantov merged 1 commit into
mainfrom
feat/ebpf-profile-transport
Aug 11, 2026
Merged

kfeofantov merged 1 commit into
mainfrom
feat/ebpf-profile-transport

Conversation

@kfeofantov

Copy link
Copy Markdown
Contributor

Slice 5.5 (plan, ADR 0011). Where a profile actually leaves the node: shipped node→controller (node-initiated, projected-token auth — the ADR 0010 pattern), joined to a workload, and spooled.

Receiver (controller, live now)

  • nodeintake.ProfileReport wire type + ProfileHandler on a second endpoint /v1/node-profile, mirroring the inventory handler's one-way discipline (reply = ack, never anything the node acts on). Same token verifier, same port, same NetworkPolicy; NewServer mounts both routes.
  • onProfile joins pod UID / container ID → namespace, workload, image digest via PodWatcher (exactly as inventory joins), then Spool.WriteProfile. An unjoinable profile (informer lag / filtered-out pod) is counted and dropped, never guessed (ADR 0010 §5).

Sender (node)

  • profileShipper mirrors reportShipper (shared projected-token read). The node attaches only what it can see locally (pod UID / container ID, PID, capture window) + the already-filtered pprof bytes (ADR 0011 §4) — it never sends env/workload identity (it holds no Kubernetes identity).

Transport confidentiality

Plain HTTP, consistent with the inventory channel (ADR 0010's honest tradeoff): the bytes are already allow-list-filtered — only symbols approved to leave the cluster — and the token is the authentication; TLS is the named upgrade path. (Your call, P1, confirmed.)

Tests

Handler: valid → 202 + decoded report + caller identity; bad/missing token → 401; unknown-field / trailing-data → 400. Shipper: POST with Bearer + JSON round-trip; nil in capture-only mode; non-2xx → error. go test -race, build darwin + GOOS=linux, golangci-lint both GOOS — clean.

Boundary

The receiver is live; the node-side ship invocation + -profile-endpoint flag + per-container grouping and cadence ride with the live pipeline in slice 6. No new security.md change: §7.2 already states profiles leave the node only toward the in-cluster controller.

🤖 Generated with Claude Code

Ship a validated, allow-list-filtered profile from the node to the controller
(node-initiated, projected-token auth — the ADR 0010 pattern) and have the
controller join it to a workload and spool it. This is where a profile actually
leaves the node.

- internal/nodeintake: a ProfileReport wire type + ProfileHandler on a second
  endpoint (/v1/node-profile), mirroring the inventory handler's one-way
  discipline (the reply is an ack, never anything the node acts on). Shares the
  token verifier and NetworkPolicy; NewServer now mounts both routes on the one
  port. The node attaches only what it can see locally (pod UID / container ID);
  environment/workload identity is never sent by the node.
- cmd/agent: a profileShipper mirroring reportShipper (shared projected-token
  read); the controller's onProfile joins pod UID / container ID -> namespace,
  workload, image digest via PodWatcher and calls Spool.WriteProfile, counting
  and dropping an unjoinable profile rather than guessing (ADR 0010 section 5).
- Transport is plain HTTP, consistent with the inventory channel (ADR 0010's
  honest tradeoff): the bytes are already allow-list-filtered — only symbols
  approved to leave the cluster — and the token is the authentication; TLS is the
  named upgrade path.

The controller receiver is live; the node-side ship invocation + endpoint flag +
per-container grouping and cadence ride with the live pipeline in slice 6.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@kfeofantov
kfeofantov merged commit aa6b3ff into main Aug 11, 2026
3 checks passed
@kfeofantov
kfeofantov deleted the feat/ebpf-profile-transport branch August 11, 2026 19:39
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