Repository navigation
feat: a workload can refuse the profiler without refusing the rest (ADR 0071) - #109
Merged
Merged
Conversation
…DR 0071) The four controls in security.md §11 are one control at four scopes — do not collect this — so declining a ten-second capture meant giving up every rollup and build fact about the service. A fifth control, `rebuildstack.co/profile: "false"`, excludes profiling and nothing else. It reads at the same three levels as the collection opt-out, in the same order, only on "false", and on the workload object rather than its pod template. It stops both profiling paths and the endpoint confirmation with them, so the promise is "the agent does not connect to it" with no exception. All five controls are refusals, so the opt-out model gains a scope rather than a second shape. Beside it: every pull attempt writes one line naming the workload and its outcome, so "who did you profile, and when" is answerable inside the cluster rather than from a payload the unbuilt transport never delivers; and NOTES.txt discloses at install time that the agent connects to workloads and starts profilers in them. Coverage gains two numbers with different subjects: pods excluded from profiling, and endpoint targets the funnel dropped. The second is a gauge on `pprof_targets` rather than an outcome on `pprof_pulls_total` — no pull is attempted, and the number falls when an annotation is removed, which a counter may not do. Both prose ceilings move, for that one obligation. make test && make chart-lint && make lint — green Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KeZECJXTDHL6Nts95eKMJA
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.
The four controls in
security.md§11 are one control at four scopes — do notcollect this — so declining a ten-second capture meant giving up every rollup
and build fact about the service. A fifth control,
rebuildstack.co/profile: "false", excludes profiling and nothing else.Pulling stays on by default; ADR 0058 settled that and this does not reopen it.
The control
Read at the same three levels as the collection opt-out, in the same order, only
on
"false", and on the workload object rather than its pod template. It isdecided in
PodWatcher.admitfrom the owner-chain walk that already happens, sono new lister, no new API read, no second traversal.
It stops both profiling paths and the endpoint confirmation with them, so the
promise is "the agent does not connect to it" with no exception to explain. Three
places read the one flag:
targeting.Publisher(an excluded workload takes notopNplace),ContainersOnNode(the only source of container IDs a node'sprofiler acts on), and
PodAddress(the only place a pod address is read atall). The candidate funnel is filtered too — a target confirmed before the
annotation would otherwise hold one of the ten pull slots every cycle forever.
Per pod where the path allows it; a workload leaves a ranking or a funnel only
when every indexed pod of it carries the annotation, and a workload with no pods
does not leave at all — a scale to zero is not something the customer asked for.
All five controls are refusals, so the opt-out model gains a scope rather than a
second shape. ADR 0071 §1 argues that; §3 covers the fail-open on a controller
the agent cannot read, counted by ADR 0028's existing two numbers.
Beside it
The log trail. Every pull attempt writes one line —
pprof profile pull,with namespace, workload, container, digest, seconds and outcome — so "who did
you profile, and when" is answerable inside the cluster rather than from a
payload the unbuilt transport never delivers. Bounded by the same construction
that bounds the profiling: ≤10 per cycle, ≤2880 lines a day.
The install disclosure.
NOTES.txtwarned about root,hostPIDand anunenforced CNI and said nothing about connecting to workloads and starting
profilers in them. It now does, rendered only where that actually runs.
Coverage. Two numbers, different subjects:
filter.excluded_profiling_annotation(pods) and
pprof.excluded_by_annotation(endpoint targets). The second is agauge on
pprof_targets, not an outcome onpprof_pulls_total: no pull isattempted, and the number falls when an annotation is removed — which a
Prometheus counter may not do, as
TestCountersAndGaugesAreTypedByWhetherTheyCanFallwould have caught.
Docs
ADR 0071,
Amends: 0025, 0028, 0057, 0058with the mirror lines. 0025 is in thatlist because its Consequences stated "there is no longer a way to profile less
than what is collected", and that is what changed — by the annotation route that
ADR called additive, not by the configured list it deleted.
security.md§10.3 and §11 (four → five, and the table row); two normativesentences in
backend-requirements.md. Both prose ceilings move, for that oneobligation, which is what the diff shows.
Evidence
Green, and green again from a clean
git archive HEADextraction.NOTES.txtrendered for
metrics-only(silent),inventory, andpull=false.New tests: every annotation level and value, fail-open on an unreadable
controller, collected-but-not-profiled, one opted-out replica of a profiled
workload, a workload with no pods; the funnel counting distinct targets rather
than candidates; one log line per attempt naming the workload; both metric
series with their types; the excluded top consumer taking no
topNplace.🤖 Generated with Claude Code
https://claude.ai/code/session_01KeZECJXTDHL6Nts95eKMJA