azure-pipelines-agent: Agent installer does not support group managed service accounts (gMSA)

Agent version and platform

2.117.2 (from https://go.microsoft.com/fwlink/?linkid=851123) on Windows.

OS of the machine running the agent?

Windows Server 2016

VSTS type and version

On-Prem TFS - TFS 2017 Update 2

What’s not working?

I am attempting to use a gMSA (group managed service account) for my build agent but the unattended install progress does allow me to install the agent as a Windows service as it the installer does not understand that gMSA users do not need to provide a password.

My PowerShell install script invokes config.cmd thus

.\config.cmd --unattended --url $tfsHost --auth Integrated --pool $agentPool --agent $agentName --windowslogonaccount "domain\buildservice$" --runasservice --work "$workingDirectory" --replace

This fails with Invalid configuration provided for windowslogonpassword. If I provide a blank value for --windowslogonpassword the same error occurs.

If I provide a " " (space) the install will fail due to invalid credentials.

My work around is

  1. remove --runasservice and --windowslogonpassword
  2. Register AgentService.exe with SC.exe manually
  3. Profit! The agent successfully connects to TFS and everything works.

Logs of failure

Agent: stoic_tiger Working directory C:\B\641
Installing agent stoic_tiger

>> Connect:

Connecting to server ...

>> Register Agent:

Scanning for tool capabilities.
Connecting to the server.
Successfully added the agent
Testing agent connection.
2017-11-13 04:43:53Z: Settings Saved.
Invalid configuration provided for windowslogonpassword. Terminating unattended configuration.

It would be good to have the installer understand gMSA so I do not need to call SC.exe myself.

About this issue

  • Original URL
  • State: closed
  • Created 7 years ago
  • Reactions: 10
  • Comments: 35 (5 by maintainers)

Most upvoted comments

Would love to have this feature implemented!

Hi everyone! We are currently working on this issue - created PR

How come the support for gMSA has not been added after more than two years it was asked for? If I am not mistaken, it should not be harder then allowing to specify no password during configuration.

My workaround is to configure the agent service to run as NETWORK SERVICE, and then use sc.exe to reconfigure the created service:

sc.exe config vstsagent.Org.Pool.Name obj= yourgmsa$@youdomain.com password= ""

Next, remove NETWORK SERVICE from VSTS_AgentService_XXXX group and add yourgmsa$@youdomain.com instead.

Azure DevOps team, you should take a look at this issue. It is Microsoft’s best-practice security guidance that we use gMSAs for services, as regular user accounts for these purposes expose security issues.

So the only conclusion that we can come to after 3.5 years of this issue being open, in a service that we pay for, is that either the Azure DevOps team does not care about best-practice security guidelines that their own organization creates, or that the person in-charge of triaging and prioritizing these issues doesn’t understand security.

I strongly urge you to consider fixing this issue. As it stands today, the only service in our entire cluster that require hard-coded passwords that need to be floated around is the Azure DevOps Agent.

Please fix this.

I just hit this as well, using the interactive configuration. The configuration wizard is able to pick up the service account correctly, but then the validation for the password fails because passwords for managed service accounts are empty:

Enter run agent as service? (Y/N) (press enter for N) > y
Enter User account to use for the service (press enter for NT AUTHORITY\NETWORK SERVICE) > domain.test\vsts-agent$
Enter Password for the account domain.test\vsts-agent$ >
Enter Password for the account domain.test\vsts-agent$ >
Enter Password for the account domain.test\vsts-agent$ >
Enter Password for the account domain.test\vsts-agent$ >
…

As far as I can tell, the validation happens here:

https://github.com/microsoft/azure-pipelines-agent/blob/66e6e9a9aa4503139f5dcf4a9894ce349b68e0ab/src/Agent.Listener/CommandSettings.cs#L389-L397

Here, the validator Validators.NonEmptyValidator is being used. This may make sense for usual accounts (although I think technically user accounts can have empty passwords too?) but for managed service accounts, the password will always be empty.

I think a quick fix would be to simply remove that validator there. If it is desired to keep the validator for normal accounts (assuming that empty passwords are indeed an accident), then an alternative idea would be to check for a managed service accounts over here:

https://github.com/microsoft/azure-pipelines-agent/blob/66e6e9a9aa4503139f5dcf4a9894ce349b68e0ab/src/Agent.Listener/Configuration.Windows/WindowsServiceControlManager.cs#L69-L74

The code there already checks for well-known accounts, skipping the password prompt. The same could be done for managed service accounts. A simple check, that would avoid talking to the AD first, would be to check for a trailing dollar sign ($) since managed service accounts will end with that when used.

Let me know if you want me to contribute any of these changes, and I will happily do so.


The agent uses OAuth tokens per build to access resources. Is there a specific reason you need the service to run as a gMSA account instead of network service or local system? Our goal is the account the agent runs as is mostly irrelevant. I’m interested in your scenario.

The agent uses OAuth to talk to Azure DevOps, yes. But this is about the permissions the process executing the jobs runs with. If you run your agent with the default NT Service account, then you are essentially giving it administrator privileges. It shouldn’t be surprising that we don’t want to give administrator access to a process that locally runs arbitrary code that is checked in remotely. So using a separate account gives us control over what the process can do, and what resources it can access. And using gMSA for that is considered a good practice.

Following up/echoing this:

It’s a pretty common scenario for build agents to need to “reach out” and grab artifacts or even run test frameworks as a domain-authenticated account. Being able to use a gMSA account seems rather ideal here.

@tastyeggs I wouldn’t go that far. Yes, it is a bit annoying that you cannot set up the service to use a gMSA during setup but it’s not impossible. As mentioned earlier you can reconfigure the created service to use a different account after it has been created.

So yes, an annoyance but not a super critical security issue.

That being said, I’m still willing to contribute a fix.

I currently do the same workaround as @TingluoHuang .\config.cmd --unattended --url $tfsHost --auth Integrated --pool $agentPool --agent $agentName --windowslogonaccount "domain\tfsbuildservice$" --work "$workingDirectory" --replace

Then

$command = "sc create `"VSTS Agent (tfs.$agentName)`" binpath=$agentInstallationPath\bin\AgentService.exe obj= `"domain\tfsbuildservice$`" start= delayed-auto"
& cmd /c $command
net start "VSTS Agent (tfs.$agentName)"

I am not sure how this is not the top priority of the team delivering the agent. To be honest in your place I would (1) allow the configuration as gMSA during the deployment and (2) recommend all your users to adopt that.

Would be really nice to get this working. Currently the only service that requires a domain user in my entire cluster are these build agents.

I tried applying the workaround above, but the agent didn’t come online (I probably did something wrong).

But as a security best-practice, would be really nice to get first-class support for MSAs.

Has there been any movement on this?

@anatolybolshakov Thank you very much for putting the time and effort in. Can I kindly ask you, when we can expect the feature to be released? I have to set up a bunch of new build servers and that change would come in very handy 😊

I have create a branch with my changes that might enable GMSA support. 😃 https://github.com/Microsoft/vsts-agent/tree/users/tihuang/gmsa

Steps to test:

  1. git clone the repository
  2. git checkout users/tihuang/gmsa
  3. run cd src/
  4. run ./dev.cmd layout
  5. run cd ../_layout
  6. run config.cmd to configure the agent.

the _layout folder is the agent folder, if needed, you can zip it and copy across machines.

please share with me the diag log after attempt to configure.

Thanks for help me testing this.