Aller au contenu
English

Identifiants et accès

  • Leçon 8
  • 45 min
  • Module 3 : Gérer les environnements et les secrets
Leçon 8 sur 15 · CI/CD, tests et mises en production sûresIdentifiants et accès

Ce que vous saurez faire

Laissez le pipeline déployer sans stocker de mot de passe du nuage. Chaque environnement peut modifier seulement sa propre application. La production attend l’approbation d’une personne.

Avant de commencerCe qu’il faut savoir et avoir sous la mainEnviron 45 minutes

Ce que vous devez savoir

Ce qu’il vous faut sur votre ordinateur

  • Votre projet sur la branche feature/deploy, avec deploy/local/ et les deux clés ignorées par Git dans secrets/, dans Séparer la configuration : exercice guidé.
  • Les droits d’administration sur votre dépôt github.com/<you>/ticket-api-ci. Il doit être public : avec le forfait gratuit, les approbateurs obligatoires fonctionnent seulement dans les dépôts publics.
  • Facultatif : l’outil en ligne de commande GitHub gh. Chaque étape GitHub est aussi décrite dans l’interface Web.
  • Parcours réel seulement : le groupe de ressources rg-ticket-api-ci, les applications ticket-api-staging et ticket-api-production, et leurs deux clés, dans Séparer la configuration : exemple détaillé (réel).
  • Si votre projet manque ou ne fonctionne plus, copiez l’instantané end-of-m02, comme dans Utiliser un instantané. Refaites ensuite l’exercice guidé de la dernière leçon.

Exécuté avec GitHub Actions (exécuteurs ubuntu-24.04) dans le dépôt public Nextia-Intelligence/ticket-api-ci, Docker Desktop 4.81.0 sur macOS (puce Apple) et Azure CLI 2.88.0 dans canadacentral. Les étapes pour Windows et Linux ne sont pas testées.

Dans le cours L’essentiel de Docker et du nuage pour les développeurs en IA, Amira déployait depuis son terminal, connectée avec son compte. Maintenant, un exécuteur doit déployer. C’est une nouvelle machine virtuelle que GitHub démarre et supprime pour chaque tâche. Azure lui pose les deux mêmes questions qu’avant :

  1. Qui êtes-vous? L’identité.
  2. Que pouvez-vous faire ici? Le rôle et sa portée.

L’ancienne réponse à la question 1 est un mot de passe. Vous créez un principal de service avec un secret client, puis vous stockez ce secret dans GitHub. Cela fonctionne, mais pose trois problèmes. Le secret reste valide pendant des mois. Il fonctionne depuis n’importe quel ordinateur. Une copie dans un journal ou une copie du dépôt donne donc le même accès que l’original. Et un seul secret sert souvent à tous les environnements.

La réponse dans ce cours n’utilise aucun mot de passe. OIDC (OpenID Connect) permet à un système d’indiquer à un autre qui appelle, au moyen d’un jeton signé. GitHub signe un jeton de courte durée pour chaque tâche. Il dit, par exemple : « C’est une tâche de Nextia-Intelligence/ticket-api-ci dans l’environnement staging (préproduction). » Azure fait confiance à ce jeton seulement s’il correspond à un identifiant fédéré. C’est une règle sur une identité Azure qui précise l’émetteur, l’audience et le sujet du jeton. Le sujet est le texte exact dans le champ sub (sujet) du jeton.

Une séquence en quatre parties : l'exécuteur (tâche Deploy to staging, déployer en préproduction), le fournisseur OIDC de GitHub à token.actions.githubusercontent.com, Microsoft Entra ID (le locataire de l'abonnement) et l'application Azure ticket-api-staging. La tâche s'exécute dans l'environnement staging avec la permission id-token : write, et aucun mot de passe Azure n'est stocké. 1 : azure/login demande à GitHub un jeton d'identité avec l'audience api://AzureADTokenExchange. 2 : GitHub renvoie un jeton d'identité signé de courte durée dont le sujet est repo:usmanahmed99@43086923/ticket-api-ci@1409181261:environment:staging. 3 : l'exécuteur envoie le jeton d'identité et l'AZURE_CLIENT_ID de id-deploy-staging à Entra ID. Entra ID vérifie la signature avec les clés publiques de GitHub. Il compare ensuite l'émetteur, l'audience et le sujet à l'identifiant fédéré de id-deploy-staging. Si le sujet ne correspond pas, Entra ID répond AADSTS700213: No matching federated identity record (aucun enregistrement d'identité fédérée correspondant). Si l'émetteur, l'audience et le sujet correspondent, Entra ID renvoie un jeton d'accès de courte durée pour id-deploy-staging. L'exécuteur appelle ensuite az containerapp update --image avec l'empreinte. Azure vérifie le rôle : Container Apps Contributor (contributeur aux applications conteneurisées) sur cette application seulement. Azure répond avec la nouvelle révision ticket-api-staging--0000001.
L'échange de jetons OIDC. L'exécuteur ne détient aucun secret. Il échange la déclaration signée de GitHub sur la tâche contre un jeton d'accès Azure de courte durée. Seule une correspondance exacte du sujet permet d'en obtenir un.
Description textuelle du diagramme

Lisez de haut en bas. GitHub, et non le fichier du flux de travail, écrit le sujet. Un flux de travail ne peut donc pas prétendre venir d’un autre dépôt ou environnement. Entra ID (le service d’identité de Microsoft, anciennement Azure Active Directory) compare le sujet à l’identifiant fédéré, caractère par caractère. S’ils correspondent, l’exécuteur obtient un jeton d’accès pour une identité. Le rôle de cette identité détermine ce que le jeton peut modifier. Rien dans l’image n’est stocké pour plus tard : les deux jetons expirent rapidement.

Le reste de cette leçon construit les trois parties : les identités Azure, les environnements GitHub et la permission du jeton dans le flux de travail.

Chaque environnement reçoit sa propre identité. Chaque identité reçoit un rôle sur une application : Container Apps Contributor (contributeur aux applications conteneurisées) sur sa propre application conteneurisée. Elle peut y déployer une nouvelle image. Elle ne peut pas modifier l’autre application, supprimer le groupe de ressources ou lire autre chose dans l’abonnement. C’est le principe du moindre privilège, comme dans le cours L’essentiel de Docker et du nuage pour les développeurs en IA. Une limite s’ajoute : la tâche du pipeline de préproduction ne peut pas toucher à la production, même par erreur.

Terminal (live route)
RG=rg-ticket-api-ci
az identity create -g $RG -n id-deploy-staging -o none
PRINCIPAL_ID=$(az identity show -g $RG -n id-deploy-staging --query principalId -o tsv)
APP_ID=$(az containerapp show -g $RG -n ticket-api-staging --query id -o tsv)
az role assignment create --assignee-object-id $PRINCIPAL_ID --assignee-principal-type ServicePrincipal \
--role "Container Apps Contributor" --scope $APP_ID -o none

-o none n’affiche rien en cas de réussite. Faites la même chose pour la production : id-deploy-production et ticket-api-production. Vérifiez ensuite les deux attributions :

Terminal (live route)
az role assignment list --all --query "[?contains(scope,'rg-ticket-api-ci')].{role:roleDefinitionName, scope:scope}" -o table

La sortie (réelle, avec l’ID d’abonnement abrégé) :

Role Scope
-------------------------- ---------------------------------------------------------------------------------------------
Container Apps Contributor /subscriptions/.../resourceGroups/rg-ticket-api-ci/providers/Microsoft.App/containerapps/ticket-api-staging
Container Apps Contributor /subscriptions/.../resourceGroups/rg-ticket-api-ci/providers/Microsoft.App/containerapps/ticket-api-production

Deux lignes, et chaque portée se termine par le nom d’une application. Une portée qui se termine par rg-ticket-api-ci ou par l’abonnement est trop large. Supprimez cette attribution, puis recréez-la avec l’ID de l’application.

Trouvez d’abord le sujet exact que GitHub écrit pour votre dépôt. Interrogez GitHub en lecture seule :

Terminal
gh api repos/<you>/ticket-api-ci/actions/oidc/customization/sub

La sortie pour le dépôt de référence :

{"use_default":true,"use_immutable_subject":true,"sub_claim_prefix":"repo:usmanahmed99@43086923/ticket-api-ci@1409181261"}

use_immutable_subject: true signifie que le sujet contient des ID immuables. Ce sont le numéro du compte propriétaire après @ et le numéro du dépôt après le deuxième @. Une personne peut renommer un compte ou reprendre un ancien nom. Ces numéros ne changent jamais. Le sujet d’une tâche de préproduction est donc :

repo:usmanahmed99@43086923/ticket-api-ci@1409181261:environment:staging

Vos numéros sont différents. Sans gh, ouvrez https://api.github.com/repos/<you>/ticket-api-ci/actions/oidc/customization/sub dans le navigateur. Vous pouvez aussi copier le préfixe du message d’erreur dans le cas d’échec.

Terminal (live route)
PREFIX=$(gh api repos/<you>/ticket-api-ci/actions/oidc/customization/sub --jq .sub_claim_prefix)
echo "${PREFIX}:environment:staging"
az identity federated-credential create -g $RG --identity-name id-deploy-staging --name github-staging \
--issuer https://token.actions.githubusercontent.com \
--subject "${PREFIX}:environment:staging" \
--audiences api://AzureADTokenExchange -o table

Faites la même chose pour la production : --identity-name id-deploy-production --name github-production et :environment:production. Les trois valeurs doivent correspondre exactement au jeton :

Champ Valeur Pourquoi
Émetteur https://token.actions.githubusercontent.com Seulement les jetons signés par GitHub Actions
Audience api://AzureADTokenExchange La valeur demandée par azure/login
Sujet <prefix>:environment:staging Seulement les tâches de ce dépôt dans cet environnement

Le sujet nomme l’environnement, pas une branche. Une tâche reçoit le sujet …:environment:staging seulement si elle s’exécute dans l’environnement GitHub staging. L’environnement détermine quelles branches peuvent l’utiliser. L’environnement GitHub est donc la barrière, et la prochaine section la crée.

Enfin, notez l’ID client de chaque identité. Ce n’est pas un secret : il nomme l’identité et ne sert à rien sans un jeton correspondant à l’identifiant fédéré.

Terminal (live route)
az identity show -g $RG -n id-deploy-staging --query clientId -o tsv
az identity show -g $RG -n id-deploy-production --query clientId -o tsv
az account show --query "{tenant:tenantId, subscription:id}" -o table

Un environnement GitHub est un ensemble nommé de règles, de variables et de secrets dans un dépôt. Une tâche qui le nomme (environment: staging) reçoit ses variables et ses secrets seulement si elle respecte ses règles. Créez-en deux : staging et production.

Dans l’interface Web : Settings → Environments → New environment (paramètres → environnements → nouvel environnement). Pour chacun :

  1. Nommez-le staging (plus tard, production). Le nom doit correspondre au flux de travail et à l’identifiant fédéré.
  2. Sous Deployment branches and tags (branches et étiquettes de déploiement), choisissez Selected branches and tags (branches et étiquettes sélectionnées). Ajoutez la règle main. Maintenant, seules les tâches provenant de main peuvent utiliser cet environnement.
  3. Production seulement : activez Required reviewers (approbateurs obligatoires) et ajoutez-vous. Dans une équipe, ajoutez les personnes autorisées à approuver une mise en production. Enregistrez les règles.
  4. Sous Environment variables (variables d’environnement), ajoutez les quatre variables du tableau ci-dessous, avec les valeurs de cet environnement.
  5. Sous Environment secrets (secrets d’environnement), ajoutez SMOKE_API_KEY avec la clé de cet environnement. Réel : la clé que vous avez donnée à l’application. Simulé : le contenu de secrets/<environment>_api_key.txt.

Ajoutez ensuite deux variables de dépôt (Settings → Secrets and variables → Actions → Variables, soit paramètres → secrets et variables → actions → variables) : AZURE_TENANT_ID et AZURE_SUBSCRIPTION_ID. Elles sont les mêmes pour les deux environnements.

Nom Type staging (valeurs de référence) production
APP_NAME Variable d’environnement ticket-api-staging ticket-api-production
APP_URL Variable d’environnement https://ticket-api-staging.blackhill-8c0e6b69.canadacentral.azurecontainerapps.io https://ticket-api-production.blackhill-8c0e6b69.…
AZURE_CLIENT_ID Variable d’environnement L’ID client de id-deploy-staging (89e675c2-…) L’ID client de id-deploy-production (e06c2c32-…)
RESOURCE_GROUP Variable d’environnement rg-ticket-api-ci rg-ticket-api-ci
SMOKE_API_KEY Secret d’environnement La clé de l’application de préproduction La clé de l’application de production
AZURE_TENANT_ID, AZURE_SUBSCRIPTION_ID Variables de dépôt Une valeur chacune, pour les deux

Pourquoi les ID sont-ils des variables et non des secrets? Aucun ne permet de se connecter seul. Une connexion exige un jeton correspondant à l’identifiant fédéré, et seul GitHub peut en signer un. L’étape azure/login les affiche de toute façon dans le journal. Dans l’exécution de référence, tenant-id: 5908b9a3-… et subscription-id: 223d2ae4-… figurent dans le journal. Un secret sert à stocker une valeur qui donne accès à elle seule, comme la clé d’API.

Avec l’outil en ligne de commande GitHub, les mêmes paramètres prennent la forme de commandes. Elles modifient votre dépôt : exécutez-les seulement sur le vôtre.

Terminal (optional, with gh)
gh variable set APP_NAME --env staging --body ticket-api-staging
gh secret set SMOKE_API_KEY --env staging < secrets/staging_api_key.txt
gh variable set AZURE_TENANT_ID --body <your tenant ID>

gh secret set … < file lit la clé depuis le fichier. Elle n’apparaît donc jamais dans l’historique de votre interpréteur de commandes.

Demandez à GitHub ce qu’il contient, en lecture seule. Le dépôt de référence a répondu ceci (réel, limité aux champs utiles) :

Terminal
gh api repos/<you>/ticket-api-ci/environments --jq '.environments[] | {name, rules: [.protection_rules[].type], can_admins_bypass}'
{"can_admins_bypass":true,"name":"production","rules":["required_reviewers","branch_policy"]}
{"can_admins_bypass":true,"name":"staging","rules":["branch_policy"]}

Les secrets d’environnement affichent leurs noms, jamais leurs valeurs :

{"total_count":1,"secrets":[{"name":"SMOKE_API_KEY","created_at":"2026-10-07T18:05:58Z","updated_at":"2026-10-07T18:05:58Z"}]}

Un secret d’environnement est un secret que seules les tâches d’un environnement peuvent lire. Un secret de dépôt est accessible à toutes les tâches de tous les flux de travail. Cette différence compte au moment de l’approbation. La tâche de production ne démarre pas avant l’approbation. Avant de démarrer, elle ne reçoit rien : ni la clé de production ni un jeton Azure. Un changement dans une demande de tirage (pull request) ne peut pas lire la clé de production. La politique de branches autorise seulement main.

Un approbateur obligatoire est une personne (ou une équipe) qui doit approuver avant qu’une tâche de cet environnement démarre. Pendant l’essai, l’approbateur et l’auteur utilisaient le même compte, car une seule personne a suivi tout le cours. Dans une équipe, l’approbateur est une autre personne. Activez Prevent self-review (empêcher l’autoapprobation) dans l’environnement de production. La personne qui a lancé le déploiement ne pourra donc pas l’approuver. Regardez aussi can_admins_bypass: true ci-dessus : par défaut, un administrateur peut contourner les règles. Dans une équipe, désactivez Allow administrators to bypass configured protection rules (autoriser les administrateurs à contourner les règles de protection configurées).

Le jeton propre au flux de travail, GITHUB_TOKEN, est un troisième identifiant d’accès. GitHub le crée pour chaque exécution, et il peut modifier le dépôt. Avec permissions:, donnez à chaque flux de travail et à chaque tâche seulement les permissions nécessaires. Le flux de travail Deploy (déployer) de la prochaine leçon commence par :

.github/workflows/deploy.yml (part)
permissions:
contents: read

et donne aux tâches de déploiement un droit supplémentaire :

.github/workflows/deploy.yml (part)
permissions:
contents: read
id-token: write

id-token: write ne permet pas à la tâche d’écrire dans le dépôt. Il lui permet de demander un jeton OIDC. Sans cette permission, azure/login ne peut pas en obtenir un. Le journal d’exécution indique ce que le jeton peut faire. Dans la tâche de déploiement de l’exécution 37664760027 (réelle) :

GITHUB_TOKEN Permissions
Contents: read
Metadata: read

La tâche peut lire le code, et rien de plus. Comparez avec le flux de travail Release (mise en production) de la prochaine leçon. Il doit créer une mise en production et étiqueter une image : Contents: write (contenu : écriture), Metadata: read (métadonnées : lecture), Packages: write (paquets : écriture). Chaque flux de travail demande ses propres droits. Aucune tâche n’a de droits qu’elle n’utilise pas.

Le parcours simulé n’a ni identités ni OIDC. Rien sur votre ordinateur ne demande l’accès à un nuage. Il conserve les autres limites :

  • Une clé par environnement. secrets/staging_api_key.txt et secrets/production_api_key.txt contiennent des clés différentes. Compose monte chaque clé seulement dans son propre conteneur api, à /run/secrets/api_key.
  • Aucun secret dans Git. Git ignore secrets/ et .env. Les fichiers de paramètres dans deploy/local/ ne contiennent aucun secret.
  • La clé d’un environnement n’ouvre pas l’autre. Avec les deux environnements locaux en marche, la clé de préproduction envoyée à la production a donné ceci (simulé) :
Terminal (simulated route)
curl -s -o /dev/null -w '%{http_code}\n' -X POST http://127.0.0.1:8082/v1/classify \
-H 'Content-Type: application/json' -H "X-API-Key: $(cat secrets/staging_api_key.txt)" \
-d '{"subject":"Package never arrived"}'
401

La simulation ne peut pas montrer l’identité, le rôle et l’échange OIDC. Lisez les parties réelles de cette leçon pour les comprendre, et regardez les exécutions réelles. L’échec ci-dessous et sa correction sont publics.

  1. Les deux parcours : créez les environnements GitHub staging et production, avec la politique de branches main et l’approbateur obligatoire sur production.
  2. Les deux parcours : ajoutez SMOKE_API_KEY à chaque environnement. Utilisez le fichier correspondant dans secrets/ (simulé) ou la clé de l’application (réel).
  3. Parcours réel : créez les deux identités et leurs attributions de rôles. Vérifiez que az role assignment list affiche deux lignes, chacune limitée à une application.
  4. Parcours réel : lisez votre préfixe de sujet avec gh api …/oidc/customization/sub. Affichez "${PREFIX}:environment:staging" et vérifiez-le visuellement.
  5. Parcours réel : créez les deux identifiants fédérés.
  6. Parcours réel : ajoutez les quatre variables d’environnement à chaque environnement et les deux variables de dépôt.
  7. Vérification : exécutez gh api repos/<you>/ticket-api-ci/environments --jq '.environments[].name'. Résultat attendu : production et staging.
Afficher le résultat attendu

gh api …/environments liste deux environnements. production a les règles required_reviewers (approbateurs obligatoires) et branch_policy (politique de branches), et staging a branch_policy. Chaque environnement contient le secret SMOKE_API_KEY. Réel : chaque environnement contient APP_NAME, APP_URL, AZURE_CLIENT_ID et RESOURCE_GROUP. Le dépôt contient AZURE_TENANT_ID et AZURE_SUBSCRIPTION_ID. az identity federated-credential list -g rg-ticket-api-ci --identity-name id-deploy-staging -o table affiche un identifiant dont le sujet se termine par :environment:staging. Il commence par votre propre repo:<you>@<number>/ticket-api-ci@<number>. Vous n’avez encore rien déployé : le premier déploiement se trouve dans la prochaine leçon.

La tâche de production s’exécute avec environment: production. Supposons qu’une erreur dans un flux de travail envoie l’ID client de préproduction avec le jeton de la tâche de production. Cet ID vient de vars.AZURE_CLIENT_ID, pris au mauvais endroit. Prédisez ce qui se passe à la connexion, et pourquoi. Puis prédisez ce qui arrive si quelqu’un ajoute à id-deploy-staging un deuxième identifiant fédéré avec le sujet …:environment:production.

Afficher la réponse

Le premier cas échoue à la connexion. Le jeton de la tâche de production a le sujet …:environment:production. id-deploy-staging fait confiance uniquement à …:environment:staging. Entra ID répond donc AADSTS700213: No matching federated identity record found (aucune identité fédérée correspondante trouvée). C’est la même erreur que lors du premier déploiement. Cette erreur de configuration ne permet aucun déploiement.

Le deuxième cas supprime la séparation. Une tâche de production pourrait alors se connecter comme id-deploy-staging, tout comme une tâche de préproduction. Elle pourrait modifier seulement l’application de préproduction, car le rôle se limite à celle-ci. Mais les deux environnements partagent maintenant une identité. Gardez une identité par environnement, chacune avec un seul identifiant fédéré. Si vous devez faire un changement, faites-le sur la bonne identité.

Erreur courante

Le sujet montré dans la plupart des guides

Symptôme : la première exécution de Deploy, exécution 37664760027, tentative 1, a échoué après 14 secondes dans la tâche de préproduction. L’étape « Sign in to Azure with this environment’s identity (no password) » (se connecter à Azure avec l’identité de cet environnement, sans mot de passe) a échoué. La tâche de production n’a jamais démarré.

La page publique de l'exécution 1 de Deploy, tentative 1, sans connexion. Une note indique que vous consultez une ancienne tentative. État : Failure (échec), durée totale de 28 secondes, commit 43de57b. Le graphique montre Find the image (trouver l'image), en vert, 4 secondes. Ensuite, staging / Deploy to staging (préproduction / déployer en préproduction), en rouge, 14 secondes. Enfin, production / deploy (production / déployer), non démarré. Sous Annotations, trois erreurs de staging / Deploy to staging : Login failed with Error : The process /usr/bin/az failed with exit code 1 (échec de connexion : le processus /usr/bin/az a échoué avec le code de sortie 1); Run the command below to authenticate interactively (exécutez la commande ci-dessous pour vous authentifier de façon interactive); et AADSTS700213: No matching federated identity record found for presented assertion subject repo:usmanahmed99@4308... (aucune identité fédérée correspondante trouvée pour le sujet de l'assertion présentée).
Tentative 1 du premier déploiement (capture réelle, sans connexion). La connexion a échoué, et le pipeline s'est arrêté avant toute modification en préproduction. La production n'a jamais été atteinte. L’image est en anglais.

Le journal indiquait ceci (extrait réel, abrégé) :

Federated token details:
issuer - https://token.actions.githubusercontent.com
subject claim - repo:usmanahmed99@43086923/ticket-api-ci@1409181261:environment:staging
audience - api://AzureADTokenExchange
Attempting Azure CLI login by using OIDC...
##[error]AADSTS700213: No matching federated identity record found for presented assertion subject 'repo:usmanahmed99@43086923/ticket-api-ci@1409181261:environment:staging'. Check your federated identity credential Subject, Audience and Issuer against the presented assertion.

Cause : l’identifiant fédéré avait le sujet repo:usmanahmed99/ticket-api-ci:environment:staging. C’est le format montré dans la plupart des guides. Les jetons de ce dépôt utilisent des ID immuables. Le jeton indiquait donc repo:usmanahmed99@43086923/ticket-api-ci@1409181261:environment:staging. Un seul caractère différent empêche la correspondance.

Diagnostic : le message d’erreur affiche le sujet envoyé par GitHub. Comparez-le avec az identity federated-credential list -g rg-ticket-api-ci --identity-name id-deploy-staging --query "[].subject" -o tsv. Ou demandez le préfixe à GitHub, comme ci-dessus.

Correction :

  1. Exécutez de nouveau la commande az identity federated-credential create, avec le même --name et le sujet de "${PREFIX}:environment:staging". Elle a remplacé l’ancien sujet lors de l’exécution de test. Faites la même chose pour la production.
  2. Sur la page de l’exécution, choisissez Re-run jobs → Re-run failed jobs (relancer les tâches → relancer les tâches échouées). La tentative 2 a conservé la tâche verte « Find the image » de la tentative 1. Elle a relancé les tâches de préproduction et de production. La préproduction a réussi, et la production a attendu l’approbation.

Pour un vrai service d’IA : cet échec était sûr. La connexion a échoué sans accorder d’accès : aucun jeton, aucun changement, et la production a conservé son ancienne version. Un identifiant de déploiement qui « fonctionne toujours » serait un mot de passe stocké avec des droits étendus. Il fonctionnerait aussi pour un attaquant. Un identifiant qui échoue à cause d’un seul caractère incorrect fonctionne uniquement pour la tâche prévue.

Vérifiez votre compréhension

Pourquoi le cours utilise-t-il des identifiants fédérés OIDC plutôt qu'un secret client Azure stocké dans GitHub?

Afficher la réponse

Un secret client est un mot de passe de longue durée. Quiconque en possède une copie peut l’utiliser depuis n’importe quel ordinateur. Un seul secret sert souvent à tous les environnements. Avec OIDC, vous ne stockez rien. GitHub signe un jeton de courte durée pour chaque tâche. Azure fournit un jeton d’accès seulement si l’émetteur, l’audience et le sujet du jeton correspondent à l’identifiant fédéré. Par exemple, le sujet peut être …:environment:staging. Chaque identité accepte uniquement les tâches de son environnement, et son rôle permet de modifier une seule application.

Vérifiez votre compréhension

Prédisez : une demande de tirage modifie deploy-to.yml pour afficher le secret SMOKE_API_KEY de production. Son exécution CI obtient-elle la clé de production? Expliquez.

Afficher la réponse

Non. SMOKE_API_KEY est un secret d’environnement de production. Une tâche l’obtient seulement si elle s’exécute dans cet environnement et respecte ses règles. La politique de branches autorise seulement main, et la personne responsable de la révision doit approuver. L’exécution d’une demande de tirage n’est pas sur main. Elle ne peut donc pas utiliser l’environnement. Même sur main, le changement nécessiterait d’abord une révision et une approbation. GitHub masque aussi les valeurs des secrets dans les journaux.

Vérifiez votre compréhension

La tâche de déploiement a les permissions contents : read et id-token : write. Que peut-elle faire avec GITHUB_TOKEN, et que permet id-token : write?

Afficher la réponse

Avec GITHUB_TOKEN, la tâche peut seulement lire le dépôt. Le journal montre Contents: read (contenu : lecture) et Metadata: read (métadonnées : lecture). Elle ne peut pas pousser de changements, créer une version publiée ni modifier les paramètres. id-token: write permet à la tâche de demander un jeton d’identité signé au fournisseur OIDC de GitHub. azure/login l’échange contre un jeton d’accès Azure. Sans cette permission, la connexion échoue avant même de commencer.

Récapitulatif

  • Chaque environnement a sa propre identité, id-deploy-staging ou id-deploy-production, avec le rôle Container Apps Contributor limité à sa propre application.
  • OIDC : GitHub signe un jeton de courte durée par tâche. Un identifiant fédéré fait confiance à un émetteur, une audience et un sujet exacts. Aucun mot de passe n’est stocké.
  • Lisez le préfixe du sujet avec gh api …/actions/oidc/customization/sub : ce dépôt utilise des ID immuables (repo:usmanahmed99@43086923/ticket-api-ci@1409181261). Dans zsh, écrivez ${PREFIX} entre accolades.
  • Environnements GitHub staging et production : politique de branches main, révision obligatoire en production, variables d’environnement pour les noms et ID, et secret d’environnement SMOKE_API_KEY.
  • En équipe : activez Prevent self-review (empêcher l’autorévision), sans contournement par les administrateurs.
  • permissions: donne à GITHUB_TOKEN seulement contents: read, plus id-token: write pour les tâches de déploiement.

Tout est prêt pour un déploiement où personne n’a de commande à taper. Dans la prochaine leçon, vous écrirez le flux de travail Deploy et enverrez la première empreinte en préproduction. Le flux attendra votre approbation avant de passer en production.

Leçon suivante : Promouvoir en préproduction