Skip to content

fix(gitlab): stop reconciles from demoting instance admins - #2805

Closed
shikanime wants to merge 7 commits into
mainfrom
fix/gitlab-admin-demotion
Closed

shikanime wants to merge 7 commits into
mainfrom
fix/gitlab-admin-demotion

Conversation

@shikanime

Copy link
Copy Markdown
Member

Issues liées

Issues numéro: #2804

Quel est le comportement actuel ?

Le pipeline de réconciliation des projets transmet admin: false à l'API d'édition GitLab dès que l'utilisateur réconcilié ne porte pas le rôle admin mappé sur le adminGroupPath du projet. L'API GitLab ne permet pas de désactiver ce flag : toute valeur falsy dégrade l'admin de l'instance. Un admin plateforme owner d'un projet perd is_admin au premier reprovisionnement.

Quel est le nouveau comportement ?

upsertUser ne transmet admin/auditor que lorsqu'ils sont vrais. La promotion reste write-positive ; la révocation, si un jour nécessaire, relèvera d'un flux admin dédié, pas du chemin de réconciliation.

Cette PR introduit-elle un breaking change ?

Non. Le correctif ne retire que la capacité à dégrader un admin/auditeur existant depuis la réconciliation ; la création de compte et la promotion true sont inchangées.

Autres informations

  • Régression : admin: false sur un utilisateur is_admin: true ne produit plus d'edit dégradant ; sans le garde-fou, le test échoue (vérifié par rollback).
  • Revue sémantique : le filtre retire tout false de la charge utile, pas seulement admin/auditor — chaque booléen de l'API utilisateur GitLab est de sémantique « set-true » ; les false explicites de createUser sont ajoutés après le spread, non affectés.
  • Portée : npx vitest run src/modules/gitlab/ — 107 tests verts.

@shikanime
shikanime requested a review from a team as a code owner October 1, 2026 10:22
@shikanime
shikanime marked this pull request as draft October 1, 2026 10:24
@github-actions github-actions Bot added the built label Oct 1, 2026
@shikanime
shikanime force-pushed the fix/gitlab-admin-demotion branch from f3defd3 to a128eb5 Compare October 1, 2026 11:41
@shikanime shikanime added the bug Something isn't working label Oct 1, 2026
@shikanime shikanime self-assigned this Oct 1, 2026
@shikanime shikanime added this to the 9.27.0 milestone Oct 1, 2026
@shikanime
shikanime force-pushed the fix/gitlab-admin-demotion branch 2 times, most recently from 60f4aa0 to 785b580 Compare October 1, 2026 15:35
Comment thread apps/server-nestjs/src/modules/gitlab/gitlab.utils.ts Outdated

@StephaneTrebel StephaneTrebel left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Le correctif décrit dans #2804 est annulé dans l’état final : la réconciliation transmet de nouveau admin: false et démote donc un administrateur GitLab. La branche est aussi à 3 commits de main ; corriger le contrat, rebaser puis relancer les contrôles avant nouvelle revue.

@iliesmrf iliesmrf modified the milestones: 9.27.0, 9.28.0 Oct 2, 2026
@shikanime
shikanime force-pushed the fix/gitlab-admin-demotion branch from 254a5f3 to 86a2dd3 Compare October 2, 2026 11:56
@StephaneTrebel

Copy link
Copy Markdown
Collaborator

Relecture de la tête actuelle : le correctif préserve bien les drapeaux d’instance GitLab lorsqu’une réconciliation ne porte aucune revendication de rôle, avec couverture unitaire et E2E. La PR étant en brouillon, aucun verdict formel n’est publié.

@shikanime
shikanime force-pushed the fix/gitlab-admin-demotion branch from 86a2dd3 to 513eedc Compare October 2, 2026 14:58
shikanime and others added 7 commits October 2, 2026 17:09
The project reconcile pipeline pushed admin: false into GitLab's user
edit whenever the reconciled user did not hold the role mapped on the
project's adminGroupPath. GitLab's edit API cannot un-set the admin
flag: a falsy value demotes the instance admin. A platform admin
owning a project lost is_admin on the first reprovision.

Reconciles now transmit admin/auditor only when true. Promotion stays
write-positive; revocation, if ever needed, belongs to a dedicated
admin flow, not the reconcile path.

Refs #2804

Co-authored-by: Automata <automata@shikanime.studio>
Signed-off-by: William Phetsinorath <william.phetsinorath-open@interieur.gouv.fr>
Change-Id: Id7dbb0f40242a7d05178be8baff88ea06a6a6964
The project reconcile pipeline pushed admin: false into GitLab's user
edit whenever the reconciled user did not hold the role mapped on the
project's adminGroupPath. GitLab's edit API cannot un-set the admin
flag: a falsy value demotes the instance admin. A platform admin
owning a project lost is_admin on the first reprovision.

Reconciles now transmit admin/auditor only when true. Promotion stays
write-positive; revocation, if ever needed, belongs to a dedicated
admin flow, not the reconcile path.

Refs #2804

Co-authored-by: Automata <automata@shikanime.studio>
Signed-off-by: William Phetsinorath <william.phetsinorath-open@interieur.gouv.fr>
Change-Id: Id7dbb0f40242a7d05178be8baff88ea06a6a6964
adminRoleFlag returned false when a project maps an admin/auditor role
the user does not hold, ordering upsertUser to demote that GitLab
instance flag. Under cumulative permissions the producer must never
emit a revocation: absence of membership is now `undefined` (no claim),
`true` stays promotion. The upsertUser guard keeps enforcing the
boundary for any future caller.

Co-authored-by: Automata <automata@shikanime.studio>
Signed-off-by: William Phetsinorath <william.phetsinorath-open@interieur.gouv.fr>
Change-Id: I501ee9e3c43068283763b2867950c92fada38ab3
Reproduces the reported incident against a live GitLab: a project
member's instance admin flag is granted outside the console, the
project is reprovisioned, and the flag must survive. Requires E2E=1
and integ credentials to execute; keeps the cumulative-permissions
contract observable for the maintenance environment.

Co-authored-by: Automata <automata@shikanime.studio>
Signed-off-by: William Phetsinorath <william.phetsinorath-open@interieur.gouv.fr>
Change-Id: If41eddf4a50094980dc961b3e4a83017ada6c37a
Reverses the promote-only contract: a resolved admin/auditor role mapping
is authoritative, so holding it transmits true (promote) and lacking it
transmits false (demote). Removal of a role therefore removes the GitLab
instance flag. An empty mapping stays unknowable and transmits no claim.
Drops the boundary false-strip, which would now swallow demotions.

Co-authored-by: Automata <automata@shikanime.studio>
Signed-off-by: William Phetsinorath <william.phetsinorath-open@interieur.gouv.fr>
Change-Id: I5f3a9c2e7b1d4a8f0e6c3b9d2a7f1e4c8b0d5a3f
Platform /admin is the bootstrap group; the instance admin flag is
governed by /console/admin membership. Union was a misdiagnosis built
on an unverified hypothesis about the reported account.

Co-authored-by: Automata <automata@shikanime.studio>
Signed-off-by: William Phetsinorath <william.phetsinorath-open@interieur.gouv.fr>
Change-Id: I3b7e9d1f5a2c8e4b6d0f9a3c5e7b1d8f2a4c6e9b
The head state reintroduced #2804: adminRoleFlag emitted false whenever a
project mapped an admin/auditor role the user did not hold, and upsertUser
forwarded it to Users.edit, demoting the GitLab instance admin on every
reconcile. Role removal is expressed by group membership only —
ensureGroupMemberAccessLevel / purgeOrphanMembers handle the group side —
so the flag mapping is tri-state again: true promotes, absence of the
claim (undefined) leaves the instance flag untouched, and the upsertUser
boundary strips falsy admin/auditor for any future caller. Restores the
e2e instance-admin-survival regression.

Fixs #2804

Co-authored-by: Automata <automata@shikanime.studio>
@shikanime
shikanime force-pushed the fix/gitlab-admin-demotion branch from 513eedc to 36a8200 Compare October 2, 2026 15:09
@cloud-pi-native-sonarqube

Copy link
Copy Markdown

@shikanime shikanime moved this to Hypotheses in Cloud Pi Native Oct 5, 2026
@iliesmrf iliesmrf closed this Oct 5, 2026
@iliesmrf
iliesmrf deleted the fix/gitlab-admin-demotion branch October 5, 2026 14:38
@shikanime shikanime removed this from the 9.28.0 milestone Oct 5, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working built

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants