Skip to content

fix(server-nestjs): make Keycloak root group creation idempotent - #2623

Open
shikanime wants to merge 2 commits into
mainfrom
fix/keycloak-root-group-idempotent
Open

fix(server-nestjs): make Keycloak root group creation idempotent#2623
shikanime wants to merge 2 commits into
mainfrom
fix/keycloak-root-group-idempotent

Conversation

@shikanime

Copy link
Copy Markdown
Member

Issues liées

#2618 (fermer délibérément après la fusion)

Quel est le comportement actuel ?

La création du groupe racine Keycloak n'est pas idempotente face à une course concurrente. getOrCreateGroupByPath lit d'abord le groupe racine, puis appelle createGroup si celui-ci est absent. Or deux réconciliations simultanées (la synchronisation cron et un project.upsert) peuvent toutes deux passer la lecture avant qu'aucune n'ait créé le groupe : la seconde échoue alors avec une erreur HTTP 409, car le groupe existe désormais. createGroup ne tolérait pas ce 409 et remontait l'erreur au lieu de récupérer le groupe déjà créé.

Comportement attendu

Un 409 sur la création du groupe racine doit être traité comme « le groupe existe déjà » : le groupe existant est re-consulté via getRootGroupByName puis renvoyé, exactement de la même manière que le chemin des sous-groupes (getOrCreateSubGroupByName) le fait déjà. Aucun autre comportement ne change.

Changements

  • Envelopper l'appel client.groups.create dans createGroup avec une tolérance au 409 : en cas de 409, re-consulter le groupe racine existant et le renvoyer.
  • Ajouter un test unitaire couvrant la course 409 sur le groupe racine (le 409 déclenche la re-consultation du groupe existant).

@github-actions github-actions Bot added the built label Aug 28, 2026
@shikanime
shikanime force-pushed the fix/keycloak-root-group-idempotent branch from bceb1cd to dd18554 Compare August 28, 2026 11:39
Signed-off-by: William Phetsinorath <william.phetsinorath-open@interieur.gouv.fr>
Change-Id: Iff465b31836b84656a084678aeec082a6a6a6964
… race)

Refs #2618


Co-authored-by: Automata <automata@shikanime.studio>


Signed-off-by: William Phetsinorath <william.phetsinorath-open@interieur.gouv.fr>
Change-Id: I5944dfc5a50f280ef836ce9e9a136f366a6a6964
@shikanime
shikanime force-pushed the fix/keycloak-root-group-idempotent branch from dd18554 to 0a0efb2 Compare August 28, 2026 14:20
@shikanime
shikanime changed the base branch from main to fix/uniformize-error-guards August 28, 2026 14:22
@shikanime

Copy link
Copy Markdown
Member Author

Updated review

The fast-path read at line 187 is intentional — when the root group exists but the full path does not (e.g. /myproject/sub), it skips the POST entirely. The 409 tolerance in ensureGroup covers the race window between that read and the create.

I initially flagged the read as redundant, and it IS technically redundant for single-part paths (getGroupByPath already reads the root). But the extra GET is negligible for an infrequent operation, and keeping the read-first makes the hot path obvious.

The PR is correct as-is.

Comment on lines -187 to +198
let current = await this.getRootGroupByName(rootName) ?? await this.createGroup(rootName)
let current = await this.getRootGroupByName(rootName) ?? await this.ensureGroup(rootName)

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

getRootGroupByName is probably not needed, since ensureGroup also do that

@shikanime
shikanime marked this pull request as ready for review August 28, 2026 15:39
@shikanime
shikanime requested a review from a team as a code owner August 28, 2026 15:40
@cloud-pi-native-sonarqube

Copy link
Copy Markdown

Base automatically changed from fix/uniformize-error-guards to main August 28, 2026 15:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant