Skip to content

Connect KEDA scalers to observed authentication dependencies - #1987

Merged
nadaverell merged 3 commits into
mainfrom
feature/relationship-keda-auth
Oct 13, 2026
Merged

nadaverell merged 3 commits into
mainfrom
feature/relationship-keda-auth

Conversation

@nadaverell

@nadaverell nadaverell commented Oct 7, 2026 •

Copy link
Copy Markdown
Contributor

Connect KEDA ScaledObject and ScaledJob authentication references to observed TriggerAuthentication and ClusterTriggerAuthentication resources. Operators can navigate from a scaler to its authentication configuration and find the scalers that consume it without manually joining YAML names.

Omitted authentication kind resolves to a same-namespace TriggerAuthentication. Explicit cluster authentication receives its exact cluster read tuple. Authentication configuration points into the scaler with EdgeConfigures; scaler-to-workload usage remains a separate EdgeUses relationship. Missing or invalid targets are not fabricated, and credential references are not traversed.

Applications ScaledJob configuration references and counts exclude authentication objects the caller cannot read. The request projection uses exact KEDA read permissions and copies affected rows before deriving counts and the capped list, preserving the shared cache for other callers. Broader authorization of pre-existing Applications relationship categories remains a separate change.

Validation: Go build, complete shared/internal Go suites, type-check, shared UI and web tests, and the embedded application build pass. Regression coverage includes mixed authentication permissions, counts above the 20-reference display cap, cache reuse and local mode. Real KEDA 2.21.0 runs cover 12 ScaledObject/ScaledJob × namespaced/cluster authentication × Secret/env/podIdentity combinations on REST, MCP and topology. All scalers reconcile Ready; the Secret/env fixture endpoint enforces its dummy bearer token. Restricted-user checks verify direct cluster authentication denial and omission from relationship projections and Applications. Test objects and the complete KEDA installation are removed and absence verified.

Scaler authentication dependency
TriggerAuthentication: Required By the ScaledObject and ScaledJob

Pod identity proof covers accepted AWS provider declarations and relationship navigation against a local fixture endpoint, not a cloud credential exchange. Declared authentication dependencies do not establish credential validity or trigger readiness.

@nadaverell
nadaverell requested a review from hisco as a code owner October 7, 2026 01:31
@qodo-free-for-open-source-projects

Copy link
Copy Markdown

PR Summary by Qodo

Show observed KEDA authentication resources as scaler dependencies

âœĻ Enhancement 🧊 Tests 📝 Documentation 🕐 20-40 Minutes

Grey Divider

AI Description

â€Ē Link ScaledObjects and ScaledJobs to referenced, observed authentication resources without
 changing workload targets.
â€Ē Preserve namespace and cluster-read boundaries while avoiding invented nodes and per-object
 requests.
â€Ē Test forward and reverse relationships, deduplication, and permission stripping; document topology
 behavior.
Diagram

graph TD
  Scalers["KEDA Scalers"] --> Extractor["Reference Extractor"] --> Join["Observed Join"] --> Topology["Topology Graph"] --> Consumers["Related Resources"]
  Cache[("Dynamic Cache")] --> Join
Loading
High-Level Assessment

Reusing the observed-dependency join is the best fit: it preserves existing node identities and authorization handling while avoiding per-object Gets. Fetching each declaration directly or displaying every authentication resource would weaken those properties.

Files changed (5) +165 / -3

Enhancement (2) +56 / -0
keda.goExtract scoped KEDA authentication references +42/-0

Extract scoped KEDA authentication references

â€Ē Adds a pure extractor for ScaledObject and ScaledJob triggers. It defaults omitted kinds to same-namespace TriggerAuthentication, treats ClusterTriggerAuthentication as cluster-scoped, and deduplicates valid references.

pkg/configrefs/keda.go

builder.goJoin scaler authentication declarations to observed resources +14/-0

Join scaler authentication declarations to observed resources

â€Ē Collects authentication references while building ScaledObject and ScaledJob nodes, then passes them to the shared observed-dependency join. The resulting authentication edges remain separate from ScaledObject workload-target edges.

pkg/topology/builder.go

Tests (2) +106 / -0
keda_test.goTest authentication reference extraction +43/-0

Test authentication reference extraction

â€Ē Covers both scaler kinds, default and explicit kinds, deduplication, invalid declarations, non-KEDA inputs, and nonmutation.

pkg/configrefs/keda_test.go

keda_authentication_test.goTest observed KEDA dependency graph and authorization +63/-0

Test observed KEDA dependency graph and authorization

â€Ē Checks scoped matching, missing-target omission, forward and reverse relationships, and separation from scale targets. Also verifies one list per authentication kind, zero object Gets, and removal of denied cluster-scoped targets.

pkg/topology/keda_authentication_test.go

Documentation (1) +3 / -3
integrations.mdDocument KEDA authentication topology +3/-3

Document KEDA authentication topology

â€Ē Explains that referenced authentication resources appear as dependencies, distinct from scaling targets. Clarifies default namespace scope, cluster read gating, and that a declaration does not establish credential validity or trigger readiness.

docs/integrations.md

@qodo-free-for-open-source-projects

qodo-free-for-open-source-projects Bot commented Oct 7, 2026 •

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (0) 📘 Rule violations (0) 📎 Requirement gaps (0) ðŸŽĻ UX issues (0) 🔗 Cross-repo conflicts (0) 📜 Skill insights (0)

Grey Divider


Remediation recommended

1. Authentication links get the wrong type ✓ Resolved
Description
buildResourcesTopology passes KEDA authentication references to addObservedDependencyEdges,
which assigns them EdgeUses rather than a configuration edge. When a trigger references an
authentication resource, the graph gives that configuration dependency the same edge type as a
scaler-to-workload link, so consumers filtering topology by edge type cannot distinguish them.
Code

pkg/topology/builder.go[3793]

+	nodes, edges, kedaAuthenticationWarnings := addObservedDependencyEdges(nodes, edges, kedaAuthenticationDependencies, dynamicCache, opts)
Evidence
Rule 3036572 reserves EdgeUses for autoscalers pointing to target workloads and EdgeConfigures
for configuration relationships. The added builder call sends authentication references through a
helper that always emits EdgeUses; relationship code separately identifies KEDA authentication as
a configuration dependency.

Rule 3036572: Use semantically correct topology edge types for Kubernetes relationships
pkg/topology/builder.go[3793-3793]
pkg/topology/observed_dependencies.go[87-98]
pkg/topology/relationships.go[794-810]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
KEDA authentication references enter a shared dependency helper that emits `EdgeUses`, although these references are configuration dependencies rather than autoscaler targets.
## Fix Focus Areas
- pkg/topology/builder.go[3793-3793]
- pkg/topology/observed_dependencies.go[87-98]
- pkg/topology/relationships.go[370-470]
## Recommended Fix
Emit `EdgeConfigures` for authentication references with the configuration resource as the source. Update relationship projection and tests so both dependency directions remain navigable.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

Tip of the day
ðŸ’Ą Did you know, you can turn these tips off under Display > Comment parts

More tips ↗ | Customize Qodo ↗ | Qodo docs ↗

Grey Divider

Qodo Logo

Comment thread pkg/topology/builder.go
nadaverell added a commit that referenced this pull request Oct 9, 2026
â€Ķationships (#1978)

Radar's relationship view treated every `uses` edge in the graph that
wasn't storage as autoscaling. A Certificate that uses its Issuer would
be shown with the Issuer as its **Scale Target**, and the Issuer would
list the Certificate as its **Autoscaler**, in the drawer, the REST
resource details and the MCP resource context given to AI tools. This
separates real autoscalers from other dependencies, so those surfaces
say "depends on" when something isn't scaling.

Nothing changes visibly on today's `main`: no edge there is
misclassified yet. The edges this fixes arrive in follow-up PRs
(Certificate → Issuer in #1979, KEDA → TriggerAuthentication in #1987),
which build on this projection.

## What changed

**Classification of `uses` edges** (`pkg/topology/relationships.go`).
Each edge is put into exactly one group:

| Edge source | Group |
|---|---|
| core `PersistentVolumeClaim` | storage (`storageRefs` / `consumers`),
as before |
| `HorizontalPodAutoscaler` (`autoscaling`), `VerticalPodAutoscaler`
(`autoscaling.k8s.io`), `ScaledObject` / `ScaledJob` (`keda.sh`), same
namespace | autoscaling (`scaleTarget` / `scalers`), as before |
| anything else | **new** `dependencies` / `dependents` |

- Matching uses the exact API group, so a custom resource that happens
to be named `ScaledObject` or `PersistentVolumeClaim` is no longer
treated as one.
- A KEDA scaler's TriggerAuthentication is a dependency, not its scale
target, so it can't displace the workload the scaler actually scales.

**New fields, additive.** `Relationships` and `resourceContext` gain
`dependencies` and `dependents`. In resource context they're filtered by
the caller's permission to read each target, and dropped ones are
reported in the existing omission reasons. `docs/mcp.md` describes how
they differ from `scaledBy`.

**UI.** The Related Resources section shows them as **Depends On** and
**Required By**, with the same badges, navigation and limits as its
other groups.

**Radar Hub compatibility.** Hub embeds a versioned UI that doesn't know
the new fields. Issuer and KEDA-authentication dependencies are
therefore also reported in the existing `configRefs` / `consumers`
(Configuration / Used By), so Hub keeps working links. The new UI hides
those mirrored entries, so each target appears once.

**De-duplication.** Reference de-duplication across these groups uses
the existing group-aware key from Checks (`resource-refs.ts`), so
same-named resources from different API groups stay distinct.
`configRefs` lists each target once on every path. Each list is
de-duplicated once after it is collected, so a PVC shared by thousands
of workloads stays linear rather than rescanning the list per consumer.

No new endpoint, permission, graph edge type, or SSE/neighborhood
change.

## Result on a live cluster

To show the fix, both builds include #1979's Certificate → Issuer edges
on top of `main`. "Before" uses `main`'s version of the projection,
"after" uses this PR's. Real cert-manager resources:

![Certificate: Scale Target becomes Depends
On](https://github.com/user-attachments/assets/384affd1-f486-4b27-b4e0-0cc968a13114)

![Issuer: Autoscaler becomes Required
By](https://github.com/user-attachments/assets/c6008433-a1d1-443d-ba59-ef81006bdcb4)

On `main` alone, this branch (merged with `main`) returned relationships
identical to `main` for all 79 resources on the test cluster, including
HPA, VPA, KEDA and PVC fixtures.

## Testing

- Graph fixtures cover Certificate/Issuer direction, KEDA target plus
authentication, PVC consumers, exact-group collisions, one configuration
target reached by two edges, each autoscaler kind accepted only in its
own group and namespace, and a claim shared by 20,000 Jobs plus a
duplicate edge (each consumer listed once).
- Context tests cover target authorization and omission reasons.
Rendered-component tests cover dependency-only responses, the
directional labels, exact-group navigation and the mirrored projections.
Existing Checks identity tests confirm unchanged keys.
- `go test` for `pkg/topology`, `pkg/resourcecontext`, `internal/server`
and `internal/mcp`; `make tsc`; the affected shared UI suites (22
tests).
- Live: the comparisons above, on a kind cluster.

ðŸĪ– Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
@nadaverell
nadaverell force-pushed the feature/relationship-keda-auth branch from f2fec1a to 8e21e7f Compare October 13, 2026 03:26
@nadaverell
nadaverell force-pushed the feature/relationship-observed-dependencies branch 2 times, most recently from 5b8ad1e to f1e10bd Compare October 13, 2026 10:21
@nadaverell
nadaverell force-pushed the feature/relationship-keda-auth branch from 479d7ec to ea71bbe Compare October 13, 2026 10:21
nadaverell added a commit that referenced this pull request Oct 13, 2026
A refactor with no behavior change: certificate → issuer links are
identical before and after. It moves cached observed-dependency
materialization into one shared helper, so the identity, scope and
deduplication rules have one implementation. The KEDA (#1987) and Flux
(#1989) dependency PRs are built on it; it exists so those two don't
carry separate copies of the same logic.

Controller-specific parsers supply exact source/target references and
retain their own defaults and valid-kind rules. The common helper groups
target reads by group/kind, lists each kind once, reuses existing node
identities and adds only observed referenced targets. Missing sources or
targets and repeated passes cannot fabricate or duplicate relationships.
Exact cluster authorization metadata stays attached to materialized
nodes.

Validation: the complete Go, type-check and frontend matrix passes at
the final head. Fresh live REST/MCP checks preserve both issuer
dependency directions and the Issuer's metadata owner. Unit cases cover
lookup fanout, missing/reused targets, scope/group collisions, absent
sources and repeated-pass deduplication. Visual testing is skipped
because this backend refactor changes no rendered surface.

No new endpoint, renderer or mandatory provider interface is added.
Cached reads are distinct from startup discovery and informer traffic.
Base automatically changed from feature/relationship-observed-dependencies to main October 13, 2026 11:17
Expose observed trigger authentication separately from scaled workloads while preserving exact scope and configuration flow.
Expose observed trigger authentication separately from scaled workloads while preserving exact scope and configuration flow.
ScaledJob application rows can contain authentication dependencies that the
caller cannot read. Filter those references with exact KEDA read permissions
on a copied response, and derive counts and the capped list from the visible
references without modifying the shared cache.

Cover mixed permissions, truncation, cache reuse and local mode, and document
the Applications behavior.
@nadaverell
nadaverell force-pushed the feature/relationship-keda-auth branch from ea71bbe to f72ee63 Compare October 13, 2026 11:21
@nadaverell
nadaverell merged commit 34b1d1f into main Oct 13, 2026
8 checks passed
@nadaverell
nadaverell deleted the feature/relationship-keda-auth branch October 13, 2026 11:23
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