Sophie relit tous les scripts écrits depuis le début de la formation : les mots de passe temporaires en dur du TP de la section 5, le "Nordika2026!" de la section 6, les clés API en variable d’environnement de la section 9. « On a pris de bonnes habitudes au fil de la formation, mais une variable d’environnement reste visible en clair pour quiconque a accès au poste. Il est temps de faire les choses proprement, une bonne fois pour toutes. »
Pourquoi une variable d’environnement ne suffit pas
Le réflexe pris depuis la section 9 ($env:NORDIKA_API_KEY) est déjà une nette amélioration par rapport à un secret codé en dur, mais reste limité : n’importe quel processus tournant sous le même compte utilisateur peut lire cette variable, elle apparaît en clair dans certains outils de diagnostic système, et elle ne bénéficie d’aucun chiffrement au repos. SecretManagement répond à ces trois limites.
Installer SecretManagement et un coffre local
SecretManagement est un module-cadre officiel Microsoft, qui s’appuie sur un second module fournissant le stockage réel des secrets (le vault) :
Install-Module -Name Microsoft.PowerShell.SecretManagement -Scope CurrentUser
Install-Module -Name Microsoft.PowerShell.SecretStore -Scope CurrentUserSecretStore est le coffre local officiel Microsoft, chiffré, protégé par un mot de passe maître. D’autres vaults existent (Azure Key Vault, notamment, pour un stockage centralisé en entreprise plutôt que local à chaque poste) et suivent exactement la même syntaxe SecretManagement, une fois enregistrés.
Enregistrer le coffre
Register-SecretVault -Name "NordikaVault" -ModuleName Microsoft.PowerShell.SecretStore -DefaultVaultStocker un secret
Set-Secret -Name "ApiTicketingNordika" -Secret "a1b2c3d4-nordika-secret"Pour un mot de passe destiné à un compte (par exemple le compte de service svc-supervision évoqué en section 8), on peut aussi stocker un objet PSCredential complet, identifiant et mot de passe ensemble :
$credential = Get-Credential -UserName "NORDIKA\svc-supervision"
Set-Secret -Name "CompteServiceSupervision" -SecretValue $credentialRécupérer un secret dans un script
$cleApi = Get-Secret -Name "ApiTicketingNordika" -AsPlainText
$headers = @{ "X-API-Key" = $cleApi }
Invoke-RestMethod -Uri "https://api.nordika-ticketing.local/tickets" -Headers $headers-AsPlainText renvoie le secret en texte brut, nécessaire ici pour l’insérer dans un en-tête HTTP. Sans ce paramètre, Get-Secret renvoie un objet SecureString, plus sûr à manipuler tant qu’on n’a pas besoin de la valeur en clair.
Le cas des scripts non interactifs (planifiés, CI/CD)
Un coffre SecretStore protégé par mot de passe pose une question légitime : comment un script planifié (section 8), exécuté sans utilisateur derrière l’écran, peut-il déverrouiller le coffre tout seul ?
$motDePasseCoffre = ConvertTo-SecureString "MotDePasseDuCoffre" -AsPlainText -Force
Unlock-SecretStore -Password $motDePasseCoffrePoint de vigilance important : cette approche déplace simplement le problème — il faut bien stocker ce mot de passe de déverrouillage quelque part. En environnement de production réel, on configure généralement
SecretStoreavec une politique d’authentification adaptée au contexte non interactif (Set-SecretStoreConfiguration -Authentication None, à réserver aux comptes de service dont l’accès au poste est déjà strictement contrôlé), ou on privilégie carrément un vault centralisé comme Azure Key Vault avec une authentification par identité managée, qui élimine complètement le besoin d’un mot de passe local à gérer.
Retour d’expérience terrain : la question du secret qui déverrouille le coffre à secrets (« qui garde la clé du coffre-fort ? ») revient systématiquement dès qu’on aborde ce sujet en formation. Il n’existe pas de solution magique éliminant totalement ce problème — seulement des approches qui déplacent la confiance vers un mécanisme déjà sécurisé par ailleurs : l’identité de la machine elle-même (identité managée Azure), ou un compte de service dont l’accès physique et réseau est déjà strictement encadré.
Lister et supprimer des secrets
powershell
Get-SecretInfo
Remove-Secret -Name "ApiTicketingNordika"Un exemple concret Nordika : le script d’API sécurisé, version finale
En reprenant le script de la leçon 9.2, débarrassé cette fois de toute variable d’environnement au profit du coffre :
powershell
$cleApi = Get-Secret -Name "ApiTicketingNordika" -AsPlainText
try {
$headers = @{ "X-API-Key" = $cleApi }
$ticketsOuverts = Invoke-RestMethod -Uri "https://api.nordika-ticketing.local/tickets?statut=ouvert" -Headers $headers
Write-Output "$($ticketsOuverts.Count) ticket(s) ouvert(s)"
} catch {
Write-Warning "Erreur lors de l'appel à l'API de ticketing : $($_.Exception.Message)"
}Le script ne contient plus aucune trace du secret lui-même, ni en dur, ni même sous forme de nom de variable d’environnement visible dans le code — seule une référence ("ApiTicketingNordika") y apparaît, sans valeur exploitable en soi.
Source officielle : la documentation Microsoft
Microsoft.PowerShell.SecretManagementdétaille l’ensemble des vaults compatibles (SecretStore, Azure Key Vault, HashiCorp Vault via des modules tiers), etabout_SecretStorecouvre en détail la configuration de l’authentification pour les contextes non interactifs.
Retenez le principe qui referme la boucle de toute la sécurité vue dans cette formation, de la section 6 à aujourd’hui : le moindre privilège limite ce qu’un script peut faire, la signature garantit qu’il n’a pas été altéré, et
SecretManagementgarantit qu’aucun secret n’apparaît jamais en clair dans le code lui-même. Trois protections indépendantes, dont aucune ne remplace les deux autres.
Dans la prochaine leçon, on termine cette section sécurité avec le logging et le transcript — pour savoir précisément ce qu’un script a réellement fait, et quand.