Skip to content

Filter APIKeyStatus Secret watch by label instead of watching all Secrets cluster-wide #83

Description

@eguzki

Background

#82 adds a Secret watch to APIKeyStatusReconciler (internal/controller/apikey_status_controller.go) so that APIKeys stuck in SecretNotFound recover once their referenced Secret is created. See #78.

The watch is currently unfiltered:

Watches(&corev1.Secret{}, handler.EnqueueRequestsFromMapFunc(r.enqueueClass)).

This reconciler uses a "class reconciler" pattern: every watched event enqueues the same fixed key and triggers a full list-and-reconcile of all APIKeys (Reconcile, internal/controller/apikey_status_controller.go:63). The manager's cache is not namespace-scoped (cmd/main.go), so in practice any Secret create/update/delete anywhere in the cluster now triggers a full reconcile pass of every APIKey.

Proposal

Define a label that marks a Secret as an APIKey's referenced secret (e.g. devportal.kuadrant.io/apikey-secret: "true"), and filter the Secret watch in apikey_status_controller.go with a predicate so it only reacts to Secrets carrying that label.

Scope — when the label is (and isn't) needed

The label is only relevant to the Secret-created-after-APIKey race. If the Secret already exists at the time the APIKey is created (the normal/original ordering), reconciliation is already triggered by the APIKey watch itself — no Secret event, and therefore no label, is needed for that path to succeed. The label-scoped watch exists solely to catch the recovery case from #78/#82: APIKey created first, referencing a Secret that doesn't exist yet, created moments later. Consumers/plugins that always create the Secret before the APIKey never need to set this label for correctness — only those that create the APIKey first (e.g. to set an ownerReference, per kuadrant-console-plugin#541) need it.

Non-goal: keeping the APIKey in sync with later Secret content changes. This watch only reacts to the Secret appearing (create/update events firing the same generic re-reconcile). It does not mean the system keeps API key material in sync if someone edits the Secret's data.api_key after the fact:

  • APIKeyStatusReconciler only re-checks existence/non-emptiness of the entry, it doesn't project the value anywhere that would need re-syncing.
  • APIKeySecretReconciler (internal/controller/apikey_secret_controller.go), which copies the consumer Secret's api_key value into the Authorino-enforced secret, does not watch Secrets at all (only APIKey) — so an in-place edit of the consumer's Secret value is never propagated to enforcement, label or no label.

This issue is scoped to detecting Secret creation for the missing-secret recovery case, not to general Secret-content sync. That gap (edits to an existing Secret's value not propagating to enforcement) is a separate, pre-existing issue if it needs addressing.

Tasks

  • Decide on the label key/value
  • Add predicate to the Secret watch in apikey_status_controller.go
  • Document the label (and its limited scope, per above) in this repo
  • Document the label in docs.kuadrant.io
  • Update kuadrant-console-plugin (RequestAPIKeyModal.tsx) to set the label — only strictly required for the create-APIKey-before-Secret flow (kuadrant-console-plugin#541)
  • Update kuadrant-backstage-plugin (router.ts POST /secrets) to set the label if/when it adopts the same create-order

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    triage/acceptedReviewed, prioritised, and ready for work

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions