Repository navigation
feat: node → controller profile transport + join (ADR 0011, slice 5.5) - #31
Merged
Merged
Conversation
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>
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.
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.ProfileReportwire type +ProfileHandleron 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;NewServermounts both routes.onProfilejoins pod UID / container ID → namespace, workload, image digest via PodWatcher (exactly as inventory joins), thenSpool.WriteProfile. An unjoinable profile (informer lag / filtered-out pod) is counted and dropped, never guessed (ADR 0010 §5).Sender (node)
profileShippermirrorsreportShipper(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-lintboth GOOS — clean.Boundary
The receiver is live; the node-side ship invocation +
-profile-endpointflag + per-container grouping and cadence ride with the live pipeline in slice 6. No newsecurity.mdchange: §7.2 already states profiles leave the node only toward the in-cluster controller.🤖 Generated with Claude Code