En direct
SécuritéCybersécurité : des dispositifs publics gratuits pour vous accompagner - TV83· il y a 4 heuresSécuritéPlusieurs plateformes Microsoft ont rencontré des problèmes, mais la société a nié la possibilité d'une cyberattaque. - Vietnam.vn· il y a 4 heuresSécuritéCrise dans les aéroports | Vols suspendus: la cyberattaque exclue pour l'instant, l'IA en cause? - 98.5 Montréal· il y a 3 heuresSécuritéLa Maison Blanche veut renforcer la cybersécurité face à l’IA - Brief IA· il y a 3 heuresSécuritéRenforcer les défenses en matière de cybersécurité à l'ère des menaces liées à l'IA. - Vietnam.vn· il y a 3 heuresSécuritéSuspension des vols aux États-Unis : pas de cyberattaque ni de lien avec la panne de Microsoft (ministre américain) - TradingView· il y a 3 heuresSécuritéCyberattaque iranienne : comment riposter - Libre Journal· il y a 2 heuresSécuritéMicrosoft, perturbations dans le monde entier : l’entreprise exclut toute cyberattaque - LaPresse News· il y a 2 heuresSécuritéPanne mondiale Microsoft: la firme présente ses excuses et écarte la piste d'une cyberattaque - RFI· il y a 3 heuresSécuritéEntre Bièvre et Rhône : les serveurs de l’intercommunalité pillés par des hackers après une cyberattaque - Cyberattaque.org· il y a 4 heuresSécuritéProjet de loi résilience : comment la France veut rattraper son retard en cybersécurité - France 24· il y a 4 heuresSécuritéGrand Est Automobiles : plus de 2 500 fiches clients diffusées avec leurs plaques d’immatriculation et adresses - Cyberattaque.org· il y a 4 heuresSécuritéPanne mondiale chez Microsoft : « Un problème technique et non pas une cyberattaque » - Le Soir· il y a 5 heuresSécuritéCyberattaque contre Entre Bièvre et Rhône, les données de milliers d'habitants divulguées - FrenchBreaches· il y a 5 heuresSécuritéCybersécurité : des dispositifs publics gratuits pour vous accompagner - TV83· il y a 4 heuresSécuritéPlusieurs plateformes Microsoft ont rencontré des problèmes, mais la société a nié la possibilité d'une cyberattaque. - Vietnam.vn· il y a 4 heuresSécuritéCrise dans les aéroports | Vols suspendus: la cyberattaque exclue pour l'instant, l'IA en cause? - 98.5 Montréal· il y a 3 heuresSécuritéLa Maison Blanche veut renforcer la cybersécurité face à l’IA - Brief IA· il y a 3 heuresSécuritéRenforcer les défenses en matière de cybersécurité à l'ère des menaces liées à l'IA. - Vietnam.vn· il y a 3 heuresSécuritéSuspension des vols aux États-Unis : pas de cyberattaque ni de lien avec la panne de Microsoft (ministre américain) - TradingView· il y a 3 heuresSécuritéCyberattaque iranienne : comment riposter - Libre Journal· il y a 2 heuresSécuritéMicrosoft, perturbations dans le monde entier : l’entreprise exclut toute cyberattaque - LaPresse News· il y a 2 heuresSécuritéPanne mondiale Microsoft: la firme présente ses excuses et écarte la piste d'une cyberattaque - RFI· il y a 3 heuresSécuritéEntre Bièvre et Rhône : les serveurs de l’intercommunalité pillés par des hackers après une cyberattaque - Cyberattaque.org· il y a 4 heuresSécuritéProjet de loi résilience : comment la France veut rattraper son retard en cybersécurité - France 24· il y a 4 heuresSécuritéGrand Est Automobiles : plus de 2 500 fiches clients diffusées avec leurs plaques d’immatriculation et adresses - Cyberattaque.org· il y a 4 heuresSécuritéPanne mondiale chez Microsoft : « Un problème technique et non pas une cyberattaque » - Le Soir· il y a 5 heuresSécuritéCyberattaque contre Entre Bièvre et Rhône, les données de milliers d'habitants divulguées - FrenchBreaches· il y a 5 heures
Guides techniques Veille Cyber & IA • PME Québec

Azure et Entra depuis un conteneur Docker PowerShell

Executer des scripts Microsoft Graph depuis un conteneur Docker PowerShell sous Linux, en s'authentifiant par Service Principal sans aucune interaction utilisateur.

Azure et Entra depuis un conteneur Docker PowerShell
PROTECTION FLUX IA ACTIF WEITSM // GUIDES TECHNIQUES

Points clés à retenir (TL;DR)

Synthèse exécutive
  • On authentifie PowerShell au Microsoft Graph via un Service Principal (app Entra) avec un secret ou un certificat, sans jamais ouvrir de navigateur.
  • Le conteneur Docker Linux embarque PowerShell 7+ et les modules Microsoft.Graph ; les secrets sont injectes par variables d'environnement et fichier monte, jamais codes en dur.
  • Le compte applicatif recoit uniquement des permissions Application en lecture seule (Directory.Read.All, Reports.Read.All, etc.), selon le principe de moindre privilege.
  • L'execution est 100 % batch : ideale pour les taches planifiees (cron), les audits recurrents et les pipelines CI/CD.
  • La sortie est horodatee (CSV + JSON) pour la tracabilite et la revue.
Illustration : gérer Azure et Entra depuis un conteneur Docker isolé, relié au cloud et à l identité
Schéma animé : gérer Azure et Entra depuis un conteneur — conteneur, authentification, connexion, exécution, jetable

Le probleme qu’on resout

Les administrateurs qui gerent un locataire Microsoft 365 / Entra ID veulent souvent automatiser des audits ou des taches recurrentes depuis un hote Linux : serveur d’administration, machine de CI, ou poste de travail d’ingenierie sans Windows. La demarche intuitive — Connect-MgGraph en mode interactif — echoue dans ce contexte : elle declenche un flux de code d’appareil (device code) ou l’ouverture d’un navigateur, ce qui est incompatible avec une execution non surveillee dans un conteneur.

D’autres pieges apparaissent rapidement : installer le SDK Microsoft.Graph alourdit l’image, les versions de modules divergent entre postes, et stocker un secret dans le script ou dans l’image Docker constitue une faute de securite majeure. L’objectif est donc d’obtenir une authentification fiable, reproductible et sans interaction, tout en gardant les credentiels hors de l’image.

Comment ca marche

La cle est l’authentification par identite d’application (OAuth 2.0 client credentials). On enregistre une application dans Entra ID ; cette application obtient une identite (le Service Principal) et des permissions d’application (et non deleguees) accordees par un administrateur via le consentement administrateur. Le conteneur presente ensuite l’AppId (client ID), l’ID de locataire (tenant ID) et un secret (ou idealement un certificat) pour obtenir un jeton d’acces au Microsoft Graph.

Comme il n’y a pas d’utilisateur, aucun flux interactif n’est necessaire. Le conteneur reste immuable : l’image contient PowerShell et les modules, mais les secrets arrivent au moment de l’execution par variables d’environnement et par un fichier monte en lecture seule. On isole ainsi le « code » (l’image, versionnee) de la « configuration sensible » (les credentiels, geres en dehors).

Prerequis

  • Un hote Linux avec Docker installe (moteur recent).
  • Une image PowerShell incluant pwsh 7+ et les modules Microsoft.Graph >= 2.x (ou la possibilite d’installer ces modules dans un Dockerfile).
  • Un compte Entra ID avec les droits pour creer une application et accorder le consentement administrateur (role Administrateur d’application ou Administrateur general).
  • Les permissions d’application en lecture seule necessaires, par exemple : Directory.Read.All, User.Read.All, Application.Read.All, Policy.Read.All, Reports.Read.All, RoleManagement.Read.Directory, IdentityRiskEvent.Read.All (cette derniere exige Entra ID P1/P2).
  • Un emplacement pour stocker le secret hors de l’image (fichier local a droits restreints, ou mieux un coffre de secrets).

Procedure

  1. Enregistrer l’application dans le portail Entra ID (Inscriptions d’applications > Nouvelle inscription). Notez l’Application (client) ID et le Directory (tenant) ID.
  2. Ajouter les permissions d’application sous « Autorisations de l’API » > Microsoft Graph > Autorisations d’application, puis cliquer sur Accorder le consentement administrateur.
  3. Creer un secret client (Certificats et secrets > Nouveau secret client). Copiez la valeur immediatement ; elle ne sera plus affichee. En production, preferez un certificat.
  4. Stocker le secret dans un fichier sur l’hote avec des droits restreints (chmod 600), par exemple /opt/graph/secret.txt. Ne le mettez jamais dans l’image.
  5. Preparer l’image contenant pwsh et les modules Microsoft Graph requis (voir Dockerfile ci-dessous).
  6. Lancer le conteneur en injectant les trois variables d’environnement et en montant le fichier de secret en lecture seule.
  7. Executer le script qui se connecte au Graph et produit la sortie horodatee.

Le script

Dockerfile minimal pour une image reutilisable :

# Dockerfile - image PowerShell + Microsoft Graph (lecture seule)
FROM mcr.microsoft.com/powershell:latest

# Installation des modules Graph necessaires (pinner une version en prod)
RUN pwsh -NoProfile -Command \
    "Install-Module Microsoft.Graph.Authentication,Microsoft.Graph.Users,\
     Microsoft.Graph.Identity.DirectoryManagement,Microsoft.Graph.Identity.SignIns,\
     Microsoft.Graph.Applications,Microsoft.Graph.Reports \
     -Scope AllUsers -Force -AcceptLicense"

WORKDIR /scripts

Script PowerShell d’authentification et de verification (valeurs generiques) :

#!/usr/bin/env pwsh
<#
.SYNOPSIS
    Connexion non interactive au Microsoft Graph via Service Principal,
    destinee a une execution en conteneur Docker sous Linux.
.DESCRIPTION
    Les credentiels sont lus depuis l'environnement :
      GRAPH_CLIENT_ID   : Application (client) ID
      GRAPH_TENANT_ID   : Directory (tenant) ID
      GRAPH_SECRET_FILE : chemin du fichier contenant le secret client
    Aucune interaction : adapte aux taches planifiees et pipelines.
#>
[CmdletBinding()]
param(
    [string]$OutputRoot = '/scripts/output'
)

$ErrorActionPreference = 'Stop'
$ProgressPreference    = 'SilentlyContinue'

# --- Modules requis (deja presents dans l'image) ---
foreach ($m in @(
    'Microsoft.Graph.Authentication',
    'Microsoft.Graph.Users',
    'Microsoft.Graph.Identity.DirectoryManagement'
)) { Import-Module $m -ErrorAction Stop }

# --- Lecture des credentiels depuis l'environnement ---
$clientId   = $env:GRAPH_CLIENT_ID
$tenantId   = $env:GRAPH_TENANT_ID
$secretFile = $env:GRAPH_SECRET_FILE

if (-not $clientId -or -not $tenantId -or -not $secretFile -or -not (Test-Path $secretFile)) {
    throw "Variables GRAPH_CLIENT_ID / GRAPH_TENANT_ID / GRAPH_SECRET_FILE manquantes ou secret introuvable."
}

# --- Construction du credential applicatif ---
$secStr = (Get-Content $secretFile -Raw).Trim() | ConvertTo-SecureString -AsPlainText -Force
$cred   = New-Object System.Management.Automation.PSCredential($clientId, $secStr)

# --- Connexion non interactive au Graph ---
Write-Host "Connexion au Microsoft Graph (Service Principal)..."
Connect-MgGraph -TenantId $tenantId -ClientSecretCredential $cred -NoWelcome

$ctx = Get-MgContext
if (-not $ctx) { throw "Echec de connexion : aucun contexte Graph." }
Write-Host "Connecte au locataire : $($ctx.TenantId)"
Write-Host "AppId utilise         : $($ctx.ClientId)"
Write-Host "Scopes accordes       : $($ctx.Scopes -join ', ')"

# --- Verification simple : recuperer quelques utilisateurs ---
if (-not (Test-Path $OutputRoot)) {
    New-Item -Path $OutputRoot -ItemType Directory -Force | Out-Null
}
$stamp = Get-Date -Format 'yyyyMMdd-HHmm'
$csv   = Join-Path $OutputRoot "graph-check-$stamp.csv"

Get-MgUser -Top 20 -Property UserPrincipalName,DisplayName,AccountEnabled |
    Select-Object UserPrincipalName, DisplayName, AccountEnabled |
    Export-Csv -Path $csv -NoTypeInformation -Encoding UTF8

Write-Host "Resultat ecrit : $csv"

# --- Deconnexion propre ---
Disconnect-MgGraph | Out-Null
Write-Host "Deconnecte."

Lancement du conteneur avec injection des credentiels :

# Le secret reste sur l'hote, monte en lecture seule dans le conteneur
docker run --rm \
  -e GRAPH_CLIENT_ID="00000000-0000-0000-0000-000000000000" \
  -e GRAPH_TENANT_ID="11111111-1111-1111-1111-111111111111" \
  -e GRAPH_SECRET_FILE="/run/secret.txt" \
  -v /opt/graph/secret.txt:/run/secret.txt:ro \
  -v /opt/graph/output:/scripts/output \
  graph-pwsh:latest \
  pwsh /scripts/Connect-Graph.ps1

Planification via cron sur l’hote (execution quotidienne a 02h15) :

# crontab -e  (sur l'hote Linux)
15 2 * * * docker run --rm \
  -e GRAPH_CLIENT_ID="00000000-0000-0000-0000-000000000000" \
  -e GRAPH_TENANT_ID="11111111-1111-1111-1111-111111111111" \
  -e GRAPH_SECRET_FILE="/run/secret.txt" \
  -v /opt/graph/secret.txt:/run/secret.txt:ro \
  -v /opt/graph/output:/scripts/output \
  graph-pwsh:latest \
  pwsh /scripts/Connect-Graph.ps1 >> /var/log/graph-audit.log 2>&1

Validation

La reussite se verifie en plusieurs points :

  • Le script affiche le locataire connecte, l’AppId et la liste des scopes accordes ; les scopes doivent correspondre aux permissions consenties.
  • Le fichier CSV horodate est cree dans le volume de sortie et contient des lignes d’utilisateurs reels.
  • En interactif, on peut confirmer le contexte avec Get-MgContext :
# Test rapide en ouvrant un shell dans le conteneur
docker run --rm -it \
  -e GRAPH_CLIENT_ID="00000000-0000-0000-0000-000000000000" \
  -e GRAPH_TENANT_ID="11111111-1111-1111-1111-111111111111" \
  -e GRAPH_SECRET_FILE="/run/secret.txt" \
  -v /opt/graph/secret.txt:/run/secret.txt:ro \
  graph-pwsh:latest pwsh

# Puis dans pwsh :
# $s = (Get-Content $env:GRAPH_SECRET_FILE -Raw).Trim() | ConvertTo-SecureString -AsPlainText -Force
# $c = New-Object System.Management.Automation.PSCredential($env:GRAPH_CLIENT_ID,$s)
# Connect-MgGraph -TenantId $env:GRAPH_TENANT_ID -ClientSecretCredential $c -NoWelcome
# Get-MgContext | Format-List

Plan de retour (rollback)

Cette operation est en lecture seule cote locataire : elle ne modifie aucune ressource Entra, donc il n’y a rien a defaire du cote des objets interroges. Le rollback concerne l’infrastructure et les credentiels :

  • Pour annuler la planification : retirer l’entree crontab correspondante et relancer crontab -l pour confirmer.
  • Pour revoquer l’acces immediatement : supprimer le secret client de l’application dans Entra ID (Certificats et secrets), ce qui invalide instantanement le jeton.
  • Pour retirer completement l’automatisation : desactiver ou supprimer l’inscription d’application dans Entra ID.
  • Conservez l’ancien secret jusqu’a validation du nouveau en cas de rotation, puis supprimez-le.

Depannage

Symptome Cause probable Solution
Le script tente d’ouvrir un navigateur ou affiche un code d’appareil Appel a Connect-MgGraph sans -ClientSecretCredential (mode interactif) Toujours fournir le credential applicatif ; verifier que les 3 variables d’environnement sont bien passees.
Erreur « secret introuvable » Fichier non monte ou chemin errone Verifier le -v et que GRAPH_SECRET_FILE pointe sur le chemin interne au conteneur.
AADSTS7000215 (invalid client secret) Secret expire, espaces parasites, ou mauvais AppId Regenerer le secret ; .Trim() la valeur ; verifier l’AppId.
Authorization_RequestDenied / Insufficient privileges Permission non accordee ou consentement admin manquant Ajouter la permission d’application et cliquer sur « Accorder le consentement administrateur ».
Module Microsoft.Graph introuvable Modules absents de l’image Les installer dans le Dockerfile ou reconstruire l’image.
Rapports MFA/risque vides ou en erreur Licence insuffisante (P1/P2) ou scope manquant Ajouter Reports.Read.All / IdentityRiskEvent.Read.All et verifier la licence.

Securite, changement et bonnes pratiques

Secrets : ne jamais inclure de secret dans l’image Docker ni dans le script. Monter le fichier en lecture seule (:ro) avec des droits 600, ou utiliser un coffre de secrets (Docker secrets, un gestionnaire externe). Mettre en place une rotation reguliere, voire migrer vers une authentification par certificat.

Moindre privilege : n’accordez que des permissions d’application en lecture seule et strictement necessaires au cas d’usage. Evitez toute permission en ecriture tant qu’une tache ne l’exige pas, et documentez chaque scope.

Tracabilite : conservez les sorties horodatees et les journaux d’execution ; ils servent de preuve d’audit et facilitent le diagnostic.

Cadrage ITIL : la creation de l’inscription d’application et l’octroi de permissions constituent un changement standard a normal selon votre organisation. Documentez la demande de changement, planifiez-la hors des heures critiques (fenetre de maintenance), et soumettez-la au CAB si l’octroi de permissions au niveau du locataire l’exige dans votre politique. Rattachez les executions recurrentes a la gestion des operations, et toute anomalie detectee a la gestion des incidents ou des problemes.

A retenir

Authentifier PowerShell au Microsoft Graph depuis un conteneur Docker Linux repose sur un principe simple : un Service Principal en lecture seule, des credentiels injectes a l’execution et jamais integres a l’image, et une connexion non interactive adaptee au batch. Ce patron est reproductible pour l’audit, la supervision et les pipelines CI/CD, tout en respectant le moindre privilege.

Commencez par un cas d’usage minimal en lecture seule, validez la connexion et la sortie, puis industrialisez via une image versionnee et une planification. Documentez vos scopes, faites tourner vos secrets et gardez la configuration sensible hors du code.

Accompagnement Cybersécurité & ITSM Québec

Besoin d'aide pour sécuriser votre PME ? Parlez à WeITSM

Audit de vos assistants d'IA (Copilot, ChatGPT Enterprise, agents CRM), mise en conformité Loi 25 et configuration des contrôles de moindre privilège en 48 heures.

Scroll to Top