Aller au contenu
3 min de lecture Moustakime KIFIA

OIDC GitLab vers AWS : la trust policy et le job CI

Comment on a branché GitLab CI sur AWS via OIDC, avec une trust policy serrée, un seul rôle pour tous les projets et la limite ACLSizePerRole qu'on a frôlée.

  • CI/CD
  • Auth
  • Operations
OIDC GitLab vers AWS : la trust policy et le job CI

Le sujet peut vite devenir verbeux parce qu’il mélange IAM, CI et sécurité. Cet article fait l’inverse : montrer le chemin minimal qui marche, puis dire où il casse — y compris la limite AWS qu’on n’avait pas vue venir.

Le pattern en cinq lignes

Le cœur du montage :

  • un provider OIDC GitLab enregistré dans IAM
  • une trust policy avec StringLike sur gitlab.com:sub
  • un aud fixé à sts.amazonaws.com
  • assume-role-with-web-identity dans le job CI
  • un seul rôle partagé entre plusieurs projets, avec sessions courtes (1h)

Le lecteur doit pouvoir reconstruire le montage sans lire un guide AWS de 40 pages.

La trust policy Terraform

# cicd.tf
locals {
  gitlab_build_subjects = [
    "project_path:keyson/cercly/*:ref_type:branch:ref:main",
    "project_path:keyson/cercly/*:ref_type:branch:ref:develop",
    "project_path:keyson/cercly/*:ref_type:tag:ref:*",
  ]
}

data "aws_iam_policy_document" "gitlab_build_assume_role" {
  statement {
    effect  = "Allow"
    actions = ["sts:AssumeRoleWithWebIdentity"]

    principals {
      type        = "Federated"
      identifiers = [aws_iam_openid_connect_provider.gitlab.arn]
    }

    condition {
      test     = "StringEquals"
      variable = "gitlab.com:aud"
      values   = ["sts.amazonaws.com"]
    }

    condition {
      test     = "StringLike"
      variable = "gitlab.com:sub"
      values   = local.gitlab_build_subjects
    }
  }
}

Le StringLike avec wildcard * permet de couvrir tous les projets sous keyson/cercly/ sans lister chaque repo.

Le job CI

# templates/docker-build.yml
.assume_aws_role: &assume_aws_role
  - >
    export $(printf "AWS_ACCESS_KEY_ID=%s AWS_SECRET_ACCESS_KEY=%s AWS_SESSION_TOKEN=%s"
    $(aws sts assume-role-with-web-identity
    --role-arn "$AWS_BUILD_ROLE_ARN"
    --role-session-name "gitlab-build-${CI_PROJECT_NAME}-${CI_PIPELINE_ID}"
    --web-identity-token "$CI_JOB_JWT_V2"
    --duration-seconds 3600
    --query "Credentials.[AccessKeyId,SecretAccessKey,SessionToken]"
    --output text))

Pas de credentials statiques. Le token OIDC est fourni par GitLab à chaque job via $CI_JOB_JWT_V2, échangé contre des credentials AWS temporaires valables 1h.

La limite qu’on n’avait pas vue venir

On avait initialement listé chaque projet explicitement dans la trust policy :

gitlab_build_subjects = [
  "project_path:keyson/cercly/apis/operator-api:ref_type:branch:ref:main",
  "project_path:keyson/cercly/apis/platform-api:ref_type:branch:ref:main",
  "project_path:keyson/cercly/bff/member-bff:ref_type:branch:ref:main",
  # ... 8 autres projets
]

En ajoutant portal et mobile, le deploy CI a échoué avec :

LimitExceeded: Cannot exceed quota for ACLSizePerRole: 2048

AWS limite la taille totale des trust policies à 2048 caractères par rôle. Avec des chemins de projet longs multipliés par 3 branches autorisées (main, develop, tags), on atteignait la limite avec 5-6 projets.

La solution : remplacer l’énumération par un wildcard sur le namespace :

gitlab_build_subjects = [
  "project_path:keyson/cercly/*:ref_type:branch:ref:main",
  "project_path:keyson/cercly/*:ref_type:branch:ref:develop",
  "project_path:keyson/cercly/*:ref_type:tag:ref:*",
]

Trois lignes au lieu de trente. Tous les projets actuels et futurs sous keyson/cercly/ sont couverts. Le wildcard * dans StringLike est supporté nativement par IAM.

Le seul garde-fou perdu : un projet extérieur au namespace keyson/cercly/ ne peut plus se glisser par erreur. Mais c’est le même namespace GitLab — si quelqu’un a accès au namespace, il a accès aux projets.

La checklist opérationnelle

Pour ajouter un nouveau projet :

  1. Créer le projet GitLab sous keyson/cercly/
  2. Créer le repo ECR dans Terraform (var.ecr_services)
  3. Appliquer Terraform — le repo ECR et les droits sont créés
  4. Pousser une première image — ça marche immédiatement

Plus besoin de toucher à la trust policy pour chaque nouveau projet.

Avec du recul

Une bonne intégration OIDC vaut surtout par sa lisibilité quand on ajoute un projet de plus. La version par énumération avait l’air précise et sécurisée. Elle était surtout fragile : chaque nouveau projet était une occasion d’oublier une ligne, de dépasser la limite, ou de devoir planifier un Terraform apply avant le premier push.

Le wildcard est moins explicite. Il est plus robuste.

Continuer la lecture

Quelques articles relies pour renforcer le maillage interne et prolonger les sujets techniques voisins.

5 min

Une carte simple de l'architecture SaaS de Cercly

Une lecture de l'architecture SaaS de Cercly centrée sur la découpe applicative : design system partagé, frontends séparés, BFFs dédiés, APIs métier et infra commune.

  • Architecture
  • Engineering
  • Product
Lire la note