Version : 1.1 · Date : 2026-10-22 · Domaine 4 de l'examen : Develop a security and compliance plan (10 à 15 %)
En une phrase : une chaîne DevOps sûre donne à chaque pipeline une identité sans secret (managed identity, workload identity federation), applique le moindre privilège aux personnes (access levels, groupes, rôles de dépôt) comme aux pipelines (protected resources,
permissionsdu GITHUB_TOKEN), range les secrets restants dans Key Vault sans jamais les afficher, et analyse chaque push, PR, build et image (GHAS, GHAzDO, Dependabot, Defender for Cloud DevOps security).

Ce que l'examen demande#
Repris mot pour mot du guide d'étude AZ-400 (compétences mesurées au 27 juillet 2026) :
| # | Compétence mesurée (guide officiel, en anglais) | Section |
|---|---|---|
| 1 | Choose between Microsoft Entra service principals and managed identities for Azure resources (system-assigned and user-assigned) | 2 |
| 2 | Implement and manage GitHub authentication, including GitHub Apps, GITHUB_TOKEN, and personal access tokens | 3 |
| 3 | Implement and manage Azure DevOps service connections and personal access tokens | 4 |
| 4 | Design and implement permissions and roles in GitHub | 5 |
| 5 | Design and implement permissions and security groups in Azure DevOps | 6 |
| 6 | Recommend appropriate access levels, including stakeholder access in Azure DevOps and outside collaborator access in GitHub | 7 |
| 7 | Configure projects and teams in Azure DevOps | 8 |
| 8 | Implement and manage secrets, keys, and certificates by using Azure Key Vault | 9 |
| 9 | Implement and manage secrets and secretless authentication (for example, workload identity federation/OpenID Connect) in GitHub Actions and Azure Pipelines | 10 |
| 10 | Design and implement a strategy for managing sensitive files during deployment, including Azure Pipelines secure files | 11 |
| 11 | Design pipelines to prevent leakage of sensitive information | 12 |
| 12 | Design a strategy for security and compliance scanning, including dependency, code, secret, and licensing scanning | 13 |
| 13 | Configure Microsoft Defender for Cloud DevOps Security | 14 |
| 14 | Configure GitHub Advanced Security for GitHub and GitHub Advanced Security for Azure DevOps | 15 |
| 15 | Integrate GitHub Advanced Security with Microsoft Defender for Cloud | 16 |
| 16 | Automate container scanning, including scanning container images and configuring an action to run CodeQL analysis in a container | 17 |
| 17 | Automate analysis of vulnerabilities of open-source components by using Dependabot alerts | 18 |
Les bases d'Entra ID (managed identities, workload identity federation) et de Key Vault sont détaillées dans SC-500 : managed identities, workload identity federation, rôles Key Vault et Defender for Cloud DevOps security. Ce chapitre reste côté DevOps : pipelines, dépôts, organisations.
1. Les bases à maîtriser#
| Terme | Ce que c'est |
|---|---|
| Service principal | L'identité d'une app registration dans un tenant Microsoft Entra ; s'authentifie par secret, certificat ou federated credential |
| Managed identity | Identité Entra gérée par Azure, sans secret : system-assigned (liée à une ressource) ou user-assigned (ressource autonome) |
| Workload identity federation (WIF) | Entra fait confiance au jeton OIDC d'un fournisseur externe (Azure DevOps, GitHub) : issuer + subject + audience |
| Service connection | Objet Azure DevOps qui permet à un pipeline d'appeler un service externe (Azure, registre, GitHub…) |
| PAT | Personal access token : jeton d'un utilisateur, avec scopes et expiration (Azure DevOps comme GitHub) |
| GITHUB_TOKEN | Jeton d'installation créé pour chaque job GitHub Actions, limité au dépôt du workflow |
| GitHub App | Application installée sur une organisation ou des dépôts, avec ses propres permissions, indépendante d'un utilisateur |
| Protected resource | Ressource Azure DevOps qu'un pipeline doit être autorisé à utiliser : service connection, agent pool, variable group, secure file, environment, repository |
| GHAS | GitHub Advanced Security, vendu en GitHub Secret Protection et GitHub Code Security |
| GHAzDO | GitHub Advanced Security for Azure DevOps : les mêmes moteurs sur Azure Repos |
| MSDO | Microsoft Security DevOps : extension Azure DevOps et action GitHub qui lancent des analyseurs (Trivy, Checkov, Bandit…) |
2. Service principal ou managed identity#

| Critère | Service principal (app registration) | System-assigned MI | User-assigned MI |
|---|---|---|---|
| Où vit l'identité | Microsoft Entra ID | Sur la ressource (VM, App Service…) | Ressource Azure autonome |
| Cycle de vie | Géré par vous | Supprimée avec la ressource | Géré par vous, partageable |
| Secret | Secret ou certificat, ou federated credential | Aucun | Aucun (federated credential possible) |
| Utilisable hors d'Azure | Oui (avec WIF) | Non | Oui, via federated credential |
| Cas DevOps typique | Service connection, workflow GitHub | Agent self-hosted sur une VM Azure | Plusieurs pipelines ou plusieurs ressources, identité stable |
flowchart TD
A[Le code qui s'authentifie tourne-t-il sur une ressource Azure ?] -->|Oui| B[Une seule ressource ?]
B -->|Oui| C[System-assigned managed identity]
B -->|Non, plusieurs| D[User-assigned managed identity]
A -->|Non : Azure DevOps hébergé, GitHub Actions| E[Workload identity federation]
E --> F[App registration + federated credential]
E --> G[User-assigned managed identity + federated credential]
A -->|Outil ancien sans OIDC| H[Service principal + secret ou certificat, en dernier recours]
À retenir :
- Une managed identity n'est utilisable que depuis une ressource Azure ; un agent Microsoft-hosted ou un runner GitHub-hosted n'en a pas. Pour eux : workload identity federation, sur une app registration ou une user-assigned managed identity.
- Le choix entre app registration et user-assigned MI pour la federation tient souvent à l'organisation : créer une app registration demande des droits Entra (Users can register applications ou un rôle comme Application Developer), créer une user-assigned MI demande seulement un rôle Azure sur un resource group.
- Une app registration ou une user-assigned MI accepte au plus 20 federated credentials.
- Le rôle Azure (RBAC) se donne au plus petit scope utile : resource group plutôt qu'abonnement.
3. L'authentification côté GitHub#

3.1 Le GITHUB_TOKEN#
Avant chaque job, GitHub crée un jeton d'installation exposé en secrets.GITHUB_TOKEN (ou github.token). Il ne vaut que pour
le dépôt du workflow et expire à la fin du job.
- Les droits par défaut se règlent dans Settings > Actions > General > Workflow permissions (organisation ou dépôt) : Read and write permissions ou Read repository contents and packages permissions (le plus sûr).
- Le bloc
permissions(au niveau du workflow ou du job) restreint le jeton. Dès qu'une permission est citée, toutes les autres passent ànone.permissions: {}retire tout. - Un événement déclenché avec le GITHUB_TOKEN (push, création de PR…) ne lance pas d'autre workflow, sauf
workflow_dispatchetrepository_dispatch: cela évite les boucles.
# .github/workflows/ci.yml : jeton réduit au strict nécessaire
permissions:
contents: read # cloner le dépôt
jobs:
build:
runs-on: ubuntu-latest
permissions:
contents: read
pull-requests: write # ce job seul commente la PR
steps:
- uses: actions/checkout@v4
- run: gh pr comment "$PR" --body "Build OK"
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
PR: ${{ github.event.pull_request.number }}
3.2 GitHub App, OAuth app ou PAT#
| Besoin | Choix | Pourquoi |
|---|---|---|
| Agir sur le dépôt du workflow | GITHUB_TOKEN | Gratuit, éphémère, déjà là |
| Agir sur d'autres dépôts ou l'organisation, en automatisation | GitHub App | Permissions fines, dépôts choisis à l'installation, jetons d'installation courts, pas liée à une personne qui part |
| Agir au nom d'un utilisateur dans une application | GitHub App (user access token) ou OAuth app | L'app agit avec les droits de l'utilisateur |
| Script ponctuel d'un utilisateur | Fine-grained PAT | Dépôts et permissions choisis, expiration obligatoire, l'organisation peut exiger une approbation |
| Rien d'autre ne marche | Classic PAT | Scopes larges (repo = tous les dépôts) : à éviter |
Dans un workflow, une GitHub App s'utilise en stockant son Client ID (différent de l'App ID) et sa clé privée (secret),
puis en générant un jeton d'installation au début du job avec actions/create-github-app-token@v3 (inputs client-id et
private-key). Les organisations peuvent restreindre ou exiger l'approbation des fine-grained PAT et bloquer les classic PAT.
4. Service connections et PAT Azure DevOps#
4.1 La service connection Azure Resource Manager#

Project settings > Service connections > New service connection > Azure Resource Manager. Les options d'identité :
| Option | Ce qu'Azure DevOps fait | À retenir |
|---|---|---|
| App registration (automatic) + workload identity federation | Crée l'app registration, la federated credential et le rôle | Recommandé ; il faut le droit de créer une app et d'attribuer un rôle sur le scope |
| App registration or managed identity (manual) + WIF | Vous créez l'identité et la federated credential, avec l'Issuer et le Subject identifier affichés | Quand l'équipe identité est séparée de l'équipe DevOps |
| Managed identity (agent-assigned) | Utilise l'identité de la VM de l'agent self-hosted | Agents self-hosted sur Azure seulement |
| App registration + secret | Stocke un secret qui expire | Compatibilité ; erreur AADSTS7000215 = secret invalide ou expiré |
| Publish profile | Profil de publication App Service | Compatibilité |
sequenceDiagram
participant P as Pipeline (job)
participant ADO as Azure DevOps
participant E as Microsoft Entra ID
participant A as Azure Resource Manager
P->>ADO: tâche AzureCLI@2 avec azureSubscription: sc-prod
ADO->>P: jeton OIDC (issuer, subject sc://org/projet/sc-prod)
P->>E: échange du jeton OIDC (audience api://AzureADTokenExchange)
E->>E: compare issuer + subject + audience à la federated credential
E->>P: jeton d'accès Entra (courte durée)
P->>A: appels ARM avec le rôle RBAC de l'identité
# azure-pipelines.yml : la service connection ne contient aucun secret
steps:
- task: AzureCLI@2
inputs:
azureSubscription: sc-prod # nom de la service connection ARM en WIF
scriptType: bash
scriptLocation: inlineScript
inlineScript: az group show --name rg-app-prod --query id -o tsv
Convertir une connexion à secret : bouton Convert dans la service connection. Il ne fonctionne que si la connexion a été créée automatiquement par Azure DevOps et n'est utilisée que par un projet ; sinon, conversion manuelle (ajouter la federated credential à l'identité). La conversion peut être annulée pendant 7 jours.
Changement d'issuer : les connexions WIF anciennes utilisent l'issuer Azure DevOps (vstoken.dev.azure.com), retiré le
1er juillet 2027 au profit de l'issuer Microsoft Entra (https://login.microsoftonline.com/{tenant-id}). Le pipeline
affiche un avertissement ; on convertit depuis la service connection. Hors périmètre : clouds non publics et apps multitenant.
Si l'organisation, le projet ou la connexion est renommé, le subject ne correspond plus (AADSTS70021) : mettre à jour la
federated credential.
4.2 Sécuriser la service connection elle-même#
Une service connection est une protected resource (voir 6.3) :
- Security : rôles User (l'utiliser), Creator, Administrator ; donner User aux seules personnes utiles.
- Pipeline permissions : n'autoriser que les pipelines nommés. Grant access permission to all pipelines (open access) est déconseillé, et Defender for Cloud a une recommandation dédiée : Azure DevOps service connections shouldn't grant access to all pipelines.
- Approvals and checks : approbation, horaires, Required template, Business hours, branche protégée.
- Une connexion par environnement (
sc-dev,sc-prod), chacune avec son identité et son rôle RBAC.
4.3 Les PAT Azure DevOps#
Un PAT agit au nom de l'utilisateur, avec ses droits limités par des scopes (Code Read, Build Read & execute…) et une
expiration (un an au maximum). Microsoft recommande de préférer les jetons Microsoft Entra (az account get-access-token --resource 499b84ac-1321-427f-aa17-267ca6975798, l'ID de ressource Azure DevOps) et, pour les pipelines, des service
connections en WIF.
| Politique | Où | Effet |
|---|---|---|
| Restrict personal access token (PAT) creation | Organization settings > Policies (Project Collection Administrators) | Seuls les utilisateurs d'une allowlist créent des PAT ; option « packaging seulement » ; bloque les PAT globaux |
| Restrict global personal access token creation | Microsoft Entra, Azure DevOps Administrator | Interdit les PAT valables sur toutes les organisations |
| Restrict full-scoped personal access token creation | Idem | Interdit les PAT « Full access » |
| Enforce maximum personal access token lifespan | Idem | Durée maximale imposée |
| Revoke leaked PATs | Activé par défaut | Un PAT trouvé dans un dépôt GitHub public est révoqué automatiquement |
Dates à connaître : les PAT globaux (toutes organisations) cessent de fonctionner le 1er décembre 2026 ; l'Azure DevOps OAuth est déprécié (plus de nouvelles apps depuis avril 2025) au profit de Microsoft Entra.
5. Permissions et rôles dans GitHub#

| Niveau | Rôles | À retenir |
|---|---|---|
| Organisation | Owner, Member, Billing manager, Security manager… | Les owners ont un accès admin à tous les dépôts ; en avoir au moins deux, pas plus que nécessaire |
| Base permissions | No permission, Read, Write, Admin | Droit minimal de tous les members sur tous les dépôts : le laisser bas (No permission ou Read) |
| Teams | Un rôle par dépôt ; équipes imbriquées | Les équipes enfants héritent des accès de l'équipe parente |
| Dépôt | Read, Triage, Write, Maintain, Admin | Le droit effectif est le plus élevé reçu (base, équipe, direct) |
| Custom repository roles | Un rôle de base + des permissions ajoutées | GitHub Enterprise Cloud seulement |
Les cinq rôles de dépôt :
- Read : lire, cloner, ouvrir des issues et commenter.
- Triage : gérer issues et PR (labels, assignations) sans écrire de code.
- Write : pousser, fusionner, gérer les workflows.
- Maintain : gérer le dépôt sans les actions sensibles ou destructrices.
- Admin : tout, y compris la sécurité, les accès et la suppression. Seul ce rôle gère les accès au dépôt.
Les protections qui complètent les rôles : branch protection rules et rulesets (voir chapitre 02), CODEOWNERS pour les revues obligatoires, et environments (reviewers requis, branches autorisées, secrets d'environment) pour les déploiements.
6. Permissions et groupes de sécurité dans Azure DevOps#

6.1 Trois notions à ne pas confondre#
- Access level : ce que l'utilisateur voit (licence) : Stakeholder, Basic, Basic + Test Plans, Visual Studio subscriber.
- Groupe de sécurité et permissions : ce qu'il peut faire.
- Protected resources : ce que chaque pipeline peut utiliser.
Un utilisateur Stakeholder membre de Project Administrators ne peut toujours pas utiliser Repos : l'access level l'emporte.
6.2 Les groupes et l'héritage#
| Niveau | Groupes intégrés principaux |
|---|---|
| Organisation (collection) | Project Collection Administrators, Project Collection Build Administrators, Project Collection Valid Users, Project-Scoped Users… |
| Projet | Project Administrators, Contributors, Readers, Build Administrators, Release Administrators, Project Valid Users, un groupe par team |
- Les permissions prennent trois états : Allow, Deny, Not set (refus implicite), et s'héritent organisation → projet → objet (dépôt, branche, pipeline, dossier). Un Deny explicite l'emporte en général sur un Allow hérité.
- Les permissions de Project Collection Administrators ne se modifient pas.
- Bonne pratique : ajouter des groupes Microsoft Entra aux groupes intégrés plutôt que des utilisateurs un par un.
- Sécurité par objet : un dépôt ou une branche (Repos > Security), un pipeline ou un dossier de pipelines.
6.3 Les protected resources#
Pour une service connection, un agent pool, un variable group, un secure file, un environment ou un dépôt :
- Security (utilisateurs) : rôles User, Creator, Administrator (selon la ressource).
- Pipeline permissions : quels pipelines y ont droit ; le premier run d'un pipeline non autorisé attend une autorisation.
- Approvals and checks : approbation, branche protégée, Required template, Invoke Azure Function, Business hours… (ordre d'évaluation et Bypass check : chapitre 04, § 10.2).
Réglages de projet utiles (Project settings > Pipelines > Settings) : Limit job authorization scope to current project, Protect access to repositories in YAML pipelines, Limit variables that can be set at queue time.
7. Recommander le bon niveau d'accès#
| Profil | Azure DevOps | GitHub |
|---|---|---|
| Métier qui suit et approuve | Stakeholder (gratuit, sans limite de nombre) | Member avec Read, ou Triage pour trier les issues |
| Développeur interne | Basic (les 5 premiers gratuits) + Contributors | Member d'une team avec Write |
| Testeur qui gère des plans de test | Basic + Test Plans | — |
| Abonné Visual Studio | Access level Visual Studio subscriber (selon l'abonnement) | — |
| Prestataire externe sur un projet | Utilisateur invité (B2B) en Basic, limité au projet | Outside collaborator sur les seuls dépôts utiles |
| Équipe sécurité | Lecteur + accès aux alertes Advanced Security | Rôle Security manager |
Stakeholder (projets privés) : accès partiel à Boards (work items), voir et approuver les releases et les déploiements, pas d'accès à Repos ni à Test Plans. Il ne crée ni ne modifie les pipelines. Les projets publics donnent davantage aux stakeholders, mais Microsoft retire les projets publics (conversion en privé à partir de 2027).
Outside collaborator : personne hors de l'organisation GitHub invitée sur un ou plusieurs dépôts précis, avec un rôle de dépôt. Elle ne voit ni les autres dépôts ni les teams, mais occupe une licence payante dès qu'elle accède à un dépôt privé (sauf sur un plan gratuit). Un admin de dépôt peut inviter des outside collaborators si l'organisation le permet.
8. Projets et équipes dans Azure DevOps#
- Projet (Organization settings > Projects > New project) : visibilité (privée), processus (Basic, Agile, Scrum, CMMI), services activés (Project settings > Overview : désactiver Boards, Repos, Test Plans… inutiles). Un projet par produit ou domaine ; éviter un projet par équipe.
- Team (Project settings > Teams > New team) : crée un groupe de sécurité au nom de l'équipe et, si demandé, une area path. Chaque équipe a ses team administrators, ses area paths, ses iterations (300 au maximum par équipe), son backlog, son tableau, ses notifications.
- Le team administrator configure l'équipe (backlogs, sprints, membres) sans être Project Administrator.
- Les permissions sur les work items se règlent par area path (Project settings > Boards > Project configuration).
# Azure DevOps CLI (extension azure-devops), à lancer dans une organisation de test
az devops team create --name "Equipe Paiement" --project "Projet-Demo" --org https://dev.azure.com/{organisation}
az devops team list --project "Projet-Demo" --org https://dev.azure.com/{organisation} -o table
9. Key Vault dans les pipelines#
Key Vault range trois types d'objets (voir SC-500, chapitre 02) : secrets (chaînes), keys (clés cryptographiques, l'opération se fait dans le coffre) et certificates (avec leur cycle de vie ; la partie privée est lisible comme secret si elle est exportable).
| Méthode | Quand | Droits de l'identité de la service connection |
|---|---|---|
| Variable group lié à Key Vault | Plusieurs pipelines partagent les mêmes secrets | Get + List (access policy) ou Key Vault Secrets User (RBAC) |
| Tâche AzureKeyVault@2 | Un pipeline lit des secrets au moment voulu | Idem |
az keyvault … après azure/login (GitHub) |
Workflow GitHub Actions | Rôle RBAC minimal sur le coffre |
| Opérations sur keys (signer, chiffrer) | Signature d'artefacts | Key Vault Crypto User |
| Lecture d'un certificate | Déployer un certificat | Key Vault Certificate User (ou Secrets User pour la partie privée) |
Le variable group lié à Key Vault :
- seuls les noms des secrets sont mappés ; la valeur est lue à chaque run (une rotation est prise en compte seule) ;
- un secret ajouté ou supprimé dans le coffre n'apparaît pas tout seul : mettre à jour le variable group ;
- il ne mappe que des secrets, pas les keys ni les certificates ;
- Key Vault privé : autoriser les IP statiques d'Azure DevOps de la géographie de l'organisation, ou lire le coffre depuis un agent self-hosted dans le réseau. Un coffre en RBAC derrière un private endpoint n'est pas supporté par le variable group (Azure DevOps n'est pas un trusted service) : utiliser le modèle Vault access policy ou un agent self-hosted.
variables:
- group: vg-kv-app-prod # variable group lié à Key Vault
steps:
- task: AzureKeyVault@2 # alternative : lire au moment voulu
inputs:
azureSubscription: sc-prod
KeyVaultName: kv-app-prod
SecretsFilter: 'DbPassword' # jamais '*' en production : le minimum utile
RunAsPreJob: false
- script: ./deploy.sh
env:
DB_PASSWORD: $(DbPassword) # un secret n'est jamais exposé seul en variable d'environnement
10. Secrets et authentification sans secret#

10.1 GitHub Actions vers Azure en OIDC#
- Créer une app registration ou une user-assigned MI, lui donner un rôle Azure minimal.
- Ajouter une federated credential : issuer
https://token.actions.githubusercontent.com, audienceapi://AzureADTokenExchange, et un entity type : Environment, Branch, Pull request ou Tag (subjectrepo:{org}/{repo}:environment:production,…:ref:refs/heads/main,…:pull_request,…:ref:refs/tags/v1), sans joker. - Ranger
AZURE_CLIENT_ID,AZURE_TENANT_IDetAZURE_SUBSCRIPTION_IDen secrets (ce ne sont pas des mots de passe, mais on évite de les exposer).
name: deploy
on:
push:
branches: [main]
permissions:
id-token: write # obligatoire pour demander le jeton OIDC
contents: read
jobs:
deploy:
runs-on: ubuntu-latest
environment: production # le subject de la federated credential vise cet environment
steps:
- uses: actions/checkout@v4
- uses: azure/login@v2
with:
client-id: ${{ secrets.AZURE_CLIENT_ID }}
tenant-id: ${{ secrets.AZURE_TENANT_ID }}
subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
- run: az group show --name rg-app-prod
Le subject doit correspondre exactement : une federated credential de type Branch main refuse un job lancé sur un
environment, et une erreur de saisie dans le subject ne se voit qu'à l'échange du jeton.
10.2 Les secrets GitHub#
| Portée | Usage |
|---|---|
| Organization secrets | Partagés, limités à des dépôts choisis |
| Repository secrets | Un dépôt |
| Environment secrets | Lus seulement par un job qui cible l'environment, après ses protections (reviewers requis, branches autorisées) |
Les secrets ne sont pas transmis aux workflows déclenchés depuis un fork (sauf le GITHUB_TOKEN, en lecture seule).
10.3 Les secret variables d'Azure Pipelines#
- Définies dans l'interface du pipeline (cadenas), dans un variable group ou dans Key Vault ; chiffrées (RSA 2048).
- Pas mappées automatiquement en variables d'environnement des scripts : les passer par
env:. - Créées dans un script avec la commande de journalisation
##vso[task.setvariable variable=nom;issecret=true]valeur. - Non transmises aux builds de fork par défaut (Make secrets available to builds of forks désactivé).
11. Les fichiers sensibles : secure files#
Certificats .pfx, profils de provisioning, clés SSH, fichiers .p12 : ils ne vont jamais dans le dépôt. Pipelines >
Library > Secure files :
- 10 MB maximum par fichier, chiffrés au repos ;
- protected resource : Security (rôles), Pipeline permissions, Approvals and checks ;
- téléchargés par DownloadSecureFile@1 (agent 2.182.1 ou plus récent) dans un dossier temporaire, et supprimés à la fin du job.
steps:
- task: DownloadSecureFile@1
name: certSigning # nom de référence pour lire le chemin
inputs:
secureFile: 'signing-cert.pfx'
- script: ./sign.sh "$(certSigning.secureFilePath)"
Alternatives : un certificate Key Vault lu au moment du déploiement ; côté GitHub, un fichier encodé en base64 dans un
secret (limité en taille) ou, mieux, la récupération depuis Key Vault après azure/login.
12. Empêcher les fuites d'informations sensibles#
Le masquage des journaux est un filet, pas une protection : Azure Pipelines et GitHub masquent la valeur exacte d'un secret déclaré, mais pas une sous-chaîne, pas une valeur transformée (base64, URL-encodée) ni un secret stocké en JSON ou en données structurées.
| Règle | Azure Pipelines | GitHub Actions |
|---|---|---|
| Pas de secret quand c'est possible | Service connection en WIF | OIDC (id-token: write) |
| Moindre privilège du jeton du job | Limit job authorization scope, permissions du Build Service | permissions au plus juste |
| Ne jamais afficher | Pas d'echo, pas de set -x, pas en argument de ligne de commande (visible dans la liste des processus) |
Idem ; ::add-mask:: pour une valeur calculée |
| Passer les secrets proprement | env: explicite ; System.AccessToken seulement si nécessaire |
env: plutôt que ${{ secrets.X }} dans le texte d'un run |
| Contributions externes | Pas de secrets pour les builds de fork | Prudence avec pull_request_target (code du fork + secrets) |
| Variables modifiables au lancement | Limit variables that can be set at queue time, settableVariables sur les steps |
inputs typés de workflow_dispatch |
| Dépendances de la chaîne | Extensions validées, Required template | Actions épinglées par SHA, liste d'actions autorisées |
| Détection | GHAzDO push protection, secret scanning | Push protection, secret scanning |
| Agents | Agents éphémères (Microsoft-hosted, Managed DevOps Pools) | Runners GitHub-hosted ; jamais de self-hosted sur un dépôt public |
# Azure Pipelines : un step qui ne peut modifier aucune variable
steps:
- script: ./outil-tiers.sh
target:
settableVariables: none
Un secret a fuité : le révoquer et le remplacer d'abord (Key Vault, rotation), puis le retirer du code ; le supprimer de l'historique Git ne suffit pas, il a pu être copié.
13. La stratégie d'analyse#

| Type d'analyse | Ce qu'elle trouve | Moment idéal |
|---|---|---|
| Secret scanning | Clés, jetons, mots de passe dans le code et l'historique | Push (push protection) puis en continu |
| Dependency scanning (SCA) | Dépendances open source vulnérables (CVE) | PR (dependency review) et build |
| Code scanning (SAST) | Failles dans le code (injection, XSS…) : CodeQL | PR et branche par défaut, planifié |
| License scanning | Licences interdites par la politique (GPL dans un produit propriétaire…) | PR : dependency review sur GitHub ; rien de documenté dans GHAzDO (outil tiers) |
| IaC scanning | Mauvaises configurations Terraform, Bicep, ARM, Kubernetes | PR et build (Checkov, Template Analyzer, Terrascan) |
| Container scanning | CVE des images, de l'OS de base aux paquets | Build, registre, runtime |
Principes d'une stratégie :
- Shift left : bloquer au plus tôt (push, PR), là où corriger coûte le moins ; garder une analyse planifiée pour les CVE découvertes après coup.
- Bloquer seulement ce qui est grave (seuil de sévérité) pour ne pas noyer les équipes ; le reste en alertes suivies.
- Rendre les contrôles obligatoires : branch policy Build validation (Azure Repos), required status checks ou rulesets (GitHub).
- Centraliser les résultats (SARIF, Defender for Cloud) pour une vue de posture unique.
14. Defender for Cloud DevOps security#

Connecter : Defender for Cloud > Environment settings > Add environment : Azure DevOps, GitHub ou GitLab. Le connecteur est une ressource Azure (abonnement, resource group) ; il faut Security Admin côté Azure et des droits d'administration côté plateforme (Project Collection Administrator, owner d'organisation GitHub).
| Fonction | Foundational CSPM (gratuit) | Defender CSPM (payant) |
|---|---|---|
| Inventaire des dépôts, console DevOps security | Oui | Oui |
| Recommandations de posture DevOps (configuration des organisations, service connections…) | Oui | Oui |
| Remontée des findings (GHAS, GHAzDO, MSDO) | Oui | Oui |
| PR annotations | — | Oui |
| Code-to-cloud mapping, attack path, cloud security explorer | — | Oui |
| Agentless code scanning | — | Oui |
| Intégration GHAS (runtime → GitHub) | — | Oui (+ licence GHAS) |
PR annotations : DevOps security > sélectionner les dépôts > Configure > activer les annotations. Sur Azure DevOps, seulement pour les findings IaC, avec une branch policy Build validation qui lance MSDO. Sur GitHub, elles demandent GHAS. Pas d'annotations pour GitLab.
Microsoft Security DevOps dans le pipeline (extension Microsoft Security DevOps à installer depuis le Marketplace) :
steps:
- task: MicrosoftSecurityDevOps@1
inputs:
categories: 'IaC,containers' # code, artifacts, IaC, containers
break: true # échoue si un résultat bloquant est trouvé
publish: true # publie le SARIF dans l'onglet Scans
Côté GitHub : l'action microsoft/security-devops-action@v1, puis github/codeql-action/upload-sarif pour envoyer le SARIF
vers code scanning. Outils exécutés selon la catégorie : AntiMalware, Bandit, BinSkim, Checkov, ESLint, IaCFileScanner,
Template Analyzer, Terrascan, Trivy.
15. GitHub Advanced Security (GHAS) et GHAzDO#
15.1 Sur GitHub#
| Produit | Fonctions | Activation |
|---|---|---|
| GitHub Secret Protection | Secret scanning (dépôt et historique), push protection, validity checks, custom patterns | Settings > Advanced Security (dépôt) ou security configurations (organisation) |
| GitHub Code Security | Code scanning (CodeQL, outils tiers en SARIF), dependency review, Copilot Autofix, security campaigns | Idem |
| Gratuit pour tous | Dependabot alerts et security updates, dependency graph ; sur les dépôts publics, secret scanning et code scanning | — |
Code scanning : default setup (GitHub choisit langages et requêtes, rien à écrire) ou advanced setup (un workflow
codeql.yml personnalisable : langages, build, requêtes security-extended, planification).
15.2 Sur Azure DevOps (GHAzDO)#
Vendu en deux produits : GitHub Secret Protection for Azure DevOps et GitHub Code Security for Azure DevOps (l'ancien bundle reste pour les clients existants). Facturé par committer actif (un push dans les 90 derniers jours), dédoublonné par abonnement Azure. Seulement Azure DevOps Services et dépôts Git.
- Activer : au niveau du dépôt (Project settings > Repositories > {dépôt} > Settings), du projet ou de l'organisation, en confirmant Begin billing.
- Push protection : bloque les pushs qui contiennent un secret ; n'évalue que les pushs après l'activation. Le secret scanning du dépôt, lui, analyse aussi l'historique.
- Dependency scanning et code scanning (CodeQL) : des tâches de pipeline. Les alertes apparaissent dans Repos > Advanced Security.
# GHAzDO : dependency scanning et CodeQL dans un pipeline Azure Repos
steps:
- task: AdvancedSecurity-Codeql-Init@1
inputs:
languages: 'csharp'
enableAutomaticCodeQLInstall: true # utile sur un agent self-hosted
- task: DotNetCoreCLI@2
inputs:
command: build
- task: AdvancedSecurity-Dependency-Scanning@1
- task: AdvancedSecurity-Codeql-Analyze@1
Pour un langage interprété (JavaScript, Python), buildtype: none évite l'étape de build. AdvancedSecurity-Publish@1 publie
dans Advanced Security un SARIF produit par un autre outil.
16. Intégrer GHAS à Defender for Cloud#
Intégration GA depuis le 3 mai 2026. Elle relie le code (GHAS) au runtime (Defender for Cloud) dans les deux sens.
| Prérequis | Rôles |
|---|---|
| Connecteur GitHub dans Defender for Cloud | Security Admin sur l'abonnement |
| Licence GHAS sur les dépôts connectés | Owner de l'organisation GitHub |
| Defender CSPM activé sur l'abonnement | Security Copilot facultatif (remédiation automatisée) |
| Clouds commerciaux seulement | — |
Ce qu'elle apporte :
- Code-to-runtime mapping automatique : quelle image en production vient de quel dépôt.
- Runtime risk factors dans les alertes GHAS : Internet Exposure, Sensitive Data, Critical Resources, Lateral Movement (issus de l'attack path analysis de Defender CSPM).
- Copilot Autofix et security campaigns lancées depuis Defender for Cloud ; création d'issues GitHub assignées aux CODEOWNERS.
- Synchronisation bidirectionnelle du statut des issues.
Mise en route : connecteur GitHub, agentless code scanning activé, GHAS actif sur les dépôts (Advanced security status : On dans DevOps security). Comptez jusqu'à 24 heures avant les premiers résultats.
17. Analyser les conteneurs et CodeQL dans un conteneur#
Analyser les images :
- dans le pipeline : Trivy via MSDO (catégorie
containers), ou le Defender CLI (tâcheMicrosoftDefenderCLI@2, demande Defender CSPM) qui analyse l'image avant le push et remonte les résultats dans Defender for Cloud ; - dans le registre et au runtime : Defender for Containers (analyse des images d'Azure Container Registry, détection au runtime, gated deployment sur Kubernetes) ;
- Dependabot suit aussi les images de base d'un
Dockerfile(écosystèmedocker).
CodeQL dans un conteneur : quand le build a besoin d'une image précise (compilateur, SDK), le job entier tourne dans le conteneur. Toutes les étapes doivent s'y exécuter, et les images Alpine (musl) ne sont pas supportées.
name: codeql-container
on: [push, pull_request]
jobs:
analyze:
runs-on: ubuntu-latest
container:
image: mcr.microsoft.com/dotnet/sdk:8.0 # image qui contient la chaîne de build
permissions:
security-events: write # publier les résultats de code scanning
actions: read
contents: read
steps:
- uses: actions/checkout@v4
- uses: github/codeql-action/init@v4
with:
languages: csharp
- run: dotnet build
- uses: github/codeql-action/analyze@v4
18. Dependabot alerts#
flowchart LR
A[Dependency graph<br>manifestes, lockfiles] --> C{Dépendance vulnérable ?}
B[GitHub Advisory Database] --> C
C -->|oui| D[Dependabot alert<br>branche par défaut]
D --> E[Notification<br>write, maintain, admin]
D --> F[Dependabot security update<br>PR de correction]
D --> G[Auto-triage rules<br>ignorer, reporter]
- Dependabot alerts : comparent le dependency graph de la branche par défaut à la GitHub Advisory Database ; gratuites, activables par dépôt (Settings > Advanced Security) ou pour toute l'organisation. Notifications aux personnes qui ont Write, Maintain ou Admin et suivent le dépôt.
- Dependabot security updates : ouvrent une PR qui monte la dépendance à la version corrigée.
- Dependabot version updates : maintiennent les dépendances à jour, même sans faille, via
.github/dependabot.yml. - Auto-triage rules : ignorer ou reporter automatiquement des alertes (par exemple, faible impact sur les dépendances de développement).
- Dependency review (dans la PR) : montre les dépendances ajoutées, leur sévérité et leur licence ; l'action
actions/dependency-review-actionfait échouer la PR selonfail-on-severity(low à critical) etallow-licensesoudeny-licenses(identifiants SPDX). Dépôts publics, ou privés avec GitHub Code Security.
# .github/dependabot.yml : mises à jour de versions, en plus des alertes
version: 2
updates:
- package-ecosystem: "nuget"
directory: "/"
schedule:
interval: "weekly"
- package-ecosystem: "docker"
directory: "/"
schedule:
interval: "weekly"
# .github/workflows/dependency-review.yml : bloquer une PR qui ajoute une faille ou une licence refusée
on: pull_request
permissions:
contents: read
jobs:
review:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/dependency-review-action@v4
with:
fail-on-severity: high
allow-licenses: MIT, Apache-2.0, BSD-3-Clause
Sur Azure Repos, Dependabot n'existe pas nativement : on utilise le dependency scanning de GHAzDO.
19. Labs conseillés#
Dans un abonnement et une organisation de test, jamais en production. Coûts : GHAzDO est facturé par committer actif (désactiver à la fin), Defender CSPM est payant (le connecteur seul, en Foundational CSPM, est gratuit). Aucun secret réel dans les dépôts : des valeurs factices.
- Service connection WIF (30 min) : créer une connexion ARM App registration (automatic) sur un resource group de test,
lancer un
AzureCLI@2, regarder l'Issuer et le Subject identifier dans la connexion et la federated credential dans Entra. Restreindre les Pipeline permissions à un seul pipeline. Résultat attendu : un deuxième pipeline attend une autorisation. - GitHub OIDC (30 min) : federated credential de type Environment
production, workflowazure/login@v2avecid-token: write. Lancer depuis une autre branche sans environment. Résultat attendu :AADSTS70021, puis succès avec l'environment. - Key Vault et secure files (30 min) : variable group lié à un coffre de test (Key Vault Secrets User), un secure file
factice téléchargé par
DownloadSecureFile@1. Afficher la valeur avececho, puis en base64. Résultat attendu : la première est masquée, la seconde ne l'est pas (d'où la règle « ne jamais afficher »). - GHAS sur un dépôt public (30 min, gratuit) : activer secret scanning et push protection, tenter de pousser un faux jeton de test, activer CodeQL default setup et Dependabot alerts sur un projet avec une vieille dépendance. Résultat attendu : push bloqué, alertes Dependabot et PR de correction.
- Defender for Cloud (20 min) : connecteur GitHub ou Azure DevOps en Foundational CSPM, ouvrir DevOps security, lire les recommandations. Supprimer le connecteur à la fin.
20. Pièges d'examen#
| Situation dans la question | Réponse attendue | Pourquoi |
|---|---|---|
| Pipeline Microsoft-hosted qui doit accéder à Azure sans secret | Workload identity federation | Pas de managed identity sur un agent hébergé |
| Agent self-hosted sur une VM Azure, une seule VM | System-assigned MI (agent-assigned) | Cycle de vie lié à la VM |
| Même identité pour plusieurs ressources ou pipelines | User-assigned MI | Ressource autonome et partageable |
Service connection en erreur AADSTS7000215 |
Secret expiré : convertir en WIF | Plus de secret à faire tourner |
| Bouton Convert grisé | Connexion manuelle ou partagée entre projets | Convert = créée automatiquement, un seul projet ; annulable 7 jours |
| Avertissement « Azure DevOps issuer deprecated » | Convertir vers l'issuer Microsoft Entra | Retrait le 01/07/2027 |
| Une service connection est utilisable par tous les pipelines | Retirer l'open access, autoriser les pipelines un par un | Recommandation Defender for Cloud |
| Empêcher les PAT « Full access » | Politique Entra Restrict full-scoped PAT (Azure DevOps Administrator) | — |
| Limiter la création de PAT à quelques personnes | Restrict personal access token (PAT) creation avec allowlist | Politique d'organisation |
| Workflow qui pousse un commit : le workflow suivant ne part pas | Normal avec le GITHUB_TOKEN ; GitHub App si nécessaire | Anti-boucle |
| Automatiser sur 30 dépôts sans dépendre d'un employé | GitHub App | Pas un PAT d'utilisateur |
permissions: contents: read et le job ne peut plus commenter la PR |
Les permissions non citées passent à none | Ajouter pull-requests: write |
azure/login en OIDC échoue sans message clair |
id-token: write manquant ou subject différent |
Le subject doit correspondre exactement |
| Prestataire sur deux dépôts GitHub | Outside collaborator | Pas member de l'organisation |
| Métier qui doit approuver des releases, gratuitement | Stakeholder | Pas besoin de Basic |
| Stakeholder qui ne voit pas Repos malgré Project Administrators | L'access level l'emporte | Passer en Basic |
| Accès aux dépôts des autres projets par le jeton du build | Limit job authorization scope to current project | Moindre privilège |
| Variable group Key Vault : nouveau secret absent | Mettre à jour le variable group | Seuls les noms choisis sont mappés |
| Coffre RBAC derrière un private endpoint pour un variable group | Non supporté : access policy ou agent self-hosted | Azure DevOps n'est pas un trusted service |
Certificat .pfx pour signer dans le pipeline |
Secure file + DownloadSecureFile@1, ou certificate Key Vault |
Jamais dans le dépôt |
| Secret masqué, mais visible en base64 dans les logs | Le masquage ne couvre pas les valeurs transformées | Ne jamais afficher |
Secret dans une variable non mappée en env: |
Le script ne la voit pas | Mappage explicite obligatoire |
| Push protection activée : un vieux secret est encore là | Push protection ne voit que les nouveaux pushs ; secret scanning trouve l'historique | — |
| Secret découvert dans le code | Révoquer et remplacer, puis nettoyer | Il a pu être copié |
| PR annotations Defender sur Azure DevOps pour du C# | Non : IaC seulement | + Build validation + Defender CSPM ; sur GitHub, il faut GHAS |
| Code-to-cloud, attack path depuis le code | Defender CSPM | Pas en Foundational CSPM |
| Intégration GHAS ↔ Defender for Cloud | Connecteur GitHub + licence GHAS + Defender CSPM | GA mai 2026 |
| Dependabot sur Azure Repos | N'existe pas : GHAzDO dependency scanning | — |
| CodeQL dans un conteneur Alpine | Non supporté | musl |
| Bloquer une PR qui ajoute une dépendance GPL | Dependency review avec allow-licenses ou deny-licenses |
License scanning (les deux options s'excluent) |
21. Scénarios corrigés#
1. Contoso déploie depuis Azure Pipelines (agents Microsoft-hosted) avec une service connection à secret ; les déploiements échouent tous les ans à l'expiration. Que faire ?
Convertir la connexion en workload identity federation (bouton Convert si elle a été créée automatiquement et sert à un seul projet, sinon federated credential manuelle). Plus de secret, réversible 7 jours. Vérifier qu'elle utilise l'issuer Microsoft Entra.
2. L'équipe sécurité découvre qu'une service connection vers l'abonnement de production est utilisable par tous les pipelines du projet, y compris ceux des stagiaires. Corrections ?
Retirer Grant access permission to all pipelines, autoriser uniquement le pipeline de déploiement, donner le rôle User aux seules personnes utiles, ajouter des approvals and checks (approbation, branche
mainprotégée, Required template), et un rôle RBAC limité au resource group.
3. Un workflow GitHub Actions doit déployer sur Azure sans aucun secret Azure stocké, et seulement depuis l'environment
production qui exige une approbation. Configuration ?
App registration (ou user-assigned MI) avec une federated credential Environment =
production; dans le workflow,permissions: id-token: write,environment: production,azure/login@v2avec client, tenant et subscription IDs. Le job attend l'approbation de l'environment avant d'obtenir le jeton.
4. Un bot doit ouvrir des PR dans 40 dépôts de l'organisation chaque nuit. Le développeur propose son PAT classique. Mieux ?
Une GitHub App installée sur les 40 dépôts, avec seulement Contents et Pull requests en écriture ; le workflow génère un jeton d'installation court. Le PAT donne
reposur tout ce que voit le développeur et casse à son départ.
5. Un prestataire externe doit corriger du code dans deux dépôts GitHub privés pendant trois mois, sans voir le reste.
L'inviter en outside collaborator sur ces deux dépôts avec le rôle Write (ou Triage s'il ne pousse pas), sans l'ajouter à l'organisation ; retirer l'accès à la fin.
6. Vingt responsables métier doivent suivre les work items et approuver les déploiements en production, sans licence payante.
Access level Stakeholder : gratuit, sans limite, approbation des releases et déploiements, Boards partiel. Pas d'accès à Repos, ce qui n'est pas leur besoin.
7. Les secrets d'une application sont dans Key Vault, et cinq pipelines les utilisent. Le coffre est derrière un private endpoint en modèle RBAC. Le variable group lié refuse de fonctionner.
Ce cas n'est pas supporté (Azure DevOps n'est pas un trusted service). Options : passer le coffre en Vault access policy et autoriser les IP statiques Azure DevOps de la géographie, ou lire les secrets depuis un agent self-hosted dans le réseau avec
AzureKeyVault@2.
8. Un pipeline doit signer une application avec un certificat .pfx de 4 MB.
Secure file (≤ 10 MB) protégé par pipeline permissions et approbation, téléchargé avec
DownloadSecureFile@1et utilisé via$(nom.secureFilePath); le mot de passe du.pfxen secret Key Vault. Le fichier est supprimé à la fin du job.
9. Une clé d'API a été poussée hier dans un dépôt Azure Repos. Le RSSI veut éviter que cela se reproduise et savoir s'il y en a d'autres.
D'abord révoquer et remplacer la clé. Puis activer GitHub Secret Protection for Azure DevOps : push protection pour bloquer les prochains pushs, secret scanning du dépôt pour trouver les secrets déjà présents dans l'historique.
10. Une banque veut, sur Azure Repos, une analyse SAST et des dépendances à chaque PR, avec des résultats visibles dans Defender for Cloud.
GitHub Code Security for Azure DevOps : tâches
AdvancedSecurity-Codeql-Init@1,AdvancedSecurity-Dependency-Scanning@1,AdvancedSecurity-Codeql-Analyze@1dans un pipeline lancé par une branch policy Build validation ; connecteur Azure DevOps dans Defender for Cloud pour remonter les findings.
11. Les développeurs reçoivent des centaines d'alertes de vulnérabilité sur des images qui ne sont même pas déployées. Comment prioriser ?
Intégration GHAS ↔ Defender for Cloud (connecteur GitHub, licence GHAS, Defender CSPM) : les alertes reçoivent des runtime risk factors (exposition Internet, données sensibles) ; filtrer sur elles et lancer une security campaign.
12. Le build d'un projet C++ a besoin d'une chaîne de compilation précise fournie par une image Docker interne, et l'équipe veut CodeQL.
Workflow CodeQL avec
container: image:pour que toutes les étapes tournent dans l'image,permissions: security-events: write,codeql-action/init@v4, la commande de build, puisanalyze@v4. Image Debian ou Ubuntu, pas Alpine.
22. Pour aller plus loin#
- Managed DevOps Pools : agents Azure éphémères dans votre VNet, utiles pour atteindre un Key Vault privé (voir chapitre 04).
- Security configurations GitHub : appliquer GHAS et Dependabot à toutes les organisations d'une entreprise d'un coup.
- Artifact attestations et provenance de build (SLSA) sur GitHub, en complément de l'intégration Defender for Cloud.
- Conditional Access sur Azure DevOps (connexion des utilisateurs) et politique de restriction des invités.
- Azure Policy et Defender for Cloud pour la conformité de ce qui est déployé : chapitre 06 et SC-500, chapitre 10.
- Mesurer la sécurité (alertes ouvertes, délai de correction) : chapitre 01.
23. Fiche à retenir#
- Ressource Azure → managed identity (system si une ressource, user-assigned si partagée) ; CI hors d'Azure → workload identity federation (app registration ou user-assigned MI, 20 federated credentials max).
- Service connection ARM : WIF automatique recommandé ; Convert = créée automatiquement + un seul projet, réversible 7 jours ; issuer Azure DevOps retiré le 01/07/2027.
- Service connection = protected resource : rôle User, pipeline permissions (pas d'open access), approvals and checks.
- PAT Azure DevOps : scopes, ≤ 1 an, politiques d'organisation et Entra ; PAT globaux morts le 01/12/2026 ; préférer les jetons Entra.
- GITHUB_TOKEN : dépôt du workflow, fin du job,
permissions(les non citées = none), ne déclenche pas d'autre workflow. - GitHub App > fine-grained PAT > classic PAT.
- GitHub : Read, Triage, Write, Maintain, Admin ; owners = admin partout ; base permissions basses ; custom roles = Enterprise Cloud ; externe = outside collaborator.
- Azure DevOps : access level (voit) ≠ groupe (fait) ≠ protected resource (pipeline) ; Allow, Deny, Not set ; Stakeholder gratuit, approuve, pas de Repos.
- Team = groupe de sécurité + area path + iterations + team administrator.
- Variable group Key Vault : noms mappés, valeurs lues à chaque run, secrets seulement, Get + List ou Secrets User ; RBAC + private endpoint non supporté.
- GitHub OIDC :
id-token: write, issuertoken.actions.githubusercontent.com, subject exact (environment, branche, PR, tag). - Secure files : 10 MB,
DownloadSecureFile@1,$(nom.secureFilePath), supprimés en fin de job. - Fuites : pas d'écho, pas en ligne de commande,
env:explicite, pas de secrets pour les forks, masquage ≠ protection, fuite = révoquer d'abord. - Scans : secret (push), dépendances et licences (PR), code CodeQL (PR), IaC, conteneurs ; bloquer par seuil.
- Defender for Cloud : connecteur gratuit (inventaire, recommandations) ; Defender CSPM = PR annotations (ADO : IaC + Build validation ; GitHub : GHAS), code-to-cloud, intégration GHAS (GA 03/05/2026).
- GHAzDO : Secret Protection / Code Security, par committer actif, push protection après activation, tâches
AdvancedSecurity-*. - CodeQL en conteneur :
container:,security-events: write, toutes les étapes dedans, pas Alpine. - Dependabot alerts : dependency graph + Advisory Database, branche par défaut, security updates en PR, auto-triage ; dependency review bloque la PR.
Références#
Toutes lues le 21/10/2026, points incertains revérifiés le 22/10/2026 :
- Study guide for Exam AZ-400
- Managed identities for Azure resources
- Important considerations and restrictions for federated identity credentials
- Connect to Azure with an Azure Resource Manager service connection
- Troubleshoot Azure Resource Manager service connections
- Convert service connections from the Azure DevOps issuer to the Microsoft Entra issuer
- Use personal access tokens
- Manage personal access tokens using policies
- About permissions and security groups
- About access levels
- Protect resources in Azure Pipelines
- Create or add a team
- Link a variable group to secrets in Azure Key Vault
- Access a private key vault from your pipeline
- Use secure files
- Set secret variables
- Use GitHub Actions to connect to Azure (OpenID Connect)
- Configure GitHub Advanced Security for Azure DevOps
- Overview of Microsoft Defender for Cloud DevOps security
- Support and prerequisites for DevOps security
- Configure the Microsoft Security DevOps Azure DevOps extension
- What is GitHub Advanced Security integration with Microsoft Defender for Cloud?
- Deploy GitHub Advanced Security integration
- What's new in Defender for Cloud (mai 2026)
- GitHub Docs : Automatic token authentication (GITHUB_TOKEN)
- GitHub Docs : Deciding when to build a GitHub App
- GitHub : actions/create-github-app-token
- GitHub Docs : Roles in an organization
- GitHub Docs : Adding outside collaborators to repositories in your organization
- GitHub Docs : Repository roles for an organization
- GitHub Docs : About GitHub Advanced Security
- GitHub Docs : Running CodeQL code scanning in a container
- GitHub Docs : About Dependabot alerts
- GitHub Docs : About dependency review
- GitHub : actions/dependency-review-action