Aller au contenu principal

Déployer sans secret (OIDC)

Bêta

Fonctionnalité en cours de déploiement. L'interface décrite ici est celle de la prochaine livraison : elle peut encore évoluer, et n'est pas forcément activée sur votre tenant.

GitLab CI et GitHub Actions remettent à chaque job un jeton OIDC de courte durée, qui dit « ce job appartient à ce projet, sur cette branche ». StackNGO l'échange contre une session de tenant. Résultat : aucun secret à stocker, rien à faire tourner.

Vous déclarez quels pipelines vous faites confiance avec un trust OIDC (IAMOIDCTrust), puis vous lui attachez une policy, exactement comme pour un utilisateur.

Prérequis​

  • Une session d'administrateur sur le tenant (sng tenant use acme).
  • Le projet CI et sa branche de déploiement.

1. Déclarer le trust​

# GitLab : pipelines de la branche protégée main du projet acme/infra
sng tenant oidc create gitlab-deploy \
--gitlab-project acme/infra --ref main \
--claim project_id=4242 --claim ref_protected=true

# GitHub : workflows du dépôt acme/infra sur main
sng tenant oidc create github-deploy \
--github-repo acme/infra --ref main \
--claim repository_id=123456789
OIDC trust "gitlab-deploy" created in tenant "acme" (pending: applied in a few minutes)
subject: project_path:acme/infra:ref_type:branch:ref:main
next: sng tenant policy attach POLICY --oidc-trust gitlab-deploy
FlagEffet
--gitlab-project GROUP/PROJECTÉmetteur https://gitlab.com (ou --gitlab-url), sujet project_path:GROUP/PROJECT:ref_type:branch:ref:REF
--github-repo ORG/REPOÉmetteur https://token.actions.githubusercontent.com, sujet repo:ORG/REPO:ref:refs/heads/REF
--ref REFBranche de confiance (main par défaut, * = toutes)
--claim CLÉ=V1,V2Claims supplémentaires exigés ; ET entre clés, OU entre valeurs
--max-session 15mDurée des sessions ouvertes par ce trust, de 5m à 1h (défaut 1h)
--issuer, --audience, --subjectPour un émetteur quelconque, sans aide
-f FICHIERUn manifeste IAMOIDCTrust ou sa spec, en YAML ou JSON (- = entrée standard)
Épinglez un identifiant stable

Un chemin de projet peut être renommé puis réutilisé par quelqu'un d'autre. project_id (GitLab) et repository_id (GitHub) ne changent jamais : ajoutez-les toujours en --claim.

Le trust est actif quelques minutes plus tard (STATUS passe à applied) :

sng tenant oidc list
NAME ISSUER SUBJECT STATUS
gitlab-deploy https://gitlab.com project_path:acme/infra:ref_type:branch:ref:main applied

sng tenant oidc get gitlab-deploy détaille le trust. Une fois le trust appliqué, la ligne discovery dit si l'émetteur a répondu : ok, ou failed: <cause> (vérifiez l'URL de l'émetteur ; la vérification est refaite à chaque échange de jeton). Un émetteur de la plateforme elle-même est refusé dès la création (issuer "…" is reserved to the platform).

2. Lui donner des droits​

Un trust n'accorde rien par lui-même.

sng tenant policy attach readwrite --oidc-trust gitlab-deploy

readwrite suffit pour sng apply. Pour une policy sur mesure (par exemple deploy:* sans ssm:read), voir Policies. Donnez au pipeline le strict nécessaire.

3. L'utiliser dans le pipeline​

La CLI détecte le jeton du job et ouvre la session toute seule, en mémoire. Il suffit de lui dire sur quel tenant.

VariableRôle
STNG_TENANTTenant visé (obligatoire)
STNG_OIDC_TOKENJeton OIDC du job (GitLab id_tokens)
STNG_OIDC_TOKEN_FILEIdem, dans un fichier
STNG_OIDC_AUDIENCEGitHub seulement : audience à demander (défaut : l'URL de l'API)
STNG_OIDC_TRUSTNom du trust à utiliser si plusieurs trusts du tenant pourraient correspondre

Sous GitHub Actions, la CLI utilise directement ACTIONS_ID_TOKEN_REQUEST_URL et ACTIONS_ID_TOKEN_REQUEST_TOKEN fournis par le runner (avec permissions: id-token: write). Une session expirée est rouverte en redemandant un jeton au CI ; rien n'est écrit sur disque.

Les pipelines complets sont dans GitLab CI et GitHub Actions.

Runner persistant​

Si plusieurs commandes doivent partager une session enregistrée (runner persistant, scripts hors sng), sng sso login --oidc échange le jeton une fois et enregistre la session dans le fichier de configuration du runner :

OIDC session saved: tenant acme (token from STNG_OIDC_TOKEN, expires in 900s)

Ce que le trust exige​

Pour qu'un job ouvre une session, un trust du tenant visé doit correspondre sur tous les points :

Champ du trustCondition
issuerLe jeton vient de cet émetteur (GitLab, GitHub ou celui que vous indiquez)
audiencesLe aud du jeton est dans la liste (par défaut : l'URL de l'API)
subjectLe sub correspond au motif (* autorisé, au moins 8 caractères littéraux avant le premier *)
claimsChaque claim listé a l'une des valeurs attendues
maxSessionDurationBorne la session, quelle que soit la durée du jeton

La session obtenue a pour principal oidc:<tenant>/<trust> : c'est lui que vous voyez dans sng tenant policy principals et dans les journaux.

Dépannage​

SymptômeCause et correction
no CI OIDC token: set STNG_OIDC_TOKEN …Le job n'expose pas de jeton : ajoutez id_tokens (GitLab) ou permissions: id-token: write (GitHub)
OIDC: tenant required: set STNG_TENANT …STNG_TENANT absent
invalid identity tokenAucun trust ne correspond, ou plusieurs : comparez iss, aud, sub affichés par la CLI avec sng tenant oidc get, ou fixez STNG_OIDC_TRUST
jeton OIDC du CI expiréLe jeton fourni par variable a expiré pendant le job : relancez, ou allongez sa durée côté CI
forbidden (no policy of this tenant allows it: see sng tenant policy list)La session est ouverte, mais la policy attachée au trust n'autorise pas cette action

Supprimer un trust​

sng tenant oidc delete gitlab-deploy

Les sessions déjà ouvertes restent valides jusqu'à leur expiration (au plus maxSessionDuration).

Voir aussi​