Le « même PC » n'est pas le même environnement d'exécution — La frontière utilisateur qui sépare AppData, HKCU, DPAPI et les informations d'identification

· Mis à jour le: · · Windows, DPAPI, Registre, AppData, Informations d'identification, Planificateur de tâches

Historique des révisions (première version, publiée le 28 Aug 2026)
Première publication

L’application lit son fichier de configuration lorsqu’elle est lancée depuis l’Explorateur de fichiers, mais le Planificateur de tâches la signale « introuvable ». Transformez-la en service et elle ne peut plus déchiffrer le mot de passe enregistré. Le navigateur de votre poste est connecté, mais en CI il retombe sur l’écran de connexion.

Face à ce type de problème, vérifiez sous qui le programme s’exécute, et comment, avant de regarder le code. Les fichiers et les paramètres qui existent sur le même PC ne peuvent pas forcément être utilisés de la même façon depuis un autre utilisateur d’exécution.

La question à laquelle cet article répond est pourquoi une application casse alors que rien n’a changé dans le code et qu’elle a seulement été transformée en tâche planifiée, en service ou en travail de CI. Si vous voulez partir du symptôme, allez à la section correspondante dans le tableau suivant.

Symptôme Quoi comparer en premier Où lire
Le fichier de configuration ou une commande est introuvable Utilisateur d’exécution, le chemin AppData réel, variables d’environnement utilisateur AppData et variables d’environnement
Une valeur de registre que vous êtes sûr d’avoir écrite manque La ruche utilisateur vers laquelle HKCU pointe HKCU
Le fichier peut être lu, mais le secret ne peut pas être déchiffré L’étendue DPAPI et le propriétaire de la clé maître DPAPI
L’état de connexion du navigateur n’est pas repris Utilisateur d’exécution, profil, la clé protégée par DPAPI Profils de navigateur
Les informations d’identification ou certificats enregistrés ne peuvent pas être utilisés Le coffre et le magasin de certificats du compte d’exécution, le type d’ouverture de session de la tâche Informations d’identification et certificats
Le lecteur Z: disparaît en exécution en tant qu’administrateur Le jeton et la session d’ouverture de session avant et après l’élévation Élévation UAC
Vous voulez une inspection complète avant une migration Les dépendances et la mise en place pour chaque forme d’exécution Liste de contrôle par forme d’exécution, Procédure d’investigation

Hypothèses de cet article

Élément Contenu
Lecteurs visés Les développeurs qui transforment des applications métier en services, tâches planifiées ou travaux de CI, et les équipes d’exploitation qui investiguent les problèmes du type « ça marche sur ma machine »
Environnement préalable Windows 10/11. Le code de vérification s’exécute sous PowerShell 5.1 ou version ultérieure
Difficulté Intermédiaire

1. D’abord la conclusion

L’unité de base qui partitionne un environnement d’exécution Windows n’est pas le PC mais le jeton d’accès et le SID, c’est-à-dire « sous qui le processus s’exécute ». AppData, HKCU, les clés DPAPI, les profils de navigateur et les informations d’identification appartiennent à l’environnement de cet utilisateur.

Les paramètres et l’état de connexion que vous avez préparés sous votre propre ouverture de session interactive ne sont pas repris automatiquement vers SYSTEM ni vers un autre compte de service. Les zones pour les données à l’échelle de la machine sont ProgramData et HKLM, et les partager par ce biais exige encore de concevoir les droits d’accès.

Deux mondes dans le même PCLe même PC ne partage que HKLM et ProgramData, tandis que le monde de votre SID et le monde d'un autre SID ont chacun leur propre AppData, leur propre ruche de registre et leurs propres clés DPAPI, invisibles l'un à l'autre de part et d'autre de la frontière utilisateurFrontière utilisateur : invisibles l'un à l'autreMême PCPartagé : HKLM et ProgramDataLe monde de votre SIDLe monde d'un autre SID (SYSTEM etc.)AppData, HKCU, clés DPAPIAutre AppData, autre ruche, autres clés

Figure 1 : Sur le même PC, un autre utilisateur d’exécution signifie un autre AppData, un autre registre et d’autres clés.

Cela dit, le même SID ne garantit pas non plus le même environnement. Vérifiez aussi le type d’ouverture de session de la tâche, le chargement du profil IIS, et la différence de session d’ouverture de session que crée une élévation UAC. S’élever au sein du même compte ne transforme pas HKCU ni le coffre en ceux d’un autre utilisateur ; l’important est de raisonner séparément sur quelles frontières changent.

Le reste de l’article procède dans cet ordre : l’utilisateur d’exécution comme prémisse (chapitre 2), les cinq frontières (chapitres 3 à 7), le contrôle par forme d’exécution (chapitre 8), et la conception et l’investigation (chapitre 9).

Dans le diagramme, un trait continu marque une relation qui vaut toujours et un trait pointillé une relation conditionnelle (les conditions figurent dans l’explication de chaque relation sur la page de détail). La liste complète des relations (33 au total, avec preuve et niveau de certitude) et les définitions des concepts principaux sont rassemblées sur la page de détail de la carte des connaissances (en japonais). Données : JSON-LD / Turtle

2. Prémisse : « Sous qui cela s’exécute » décide de tout

2.1 Vérifier le SID et le jeton, pas le nom d’utilisateur

L’identifiant que Windows utilise pour reconnaître un utilisateur n’est pas le nom d’utilisateur mais le SID (identificateur de sécurité). Un processus détient un jeton d’accès, et le jeton contient le SID de l’utilisateur d’exécution. Ce principal d’exécution est le point de départ dès que vous raisonnez sur les contrôles d’ACL de fichiers, le registre physique derrière un alias, ou les clés de chiffrement.

Utilisez whoami /user pour la première vérification. Confirmez le résultat dans l’environnement d’exécution où le problème se produit, pas dans votre propre terminal.

> whoami /user

INFORMATIONS SUR L'UTILISATEUR
----------------

Nom d'utilisateur SID
=============== =============================================
desktop\you     S-1-5-21-3623811015-3361044348-30300820-1001

C:\Users\you est la forme sur disque du profil utilisateur lié à ce SID. Un profil se compose d’un ensemble de dossiers tels qu’AppData et de la ruche de registre utilisateur NTUSER.DAT. Parce qu’il est copié depuis le profil par défaut à la première ouverture de session, le profil d’un autre utilisateur part d’un état initial distinct de l’environnement que vous avez configuré.1

Du chemin de lancement au profilQu'il soit lancé par double-clic, Planificateur de tâches, ou un service ou IIS, le processus détient le SID dans son jeton d'accès, et l'ensemble de données de profil utilisateur lié à ce SID devient son environnement d'exécutionDouble-clicJeton du processus (SID)Planificateur de tâchesService ou IISEnsemble de profil lié au SIDUn SID différent signifie un profil différent, à l'état initial

Figure 2 : Le chemin par lequel un processus est lancé décide du profil de quel SID il porte pendant qu’il s’exécute.

2.2 Chaque compte de service a un environnement qui lui est propre

Windows a des comptes intégrés qui s’exécutent sans qu’un humain ouvre de session. Chacun d’eux a un environnement d’exécution indépendant.2

Compte SID Où pointent son profil et son registre
SYSTEM (LocalSystem) S-1-5-18 Profil sous C:\Windows\System32\config\systemprofile. HKCU est associé à l’utilisateur par défaut3
LocalService S-1-5-19 Sous C:\Windows\ServiceProfiles\LocalService. A sa propre sous-clé sous HKEY_USERS4
NetworkService S-1-5-20 Sous C:\Windows\ServiceProfiles\NetworkService. Comme LocalService, a son propre profil et sa propre ruche4
IIS AppPool\<nom> S-1-5-82-… Une identité propre au pool. Le profil n’est pas chargé par défaut5

La différence entre les chemins de lancement d’un double-clic, du Planificateur de tâches, d’un service et d’IIS devient une différence de l’environnement de qui est utilisé. Ne supposez pas que les paramètres, les clés et les informations d’identification que vous avez préparés sous votre ouverture de session interactive existent aussi à cette destination d’exécution.

2.3 Trois conditions à vérifier après « le même utilisateur »

Condition à vérifier Exemple d’endroit où la différence se voit
Type d’ouverture de session Avec une ouverture de session S4U d’une tâche, le mot de passe n’est pas stocké, et le réseau et EFS ne sont pas accessibles6
Chargement du profil Dans IIS, loadUserProfile décide si AppData et la ruche utilisateur sont disponibles7
Session d’ouverture de session et élévation Même avec le même SID, un processus élevé peut ne pas voir les lecteurs réseau mappés89

Ne vous arrêtez pas à la vérification du SID ; servez-vous de ces trois points pour trier ce qui diffère même avec le même compte. Les tâches sont détaillées au chapitre 8, IIS aux chapitres 4 et 5, et l’élévation au chapitre 7.

3. Frontière 1 : AppData — La même variable d’environnement pointe vers un autre endroit

Le symptôme typique est que le fichier de configuration cesse d’être trouvé dès que l’application devient une tâche planifiée. La résolution de chemin n’a pas échoué ; le chemin peut s’être résolu correctement vers l’emplacement d’un autre utilisateur, où le fichier n’existe pas.

3.1 Les divisions d’AppData et comment l’utilisateur d’exécution les change

AppData est un dossier sous le profil utilisateur. Ses usages se répartissent comme suit.10

Zone Usage principal
%APPDATA% (Roaming) Paramètres utilisateur qui doivent suivre le profil lorsqu’il itinère
%LOCALAPPDATA% (Local) Données et caches locaux à la machine
AppData\LocalLow Données pour les processus qui s’exécutent à un niveau d’intégrité bas

Même lorsque le même code ouvre %APPDATA%, l’emplacement auquel il se réfère change avec l’utilisateur d’exécution.

Utilisateur d’exécution Exemple d’endroit où le fichier de configuration est cherché
Utilisateur A C:\Users\a\AppData\Roaming\MyApp
SYSTEM AppData sous systemprofile

Le fichier que l’utilisateur A a enregistré n’existe pas du côté SYSTEM. Une erreur qui dit seulement que le fichier de configuration manque ne rend pas cela évident, donc pendant l’investigation regardez le chemin réellement ouvert, pas le nom de la variable d’environnement.

La façon dont %APPDATA% se résout dépend de l'utilisateurMême lorsque le même code ouvre %APPDATA%, il se résout vers un chemin sous C:\Users si l'utilisateur d'exécution est vous et sous systemprofile s'il est SYSTEM, et votre fichier de configuration n'existe pas dans ce dernierVousSYSTEMMême code : ouvrir %APPDATA%Utilisateur d'exécution ?C:\\Users\\you\\AppData\\RoamingAppData sous systemprofileLe fichier que vous y avez mis est absent

Figure 3 : Les variables d’environnement ne mentent pas, mais l’endroit où elles se résolvent dépend du jeton.

3.2 PATH diffère aussi par utilisateur

Les variables d’environnement système sont partagées par toute la machine, mais les variables d’environnement utilisateur sont par utilisateur. Lorsqu’une commande que vous avez ajoutée à votre propre PATH est introuvable depuis un service, vérifiez aussi cette différence.

Décidez de l’emplacement de stockage selon qui lit les données. Les paramètres pour cet utilisateur seul vont sous AppData ; les données partagées par tous les utilisateurs ou par des services vont sous %ProgramData%, et pour ces dernières vous concevez les ACL. Pour une façon détaillée de choisir, voir « Comment choisir où une application Windows stocke ses données locales — tableau de décision pour SQLite / JSON / Registre / Access ».

Choisir l'emplacement de stockage selon ses lecteursLes données que seul cet utilisateur lit vont dans AppData ou HKCU, les données partagées avec tous les utilisateurs ou des services vont dans ProgramData ou HKLM, et ces dernières s'accompagnent d'une conception d'ACLCet utilisateur seulementTous les utilisateurs, servicesQui lit ces données ?AppData, HKCUProgramData, HKLMReconsidérer si cela peut devenir un serviceConcevoir les droits d'écriture et les ACL

Figure 4 : « Elle ne peut plus le lire une fois devenue un service » est le résultat d’avoir sauté cette branche à la conception.

4. Frontière 2 : HKCU — « Utilisateur actuel » change avec l’appelant

Le symptôme typique est qu’un service ne trouve pas les informations de licence qu’un installateur a écrites. Même lorsque l’écriture et la lecture sont allées toutes deux vers quelque chose nommé HKCU, ce n’est pas nécessairement la même ruche physique.

4.1 HKCU est un alias de la ruche de l’utilisateur

HKEY_CURRENT_USER (HKCU) n’est pas une ruche indépendante ; c’est un alias redirigé vers un emplacement physique selon l’utilisateur appelant. Dans un processus utilisateur ordinaire, il pointe vers la clé de ce SID sous HKEY_USERS. Son contenu est le NTUSER.DAT chargé à l’ouverture de session.1

L’exception est HKCU\Software\Classes, dont l’emplacement physique est un fichier de ruche distinct, UsrClass.dat. Ce fichier se trouve sous %LOCALAPPDATA%\Microsoft\Windows.11

Le HKCU de LocalSystem est associé à l’utilisateur par défaut (HKEY_USERS\.DEFAULT). Lorsqu’un installateur s’exécutant sous un compte administrateur écrit dans HKCU et qu’un service SYSTEM lit depuis HKCU, les deux se réfèrent à des endroits différents.3

Ce qu'est vraiment l'alias HKCULorsqu'une application ouvre HKCU, il est redirigé vers votre clé SID sous HKEY_USERS dans votre processus et vers la clé de l'utilisateur par défaut dans un processus LocalSystem, donc la valeur que l'installateur a écrite n'est plus visibleVotre processusProcessus SYSTEMCode de l'app : ouvrir HKCUHKCU est un alias de la vraie cléVotre SID sous HKEY_USERSHKEY_USERS\\.DEFAULTLa valeur que vous avez écrite n'existe pas

Figure 5 : Même sous le même nom HKCU, un utilisateur différent signifie qu’une ruche différente est lue et écrite.

Placez les paramètres à l’échelle de la machine dans HKLM. Microsoft ne recommande pas d’accéder à HKCU depuis un service. Si vous devez lire les paramètres d’un utilisateur, empruntez l’identité de cet utilisateur puis utilisez RegOpenCurrentUser.12

4.2 Vérifier aussi si le profil est chargé

Au-delà du compte d’exécution, le fait que le profil soit chargé ou non peut aussi être le problème.

Les pools d’applications IIS s’exécutent sans charger de profil utilisateur par défaut. Activer loadUserProfile rend AppData et la ruche sous le profil disponibles.7 Ce paramètre influe aussi sur l’endroit où sont stockées les clés DPAPI et ASP.NET Core Data Protection du chapitre suivant.

Le paramètre de tâche « Ne pas stocker le mot de passe » se vérifie séparément, comme contrainte de type d’ouverture de session. Même avec le même utilisateur indiqué, une ouverture de session S4U ne peut pas utiliser le réseau ni EFS. Les différences concrètes entre configurations sont résumées au chapitre 8.6

5. Frontière 3 : DPAPI — Le chiffrement est verrouillé avec « la clé de l’utilisateur »

Alors qu’AppData et HKCU sont des problèmes de chercher à un autre endroit, DPAPI produit un problème où le fichier peut être lu mais son contenu ne peut pas être déchiffré. Transformer en service une application qui utilise un mot de passe enregistré et obtenir une CryptographicException en est un exemple.

5.1 Un autre propriétaire de clé maître signifie pas de déchiffrement

DPAPI (Data Protection API) est le mécanisme de chiffrement que Windows fournit aux applications. Appeler CryptProtectData ou ProtectedData.Protect de .NET permet à une application de protéger des données sans transporter une clé de chiffrement dans son propre code.13

Cela ne rend pas la clé inutile pour autant. DPAPI utilise une clé maître gérée par le système d’exploitation. Dans l’étendue CurrentUser, une clé maître par utilisateur générée aléatoirement est protégée avec une clé dérivée des informations d’identification d’ouverture de session et stockée sous le profil.14

La chaîne de clés DPAPILa clé maître utilisateur générée aléatoirement est protégée par une clé dérivée des informations d'identification d'ouverture de session, cette clé maître chiffre les secrets de l'application, et la clé maître d'un autre utilisateur ne peut pas déchiffrer le même texte chiffréProtège via une clé dérivéeChiffreNe peut pas déchiffrerInformations d'identification d'ouverture de sessionVotre clé maîtreSecret de l'app (mot de passe enregistré etc.)Clé maître d'un autre utilisateurStockée sous le profil

Figure 6 : Les données ne sont pas chiffrées directement à partir des informations d’identification ; une clé dérivée des informations d’identification protège la clé maître.

Vient ensuite un exemple minimal dans lequel l’utilisateur A chiffre des données, les place dans un emplacement partagé, et un autre utilisateur tente de les déchiffrer. Partager l’emplacement de stockage ne change pas qui peut déchiffrer sous CurrentUser.

# Dans la session de l'utilisateur A : chiffrer dans l'étendue CurrentUser et enregistrer dans un emplacement partagé
Add-Type -AssemblyName System.Security
$bytes = [Text.Encoding]::UTF8.GetBytes("secret")
$enc = [Security.Cryptography.ProtectedData]::Protect($bytes, $null, "CurrentUser")
[Convert]::ToBase64String($enc) | Set-Content C:\ProgramData\demo.bin

# En tant qu'utilisateur différent (par exemple, après être devenu SYSTEM avec PsExec), tenter de déchiffrer
$enc = [Convert]::FromBase64String((Get-Content C:\ProgramData\demo.bin))
[Security.Cryptography.ProtectedData]::Unprotect($enc, $null, "CurrentUser")
# → CryptographicException : Clé non valide pour l'utilisation dans l'état spécifié.

5.2 Choisir l’étendue d’après qui doit pouvoir déchiffrer

Étendue Unité de déchiffrement Point de conception
CurrentUser La clé maître de l’utilisateur qui a chiffré les données Ne peut plus être déchiffré une fois déplacé vers un autre compte d’exécution
LocalMachine Une clé partagée par la même machine N’importe quel processus sur la même machine peut déchiffrer, donc restreindre qui peut lire le texte chiffré avec une ACL de fichier

Un secret que lisent à la fois un service et l’utilisateur interactif doit être conçu dès le départ comme LocalMachine combiné à une ACL de fichier, ou le processus doit s’exécuter sous le compte de la personne qui a chiffré. Ne changez pas l’étendue seulement pour faire disparaître l’erreur de déchiffrement ; décidez à qui le déchiffrement est permis. Sur des machines partagées, soyez aussi conscient du risque qu’une protection au niveau machine soit trop large.15

Comment choisir l'étendue DPAPIChoisissez l'étendue CurrentUser si seul cet utilisateur doit pouvoir déchiffrer et l'étendue LocalMachine si plusieurs principaux sur le même PC le doivent, et restreignez les lecteurs de cette dernière avec une ACL de fichierCet utilisateur seulementPlusieurs principaux sur le même PCQui doit pouvoir déchiffrer ?Étendue CurrentUserÉtendue LocalMachineLe déchiffrement échoue en exécution sous un autre utilisateurRestreindre les lecteurs avec une ACL de fichier

Figure 7 : Choisissez l’étendue comme décision de conception sur qui déchiffre, pas comme « celle qui a marché par hasard ».

5.3 Un « changement » et une « réinitialisation » de mot de passe sont différents

La clé qui garde la clé maître dépend des informations d’identification d’ouverture de session. Lorsque les utilisateurs changent leur propre mot de passe, la clé maître est re-protégée avec une clé dérivée du nouveau mot de passe, et la capacité de déchiffrer est reprise.

En revanche, lorsqu’un administrateur réinitialise le mot de passe d’un compte local, le texte chiffré passé peut ne plus être déchiffrable. Même avec le même compte, il faut vérifier comment les informations d’identification ont été changées.14

5.4 Vérifier aussi où les clés sont stockées dans ASP.NET Core

Même du code qui n’appelle jamais DPAPI directement peut dépendre de cette frontière. ASP.NET Core Data Protection stocke l’anneau de clés utilisé pour protéger l’authentification par cookie et assimilé dans un emplacement qui dépend de l’environnement.16

Environnement Où vont les clés et la conséquence
Un profil utilisateur est disponible %LOCALAPPDATA%\ASP.NET\DataProtection-Keys. Sous Windows les clés sont chiffrées avec DPAPI
Aucun profil n’est disponible, et l’application est hébergée dans IIS Repli vers le registre HKLM, avec ACL pour le compte du processus de travail
Ni l’un ni l’autre Les clés deviennent des clés éphémères locales au processus. Elles sont perdues au redémarrage, et les données protégées telles que les cookies d’authentification deviennent invalides

Vérifiez loadUserProfile, setProfileEnvironment et le modèle d’hébergement comme un ensemble, et comprenez quelle configuration décide où les clés sont placées. Ce qui compte n’est pas seulement que l’application démarre, mais qu’elle puisse utiliser les mêmes clés après un redémarrage.

Le choix d’étendue et le moment d’utiliser plutôt le Gestionnaire d’informations d’identification sont traités en détail dans « Stocker les secrets des applications Windows - Éviter les configurations en clair avec DPAPI ».

6. Frontière 4 : Profils de navigateur — « Connecté » appartient à l’utilisateur

Connecté sur votre poste, et pourtant lorsque la CI lance le navigateur il est de retour à l’écran de connexion. Ce problème devient traitable une fois que vous séparez l’endroit où le profil est stocké de la clé de chiffrement.

6.1 Il y a deux frontières : emplacement de stockage et clé

Le profil d’un navigateur fondé sur Chromium tel que Chrome ou Edge se trouve par défaut dans le dossier User Data sous %LOCALAPPDATA%. L’historique, les cookies, les extensions, les mots de passe enregistrés, etc. appartiennent à l’environnement de cet utilisateur Windows.17

Les cookies et les mots de passe enregistrés sont chiffrés avec une clé de chiffrement à l’intérieur du profil, et cette clé elle-même est protégée par DPAPI. Copier le dossier vers un autre utilisateur ou une autre machine échoue donc au déchiffrement parce que la clé ne correspond pas.

Chrome récent superpose App-Bound Encryption. Le déchiffrement de la clé passe par un service qui s’exécute avec les privilèges SYSTEM, qui vérifie non seulement l’utilisateur mais aussi l’identité de l’application demanderesse.18 Cela s’applique aux navigateurs fondés sur Chromium ; la situation diffère pour des navigateurs tels que Firefox qui ont leur propre protection de profil.

Frontière Ce qui se passe à la cible d’automatisation
La frontière AppData L’utilisateur de l’agent de CI ou du service n’a pas le profil que vous utilisez d’habitude
La frontière DPAPI Même si le dossier est copié, la clé protégée ne peut pas être déchiffrée
Les deux frontières derrière l'état de connexion d'un navigateurLe profil de navigateur se trouve sous LOCALAPPDATA et appartient à la frontière 1, et la clé de chiffrement des cookies est protégée par DPAPI et appartient à la frontière 3, donc ni le profil ni la clé ne passent à un autre utilisateurProfil de navigateurStocké sous LOCALAPPDATAClé de chiffrement des cookies protégée par DPAPIL'utilisateur d'exécution de la CI reçoit un profil vide et distinctNe peut pas être emporté en copiant le dossier

Figure 8 : « Emporter l’état de connexion avec soi » est bloqué à la fois par la frontière 1 et par la frontière 3.

6.2 En automatisation, rendre explicite la façon dont l’état de connexion est créé

Selenium et Playwright se lancent par défaut avec un profil temporaire jetable. Donc même sous le même utilisateur, l’état de connexion de votre navigateur quotidien n’est pas utilisé automatiquement.

Même si vous indiquez un répertoire de profil persistant, les problèmes d’emplacement de stockage et de clé de la section précédente restent dès que vous passez à un travail de CI ou à un service sous un autre utilisateur. Le remède n’est pas de copier un profil déjà connecté mais l’un des suivants.

  • Coder les étapes de connexion d’un compte de test.
  • Utiliser le mécanisme d’état de stockage de l’outil d’automatisation pour enregistrer et restaurer explicitement les cookies et assimilé.

Qu’un autre utilisateur ne puisse pas utiliser les cookies par une simple copie n’est pas un inconvénient ; c’est aussi une frontière de sécurité. Concevez l’automatisation en partant du principe que cette frontière existe.

7. Frontière 5 : Informations d’identification et certificats — Chaque utilisateur a un coffre distinct

Les informations d’identification enregistrées avec cmdkey ne sont pas utilisées lorsque la tâche s’exécute, et l’authentification échoue. Ici aussi, vérifiez non pas « c’était enregistré sur le PC » mais « sous quel utilisateur c’était enregistré ».

7.1 Le Gestionnaire d’informations d’identification est un coffre par utilisateur d’exécution

Le Gestionnaire d’informations d’identification, que vous pouvez inspecter avec cmdkey /list, est un coffre par utilisateur.19 Les informations d’identification enregistrées sont sur disque, mais elles sont protégées par DPAPI et utilisées par les programmes qui s’exécutent en tant que cet utilisateur.20

Le coffre contient les informations d’identification enregistrées pour les serveurs de fichiers et les lecteurs réseau, les jetons Git enregistrés par git-credential-manager, les mots de passe enregistrés pour les connexions RDP, les secrets d’applications qui utilisent l’API Credential, et ainsi de suite.

Être dans le coffre de votre ouverture de session interactive ne les met pas dans le coffre du compte qui exécute le service ou la tâche. Préparez une étape de mise en place qui dépose les informations d’identification requises dans le contexte du compte d’exécution lui-même. Lorsque seul le git pull de votre poste réussit, vérifiez aussi la différence de coffres.

Cependant, une tâche configurée en S4U n’est pas corrigée par le seul dépôt d’informations d’identification. Vérifiez d’abord le type d’ouverture de session, et envisagez une configuration qui stocke le mot de passe ou un passage à un compte de service. L’ordre des étapes est exposé au chapitre 8.

Le coffre des informations d'identification est par utilisateurVotre coffre contient les informations d'identification Git, les informations d'identification enregistrées pour les serveurs de fichiers et les mots de passe RDP, mais le coffre de l'utilisateur d'exécution du service est vide tant que rien n'est déposé, et c'est cela l'erreur d'authentification réelleVotre coffreInformations d'identification GitInformations d'identification enregistrées pour les serveurs de fichiersMots de passe RDP enregistrésCoffre de l'utilisateur d'exécution du serviceVide tant que rien n'est déposé = la vraie erreur d'authentification

Figure 9 : « L’authentification marche sur ma machine » n’est que l’abréviation de « mon coffre est disponible ».

7.2 Pour les certificats, vérifier séparément le magasin et les droits de la clé privée

Magasin Frontière et usage
Cert:\CurrentUser Magasin par utilisateur. La clé privée d’un certificat client placé ici est protégée par utilisateur
Cert:\LocalMachine Magasin à l’échelle de la machine. Placez ici les certificats pour les services, et accordez au compte de service le droit de lecture par l’ACL de la clé privée

Pour un certificat utilisé par un service, la conception de base est le magasin LocalMachine conjointement avec l’ACL sur la clé privée.21 Le magasin utilisateur se trouve physiquement sous HKCU\Software\Microsoft\SystemCertificates, donc à l’intérieur de la frontière HKCU.22

Pour les détails, voir « Guide pratique du magasin de certificats Windows — Faut-il l’installer côté utilisateur ou côté ordinateur ? ».

7.3 Avec l’élévation UAC, séparer « le même compte » de « un compte différent »

Lorsqu’un utilisateur administrateur ouvre une session avec UAC activé, deux jetons liés sont créés : un jeton standard aux privilèges restreints et un jeton administrateur complet.8

Les mappages de lecteurs réseau sont par session d’ouverture de session. Z: peut être visible dans l’Explorateur de fichiers et invisible pour un outil exécuté en tant qu’administrateur.9

Comment cela s’exécute Ce qui change et ce qui ne change pas
Élévation UAC en restant sur le même compte Le SID est le même, et HKCU et le coffre d’informations d’identification restent les mêmes. Les mappages de lecteurs, qui sont par session d’ouverture de session, peuvent devenir invisibles
Élévation ou RunAs avec les informations d’identification d’un autre compte administrateur Le SID change aussi. HKCU et le coffre deviennent ceux de cet administrateur. AppData, les clés et l’état du navigateur sont aussi soumis à la frontière de l’autre utilisateur

Ne supposez pas que chaque « ça s’arrête de marcher une fois élevé » est un changement d’utilisateur ; vérifiez d’abord s’il s’agit du même compte.

La scission au sein d'un même utilisateur créée par l'élévation UACUne ouverture de session administrateur avec UAC activé crée deux jetons, un jeton standard et un jeton élevé, et un lecteur réseau mappé du côté du jeton standard n'est pas visible pour un processus qui s'exécute avec le jeton élevéSession d'ouverture de session distincteOuverture de session de l'utilisateur administrateurJeton standardJeton élevéLecteur Z: mappé iciL'outil élevé ne voit pas Z:

Figure 10 : L’élévation crée « un autre monde pour le même utilisateur ». La frontière ne concerne pas seulement le SID.

8. Liste de contrôle par forme d’exécution

8.1 Pour les tâches, regarder le type d’ouverture de session après le compte d’exécution

Dans le Planificateur de tâches, ce qui est disponible change avec le type d’ouverture de session même lorsque le même utilisateur est indiqué.6

Type d’ouverture de session Quoi vérifier
Jeton interactif (InteractiveToken) Une configuration qui s’exécute dans la session ouverte
Mot de passe stocké (Password) Une configuration qui peut utiliser des informations d’identification même hors interactif
S4U (mot de passe non stocké) Le mot de passe n’est pas stocké, et les ressources réseau et les fichiers chiffrés (EFS) ne sont pas accessibles

Lorsqu’une tâche ne peut pas utiliser des informations d’identification enregistrées, vérifiez d’abord la contrainte S4U. Ne faites pas du dépôt d’informations d’identification dans le coffre en restant en S4U votre correction. Envisagez une configuration qui stocke le mot de passe ou un passage à un compte de service, et seulement ensuite, si besoin, déposez des informations d’identification dans le coffre du compte d’exécution.

Les détails des paramètres sont traités dans « Les tâches du Planificateur de tâches qui ne s’exécutent pas ou se terminent en 0x1 — isoler la cause et concevoir une exploitation fiable ».

Le type d'ouverture de session de la tâche comme deuxième axeUne configuration d'exécution du Planificateur de tâches a un type d'ouverture de session jeton interactif, mot de passe stocké ou S4U, et avec S4U le mot de passe n'est pas stocké et le réseau et EFS ne sont pas accessiblesJeton interactifMot de passe stockéS4U (mot de passe non stocké)Configuration d'exécution de la tâcheType d'ouverture de sessionS'exécute dans la session ouverteInformations d'identification utilisables même hors interactifNe peut pas atteindre le réseau ni EFS

Figure 11 : Même avec le même utilisateur d’exécution, la façon dont la session a été ouverte change ce qui est disponible.

8.2 Le tableau d’inspection avant de changer la destination d’exécution

Forme d’exécution Principal d’exécution Frontières et symptômes à inspecter en particulier
Planificateur de tâches Le compte indiqué à l’enregistrement Frontières 1, 2, 3 et 5. Vérifier où pointent AppData et HKCU, le déchiffrement DPAPI, et le coffre. Avec S4U, le réseau et EFS ne peuvent pas être utilisés
Service Windows SYSTEM, LocalService, NetworkService, un compte de service Frontières 1 à 5. SYSTEM utilise systemprofile et le HKCU de l’utilisateur par défaut ; LocalService et NetworkService utilisent leurs propres environnements sous ServiceProfiles. Les clés, le coffre et l’état de navigateur du développeur ne sont pas repris
Pool d’applications IIS Une identité propre au pool telle que IIS AppPool\<nom> Frontières 1, 2, 3 et 5. Vérifier que le profil n’est pas chargé par défaut, où sont placées les clés Data Protection, et l’accès aux clés privées des certificats CurrentUser
RunAs / élévation UAC L’utilisateur indiqué, ou un jeton différent du même utilisateur Avec le même compte, le SID, HKCU et le coffre sont les mêmes, et les mappages de lecteurs sont affectés par la différence de session. Avec un compte différent, inspecter l’ensemble des frontières 1 à 5
Agent CI/CD L’utilisateur de service de l’agent. Souvent n’a jamais ouvert de session interactive Frontières 1 à 5. Vérifier les dépendances au profil et à l’état de connexion du navigateur, aux informations d’identification Git, aux paramètres HKCU du développeur et aux données protégées par DPAPI
RDP / serveur partagé Plusieurs sessions du même utilisateur, ou plusieurs utilisateurs Plusieurs sessions du même utilisateur partagent AppData et HKCU, donc surveiller les conflits d’écriture. Des utilisateurs différents sont séparés par les frontières 1 à 5

La dernière ligne est une mise en garde dans l’autre sens. Plusieurs sessions RDP du même utilisateur ne donnent pas à chaque session son propre AppData et HKCU indépendants. Ici le problème n’est pas qu’une chose soit invisible, mais que la même chose est partagée et écrite.

9. Lignes directrices pour la conception et le dépannage

9.1 Décider des emplacements de stockage et de la mise en place à partir du principal qui les utilise

Cible Bases de conception
Paramètres propres à l’utilisateur Les placer dans AppData ou HKCU
Données et paramètres partagés par tous les utilisateurs ou des services Les placer dans ProgramData ou HKLM, et concevoir les droits d’écriture et les ACL
Secrets Choisir l’étendue DPAPI d’après qui doit pouvoir déchiffrer. Avec LocalMachine, concevoir aussi l’ACL de fichier
Informations d’identification et certificats pour les services Inclure le dépôt dans le coffre du compte d’exécution, le placement du certificat dans le magasin de certificats LocalMachine, et le réglage de l’ACL de la clé privée dans la procédure de mise en place

Si vous prévoyez de transformer l’application en service plus tard, incluez ce principal d’exécution parmi les lecteurs dès l’étape où vous décidez où stocker. Le principe est de ne pas emporter en exploitation une dépendance à « ce qui se trouvait par hasard dans l’environnement du développeur ».

9.2 Investiguer du principal d’exécution jusqu’à l’emplacement réellement référencé

Procédure d'investigation des problèmes de frontière utilisateurConfirmer l'utilisateur d'exécution avec whoami, regarder le jeton dans Process Explorer, identifier les chemins et les clés de registre réellement lus avec Process Monitor, et si besoin reproduire depuis le monde de l'autre côté avec psexecConfirmer l'utilisateur d'exécution avec whoami /allVérifier le jeton dans Process ExplorerIdentifier les chemins et clés réels avec ProcMonReproduire depuis le monde de l'autre côté avec psexecUn chemin de profil inattendu est l'indice

Figure 12 : Confirmer l’utilisateur d’exécution, regarder les chemins et les clés de registre réels, puis reproduire en tant que principal d’exécution cible.

Étape Comment vérifier Quoi regarder
1. Confirmer l’utilisateur d’exécution Écrire whoami /all dans le journal juste après le démarrage Si le principal d’exécution de la tâche ou du service qui échoue est le même que sur votre poste
2. Vérifier le jeton Process Explorer L’utilisateur et la session du processus. S’agit-il d’un autre utilisateur, ou d’un autre contexte d’exécution du même utilisateur ?
3. Regarder l’emplacement réellement référencé Process Monitor Les chemins des fichiers ouverts et les clés de registre. Un profil autre que celui attendu apparaît-il dans PATH NOT FOUND ?
4. Reproduire en tant que principal d’exécution cible Pour SYSTEM, psexec -s -i cmd Essayer la même opération depuis un interpréteur SYSTEM et confirmer les différences avec votre propre environnement interactif

Lorsque des paramètres manquent, revenir à AppData et HKCU ; lorsque le fichier peut être lu mais pas déchiffré, à DPAPI ; lorsque seule l’authentification échoue, au coffre, aux certificats et au type d’ouverture de session. Ne jugez pas d’après le message d’erreur seul ; le raccourci est d’aligner « qui a utilisé quel emplacement, avec quelle clé ou quelles informations d’identification ».

10. Résumé

« Ça marche sur ma machine » signifie « ça marche en tant que cet utilisateur, avec ce profil, avec ces clés et ce coffre ». Même lorsque le même .exe est lancé sur le même PC, le transformer en tâche, en service ou en travail de CI doit être traité comme une migration de l’environnement d’exécution.

AppData et les variables d’environnement utilisateur se réfèrent au profil de l’utilisateur d’exécution, et HKCU pointe de même vers la ruche de cet utilisateur. L’étendue CurrentUser de DPAPI dépend de la clé maître de l’utilisateur, et l’état de connexion du navigateur et le Gestionnaire d’informations d’identification sont aussi affectés par cette frontière.

En outre, même avec le même SID, les différences de type d’ouverture de session, de chargement de profil et de session créée par l’élévation UAC restent. À l’inverse, lorsque plusieurs sessions du même utilisateur partagent AppData et HKCU, pensez aux conflits d’écriture.

Dans les revues de conception, posez la question suivante.

Ce code est-il correct, quel que soit l’utilisateur sous lequel il s’exécute ?

Fournissez explicitement les emplacements de stockage, les clés et les informations d’identification requis pour le principal d’exécution réel. Confirmez ce principe avant la migration, et vous pouvez réduire, dès la conception, la casse où « le code n’a pas changé, et pourtant ça a cassé ».

Articles connexes

Domaines de conseil associés

KomuraSoft LLC prend en charge la conception des environnements d’exécution lorsque des applications métier sont transformées en services ou en tâches planifiées, l’investigation des pannes du type « ça marche sur ma machine », et la conception de la gestion des secrets pour les applications Windows.

Références

  1. Microsoft Learn, About User Profiles. Sur le fait que le profil utilisateur est créé à la première ouverture de session, et sur le fait qu’un profil se compose de la ruche de registre NTUSER.DAT (chargée à l’ouverture de session et mappée vers HKEY_CURRENT_USER) et de l’ensemble de dossiers de profil sur le système de fichiers.  2

  2. Microsoft Learn, Local accounts. Sur le fait que SYSTEM (S-1-5-18), NETWORK SERVICE (S-1-5-20) et LOCAL SERVICE (S-1-5-19) sont les comptes système locaux par défaut utilisés pour exécuter le système d’exploitation et les services. 

  3. Microsoft Learn, LocalSystem Account. Sur le fait que le jeton LocalSystem inclut NT AUTHORITY\SYSTEM, qu’il n’est associé à aucun compte d’utilisateur ayant ouvert une session, et par conséquent sur le fait que HKEY_CURRENT_USER est associé à l’utilisateur par défaut et sur le besoin d’emprunter l’identité d’un utilisateur pour accéder au profil de cet utilisateur.  2

  4. Microsoft Learn, LocalService Account. Sur le fait que le compte LocalService a sa propre sous-clé sous HKEY_USERS, et sur le fait que HKEY_CURRENT_USER est associé au compte LocalService. Il en va de même pour NetworkService (NetworkService Account).  2

  5. Microsoft Learn, Application Pool Identities. Sur le fait que les pools d’applications s’exécutent sous une identité propre au pool, qu’IIS ne charge pas le profil utilisateur Windows par défaut, et sur le fait de mettre l’attribut LoadUserProfile à true pour charger le profil. 

  6. Microsoft Learn, logonType Simple Type. Sur les types d’ouverture de session de tâche comprenant S4U, Password et InteractiveToken, et sur le fait qu’une ouverture de session S4U ne stocke pas le mot de passe et n’a pas accès au réseau ni aux fichiers chiffrés.  2 3

  7. Microsoft Learn, Process Model Settings for an Application Pool. Sur les attributs loadUserProfile et setProfileEnvironment du processModel d’un pool d’applications, qui contrôlent si le processus de travail charge le profil utilisateur.  2

  8. Microsoft Learn, How User Account Control works. Sur le fait que l’ouverture de session d’un utilisateur administrateur crée deux jetons liés, un jeton d’utilisateur standard et un jeton d’accès administrateur complet, lorsque UAC est activé.  2

  9. Microsoft Learn, Mapped drives are not available from an elevated prompt. Sur le fait que les lecteurs réseau mappés dans une session ouverte avec le jeton standard sont indisponibles pour les processus élevés, et sur la raison sous-jacente que les deux sessions d’ouverture de session liées tiennent leurs mappages de lecteurs séparément.  2

  10. Microsoft Learn, KNOWNFOLDERID. Sur le fait que FOLDERID_RoamingAppData (%APPDATA%), FOLDERID_LocalAppData (%LOCALAPPDATA%) et FOLDERID_LocalAppDataLow sont définis comme dossiers connus par utilisateur. 

  11. Microsoft Learn, Error occurs during desktop setup and desktop location is unavailable. Sur le fait qu’un profil utilisateur a deux fichiers de ruche, NTUSER.DAT et UsrClass.dat, et sur le fait que UsrClass.dat est placé sous AppData\Local\Microsoft\Windows. 

  12. Microsoft Learn, Services and the Registry. Sur le fait que les services ne doivent pas accéder à HKEY_CURRENT_USER ni à HKEY_CLASSES_ROOT, et sur l’utilisation de la fonction RegOpenCurrentUser lors de l’emprunt d’identité d’un utilisateur. 

  13. Microsoft Learn, CryptProtectData function. Sur le fait que CryptProtectData protège généralement les données avec une clé de session associée à l’utilisateur ayant ouvert une session et suppose un déchiffrement par le même utilisateur, et sur l’indicateur CRYPTPROTECT_LOCAL_MACHINE qui bascule vers une protection au niveau machine. 

  14. Microsoft Learn, Windows Data Protection. Sur le fait que DPAPI protège une clé maître générée aléatoirement en la chiffrant avec une clé dérivée du mot de passe de l’utilisateur, que la clé maître est stockée sous le profil utilisateur, et que la clé maître est re-protégée lorsque le mot de passe change.  2

  15. Microsoft Learn, ProtectedData Class. Sur le fait que DataProtectionScope.CurrentUser n’autorise le déchiffrement que par l’utilisateur qui a protégé les données, et que LocalMachine autorise le déchiffrement par n’importe quel processus sur la même machine. 

  16. Microsoft Learn, Data Protection key management and lifetime in ASP.NET Core. Sur le fait que les clés sont stockées dans %LOCALAPPDATA%\ASP.NET\DataProtection-Keys et chiffrées avec DPAPI sous Windows lorsqu’un profil utilisateur est disponible, sur le repli vers le registre HKLM avec ACL pour le compte du processus de travail lorsqu’hébergé dans IIS sans profil, sur le fait que les clés sont perdues à la sortie du processus et que les charges utiles protégées deviennent indéchiffrables lorsqu’aucune des conditions ne s’applique, et sur l’implication de l’attribut setProfileEnvironment. 

  17. Chromium project, User Data Directory. Sur le fait que le répertoire User Data par défaut de Chrome sous Windows est %LOCALAPPDATA%\Google\Chrome\User Data, et sur le fait que les profils (historique, favoris, cookies, etc.) y sont placés. 

  18. Google Security Blog, Improving the security of Chrome cookies on Windows. Sur le fait que Chrome a utilisé DPAPI pour chiffrer les cookies et assimilé sous Windows, et sur le fait qu’App-Bound Encryption protège la clé par un service qui s’exécute avec les privilèges SYSTEM et vérifie l’identité de l’application qui demande le déchiffrement. 

  19. Microsoft Learn, cmdkey. Sur le fait que la commande cmdkey liste, crée et supprime les noms d’utilisateur et mots de passe (informations d’identification) stockés. 

  20. Microsoft Learn, Cached and Stored Credentials Technical Overview. Sur le fait que les informations d’identification enregistrées dans le Gestionnaire d’informations d’identification sont stockées sur disque et protégées par DPAPI, et sur le fait que les programmes qui s’exécutent en tant que cet utilisateur peuvent accéder aux informations d’identification de ce magasin. 

  21. Microsoft Learn, Local Machine and Current User Certificate Stores. Sur le fait qu’il existe deux sortes de magasins de certificats, le magasin de l’ordinateur local (à l’échelle de la machine) et le magasin de l’utilisateur actuel (par utilisateur). 

  22. Microsoft Learn, System Store Locations. Sur le fait que le magasin système CERT_SYSTEM_STORE_CURRENT_USER est placé sous HKEY_CURRENT_USER\Software\Microsoft\SystemCertificates dans le registre. 

Articles récents partageant les mêmes étiquettes, pour approfondir des sujets proches.

Ces pages replacent le sujet dans un contexte plus large de services et de décisions.

Cet article est directement lié aux services suivants.

Questions fréquentes

Questions souvent posées lors d’une consultation sur le sujet de cet article.

Une application qui fonctionne lancée depuis l'Explorateur de fichiers ne trouve plus son fichier de configuration lancée depuis le Planificateur de tâches. Pourquoi ?
Parce que des variables d'environnement telles que %APPDATA% se résolvent vers le profil de l'utilisateur qui exécute le programme. Lorsque la tâche s'exécute en tant que SYSTEM ou sous un autre compte, les variables d'environnement pointent vers un autre profil (sous systemprofile dans le cas de SYSTEM), et le fichier de configuration que vous avez enregistré n'y existe pas. Vérifiez le compte sous lequel la tâche s'exécute, et placez les données à partager sous ProgramData comme correction durable.
Un mot de passe enregistré avec ProtectedData.Protect ne peut plus être déchiffré une fois l'application devenue un service.
DPAPI dans l'étendue CurrentUser dépend de la clé maître de l'utilisateur qui a chiffré les données. Si le service s'exécute sous un autre compte, la clé maître est une autre, donc le déchiffrement échoue avec une CryptographicException. Concevez à nouveau un secret lu à la fois par le service et par l'utilisateur interactif avec l'étendue LocalMachine plus une ACL de fichier, ou exécutez le service sous le compte de la personne qui a chiffré.
Que se passe-t-il lorsqu'un processus qui s'exécute en tant que SYSTEM lit HKCU ?
Dans un processus LocalSystem, HKEY_CURRENT_USER est associé à l'utilisateur par défaut (HKEY_USERS\.DEFAULT), donc les valeurs que l'utilisateur interactif a écrites dans HKCU ne sont pas visibles. Placez les paramètres à l'échelle de la machine dans HKLM, et si vous devez absolument lire les paramètres d'un utilisateur, empruntez l'identité de cet utilisateur puis utilisez RegOpenCurrentUser.
Puis-je copier un profil Chrome/Edge déjà connecté sur une machine de CI et l'utiliser ?
En général, non. Le profil d'un navigateur fondé sur Chromium tel que Chrome ou Edge se trouve sous le %LOCALAPPDATA% de l'utilisateur, et la clé de chiffrement des cookies et des mots de passe enregistrés est protégée par le DPAPI de cet utilisateur. Copier le dossier vers un autre utilisateur ou une autre machine échoue au déchiffrement parce que la clé ne correspond pas (les navigateurs tels que Firefox, qui ont leur propre protection de profil, sont un autre cas). Pour l'automatisation, codez les étapes de connexion d'un compte de test, ou utilisez le mécanisme d'état de stockage de votre outil d'automatisation.
Les informations d'identification enregistrées avec cmdkey ne sont pas utilisées lorsque la tâche s'exécute depuis le Planificateur de tâches.
Parce que le coffre du Gestionnaire d'informations d'identification est distinct pour chaque utilisateur, et ce que vous avez enregistré est allé dans le coffre de votre propre ouverture de session interactive. De plus, une tâche configurée avec « Ne pas stocker le mot de passe » (S4U) s'exécute sans informations d'identification réseau, donc déposer des informations d'identification dans le coffre n'aide pas tant qu'elle reste en S4U. Envisagez d'abord une configuration qui stocke le mot de passe ou un passage à un compte de service, et seulement ensuite, si besoin, déposez les informations d'identification dans le coffre du compte d'exécution lui-même.

Profil de l’auteur

Page de présentation de l’auteur de l’article.

Go Komura

Représentant de KomuraSoft LLC

Spécialisé dans le développement de logiciels Windows, le conseil technique et l’analyse de pannes, notamment pour les systèmes existants et les incidents difficiles à reproduire.

Retour au blog