Skip to content

Project ConfigMap and Secret consumers by mode (#410 P1, core) - #503

Merged
hellices merged 7 commits into
mainfrom
feat/501-config-consumers
Oct 29, 2026
Merged

hellices merged 7 commits into
mainfrom
feat/501-config-consumers

Conversation

@hellices

Copy link
Copy Markdown
Owner

Closes #501

Summary

The core half of slice P1 of #410: given a ConfigMap or Secret, find every Pod container in its namespace that consumes it, and how, from bounded evidence reads, keeping no configuration value. The view, the shared evidence renderer (#486) and the wiring follow in #502.

  • k8s/config_references.py: one extraction of the ConfigMap and Secret references a Pod spec makes:

    • envFrom;
    • env[].valueFrom;
    • configMap, secret and projected volumes;
    • imagePullSecrets.

    It keeps the variable, key, volume and optional flag, never a value.

  • Relationship graph: it now builds its USES_CONFIG facts from that extraction, in the same order and with the same field paths, so the two cannot disagree. The graph's existing tests pass unchanged.

  • core/config_consumers.py: projects a Pod to its references to one object, by mode:

    • ENV_FROM and ENV_KEY;
    • VOLUME, or SUBPATH for a subPath or subPathExpr mount;
    • UNMOUNTED for a volume no container mounts;
    • IMAGE_PULL.

    Rows name the container and its category (container, init container, sidecar, ephemeral), except the Pod-level UNMOUNTED and IMAGE_PULL rows.

  • core/config_propagation.py: the run. It resolves two sources from discovery and reads them together under the run token:

    • the object's metadata, by name;
    • the namespace's Pods, at the readers' maximum budgets, up to 1,000 Pods.

    Each Pod is projected at once. The report keeps both observations, the baseline and the consumers.

Departures from the design

Both are recorded in the plan:

Verification

  • uv run pytest -p no:tach tests/k8s/test_config_references.py tests/core/test_config_consumers.py tests/core/test_config_propagation.py -q: 32 passed.
  • Mutation checks: each of 11 changes was caught by a test:
    • no sidecar;
    • subPathExpr ignored;
    • no UNMOUNTED row;
    • any owner reference instead of the controller;
    • matching by name alone;
    • dropped max_pages;
    • dropped max_bytes;
    • an unresolved observation without the token;
    • consumers_conclusive always true;
    • any available object reported absent;
    • dropped expected_uid.
  • uv run pytest -p no:tach tests/k8s/ tests/core/test_relationships*.py tests/ui/test_relationship* -q: 1226 passed (the graph unchanged).
  • Full gate (check_source_size, ruff check, ruff format --check, mypy, tach check, pytest -n 8): 14796 passed, 39 skipped. One local failure, test_the_measured_release_is_the_installed_one: this machine's venv still has litellm 1.100.3 and cannot install the lock from behind the mirror. CI installs from the lock.

Checklist

  • This closes an accepted issue in this repository that is assigned to me.
  • Tests cover the change, written to fail first where behavior changed.
  • make check passes locally. (Except the litellm version test above, which depends on this machine's venv.)
  • User-facing docs and the README match the change, or nothing user-facing changed. (Nothing user-facing yet; the view is Show ConfigMap and Secret consumers with the shared evidence renderer (#410 P1, view) #502.)
  • No security invariant is weakened: writes still need a keystroke approval
    and a fail-closed audit entry, and sensitive reads are still masked.

Copilot AI balanced review requested due to automatic review settings October 28, 2026 12:47
@hellices hellices added this to the v0.7.0 milestone Oct 28, 2026
@hellices hellices added enhancement New feature or request area: k8s Kubernetes clients, resources, operations, and cluster behavior concern: security Authorization, approval, sensitive data, and destructive-operation safety labels Oct 28, 2026
@hellices hellices self-assigned this Oct 28, 2026
Copilot AI previously approved these changes Oct 28, 2026

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟢 Approved

No active review issues remain for the ConfigMap and Secret consumer diagnostics foundation.

No open issues 🎉

What changed in this PR

Adds the core foundation for ConfigMap and Secret consumer diagnostics in korvid (#501, part of #410). It identifies declared Pod consumers by consumption mode; the UI, shared evidence renderer, and wiring follow in #502.

Changes:

  • Shares configuration-reference extraction with the relationship graph, preserving fact ordering and field paths.
  • Projects consumers by environment, volume, subPath, unmounted-volume, and image-pull modes, including container categories.
  • Adds bounded namespace-scoped evidence reads, run-token tracking, and tests for incomplete reads, absence, recreation, and exclusion of literal environment values.
File Description
tests/​test_optional_extras.py Checks that new modules import without optional extras.
tests/​k8s/​test_config_references.py Covers reference forms, ordering, and malformed entries.
tests/​core/​test_config_propagation.py Covers read budgets, evidence outcomes, tokens, and object identity.
tests/​core/​test_config_consumers.py Covers consumption modes, container categories, and matching.
src/​korvid/​k8s/​relationship_facts.py Uses shared extraction for configuration relationship facts.
src/​korvid/​k8s/​config_references.py Extracts configuration references without literal environment values.
src/​korvid/​core/​config_propagation.py Coordinates metadata and Pod reads into an evidence report.
src/​korvid/​core/​config_consumers.py Projects Pod references into consumer rows by mode.
docs/​superpowers/​plans/​2026-10-28-config-consumers.md Documents implementation steps, constraints, and the core/UI split.

Review effort: Balanced

@my-reviewer-agent my-reviewer-agent Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이슈 2건을 인라인 코멘트로 남겼습니다.

Comment thread tests/core/test_config_propagation.py
Comment thread tests/core/test_config_propagation.py Outdated

@my-reviewer-agent my-reviewer-agent Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이슈 1건을 인라인 코멘트로 남겼습니다.

Comment thread docs/superpowers/plans/2026-10-28-config-consumers.md

@my-reviewer-agent my-reviewer-agent Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이슈 3건을 인라인 코멘트로 남겼습니다.

Comment thread docs/superpowers/plans/2026-10-28-config-consumers.md Outdated
Comment thread tests/core/test_config_propagation.py
Comment thread docs/superpowers/plans/2026-10-28-config-consumers.md Outdated
hellices and others added 7 commits October 29, 2026 08:07
config_references reads the fields that name a configuration object -
envFrom, env[].valueFrom, configMap, secret and projected volumes, and
imagePullSecrets - and keeps the variable, key, volume and optional flag
the propagation view needs, never a value. The relationship graph now
builds its USES_CONFIG facts from it, in the same order and with the
same field paths, so the graph and the view cannot disagree.

Part of #501.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
config_consumers turns a Pod into its references to one object, each
with the mode that decides whether a change reaches the container:
environment (envFrom, env[].valueFrom), a mounted volume, a subPath or
subPathExpr mount, a volume no container mounts, or an image pull
secret. Each row names its container and category - container, init
container, sidecar (an init container with restartPolicy: Always) or
ephemeral - except the Pod-level unmounted and image pull rows. Only
references, names and the controlling owner are kept, never a value.

Part of #501.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
explain_propagation resolves two sources from the discovery snapshot and
reads them together under the run's token: the object's metadata by
name, which confirms it exists and which incarnation it is, and the
namespace's Pods at the readers' maximum budgets, each projected to its
consumers at once. The report keeps both observations, the baseline and
the consumers; whether no Pod consumes the object is conclusive only
when the Pod list is. A 404 that names the object reports it absent, a
404 that does not is not a deletion, and an unserved source is reported
with the token and not read.

Part of #501.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The plan for #501 records two departures from the design: P1 lands in
two pull requests, this core and the view in #502, and the shared
extraction is its own k8s module. It also types a test's malformed
volume list for mypy.

Part of #501.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The fake reader records each continuation, so the truncated Pod list
must ask for each page the server named, and the metadata GET must use
the default byte budget: only the Pod list reads at the maxima.

Part of #501.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
A spy on read_list asserts the Pod list gets the page size, page cap,
deadline and byte budget at the readers' maxima, so a deadline that
fell back to the default would fail.

Part of #501.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The Secret test now asserts the one GET it makes: secrets, in the
namespace, by name, metadata only, at the default byte budget. The
plan's privacy constraint lists the identities and reference evidence
that leave the run, and what never does.

Part of #501.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@hellices
hellices force-pushed the feat/501-config-consumers branch from 9f1d311 to 6c37b95 Compare October 28, 2026 23:07

@my-reviewer-agent my-reviewer-agent Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

검토 범위에서 보고할 이슈가 없습니다.

@hellices
hellices merged commit 17ab2c4 into main Oct 29, 2026
14 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: k8s Kubernetes clients, resources, operations, and cluster behavior concern: security Authorization, approval, sensitive data, and destructive-operation safety enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Project ConfigMap and Secret consumers by mode (#410 P1, core)

2 participants