Skip to content

security: identity and credential reconciliation is additive with incomplete cleanup #164

Description

@dcmcand

Summary

Identity and credential reconciliation is largely additive. Group membership sync only adds users, client scopes and protocol mappers are added or updated but never removed when dropped from spec, and NebariApp deletion leaves groups, memberships, realm client scopes, and the generated OIDC Secret behind. A hash optimization can also skip provisioning without confirming that Keycloak still matches the desired state.

Affected code

  • internal/controller/reconcilers/auth/providers/keycloak.go:
    • Group membership sync is additive-only (L1020-1073); omitted users are not removed.
    • syncClientScopes (L749-824) creates and assigns scopes but never unassigns or deletes stale ones.
    • syncClientProtocolMappers (L833-910) creates/updates mappers by name but never removes ones dropped from spec.
    • storeClientSecret (L696-745) builds the OIDC Secret with no owner reference, so it is not garbage-collected and is never deleted.
  • internal/controller/reconcilers/auth/reconciler.go:
    • CleanupAuth (L265-300) calls CleanupTokenExchange (only when token exchange was enabled, L279) and DeleteClient. It does not remove groups, memberships, realm scopes, or the OIDC Secret.
    • The hash skip (L175-211, condition at L179) skips provisioning when AuthReady=True and the stored AuthConfigHash is unchanged, without reading Keycloak back, so external drift persists until a spec change or the force-reprovision annotation.

Impact

Access can persist after desired membership is removed, realm resources accumulate and can collide with later applications, OIDC client credentials remain in the cluster after app deletion, and security-relevant Keycloak drift is not necessarily repaired.

Remediation

  • Decide explicitly whether each identity object is operator-owned or referenced, and store immutable object IDs plus NebariApp UID ownership.
  • Reconcile removals for fully managed resources, and delete or revoke generated credentials on cleanup (give the OIDC Secret an owner reference).
  • Periodically verify external desired state rather than trusting only a local hash.
  • Provide migration and dry-run tooling before removing shared realm resources.

Acceptance criteria

  • Removing a user, scope, mapper, app, or credential produces complete, bounded revocation.
  • The OIDC Secret is removed on NebariApp deletion.
  • External Keycloak drift is detected and repaired without requiring a spec change.

References

Line numbers reference commit 4ad2c10.

Metadata

Metadata

Assignees

No one assigned

    Labels

    area: securitySecurity vulnerabilities and hardeningpriority: medium ⚡Medium priority - standard queuetype: tech debt 🧹Technical debt and code quality improvements

    Type

    No type

    Fields

    Priority

    None yet

    Start date

    None yet

    Target date

    None yet

    Size

    None yet

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions