azure-pipelinesteams-toolkitazureclicredential

How to authenticate teamsapp-cli in Azure Pipeline without user interaction (e.i. browser sign-in)


I am trying to automate the deployment and publication of my Teams App using Azure Pipelines.

Ideally, I would like to use the clientId and client secret of my AD App registration, but if I need to use a service account that is fine too. Note the service account has MFA disabled.

However, when I add the following command to my pipelines .YAML file, it tries to prompt for user interaction to sign in via a browser. teamsapp publish --package-file $(PACKAGE_FILE_PATH)

So, I am trying to authenticate the CLI before the publish command so that it can do it without user interaction. As per the documentation, I used the following command teamsapp auth login azure

However, this still prompts for me to sign in via a browser.

If I then add the --interactive false flag I then get the following error:

(×) Error: unknown.UnhandledError: An unexpected error has occurred while performing the unknown task. {"stack":"Error: UsernamePasswordCredential: tenantId, clientId, username and password are required parameters. To troubleshoot, visit https://aka.ms/azsdk/js/identity/usernamepasswordcredential/troubleshoot.
    at new UsernamePasswordCredential (C:\\Users\\dalel\\AppData\\Roaming\\npm\\node_modules\\@microsoft\\teamsapp-cli\\lib\\index.js:2:270665)
    at AzureAccountProviderUserPassword.<anonymous> (C:\\Users\\dalel\\AppData\\Roaming\\npm\\node_modules\\@microsoft\\teamsapp-cli\\lib\\index.js:2:1552520)
    at Generator.next (<anonymous>)
    at C:\\Users\\dalel\\AppData\\Roaming\\npm\\node_modules\\@microsoft\\teamsapp-cli\\lib\\index.js:2:1550876
    at new Promise (<anonymous>)
    at __awaiter (C:\\Users\\dalel\\AppData\\Roaming\\npm\\node_modules\\@microsoft\\teamsapp-cli\\lib\\index.js:2:1550424)
    at AzureAccountProviderUserPassword.getIdentityCredentialAsync (C:\\Users\\dalel\\AppData\\Roaming\\npm\\node_modules\\@microsoft\\teamsapp-cli\\lib\\index.js:2:1552394)
    at AzureAccountProviderUserPassword.<anonymous> (C:\\Users\\dalel\\AppData\\Roaming\\npm\\node_modules\\@microsoft\\teamsapp-cli\\lib\\index.js:2:1553350)
    at Generator.next (<anonymous>)
    at C:\\Users\\dalel\\AppData\\Roaming\\npm\\node_modules\\@microsoft\\teamsapp-cli\\lib\\index.js:2:1550876","message":"UsernamePasswordCredential: tenantId, clientId, username and password are required parameters. 
To troubleshoot, visit https://aka.ms/azsdk/js/identity/usernamepasswordcredential/troubleshoot."}

From my understanding, it is saying that when the UserNamePasswordCedential authentication method is used (i.e. --interactive false), that --tenantId, --clientId, --username and --password are required parameters. I also went to the troubleshooting link it provided but I did not find it useful.

However, when I then run this command:

teamsapp auth login azure --clientId <my client id> --tenantId <my tenant id> --username <service account username> --password <service account password> --interactive false --debug --verbose

I get this error:

(×) Error: TeamsfxCLI.UnknownOptionError: The command 'teamsapp auth login azure' can not be executed for unknown option '--clientId'.

If I just use --clientId and --tenantId (i.e. no username or password), then I get the same error.

If run the following command and just use --username and --password:

teamsapp auth login azure --username <service account username> --password <service account password> --interactive false --debug --verbose

Then I get the following error:

(×) Error: login.UsageError: teamsapp auth login azure
Call stack: UsageError: teamsapp auth login azure
    at C:\Users\dalel\AppData\Roaming\npm\node_modules\@microsoft\teamsapp-cli\lib\index.js:2:1453900
    at Generator.next (<anonymous>)
    at C:\Users\dalel\AppData\Roaming\npm\node_modules\@microsoft\teamsapp-cli\lib\index.js:2:1451871
    at new Promise (<anonymous>)
    at __awaiter (C:\Users\dalel\AppData\Roaming\npm\node_modules\@microsoft\teamsapp-cli\lib\index.js:2:1451419)
    at handler (C:\Users\dalel\AppData\Roaming\npm\node_modules\@microsoft\teamsapp-cli\lib\index.js:2:1453512)                                                                                             at C:\Users\dalel\AppData\Roaming\npm\node_modules\@microsoft\teamsapp-cli\lib\index.js:2:1778195                                                                                                       at AsyncLocalStorage.run (node:async_hooks:327:14)                                                                                                                                                      at Correlator.run (C:\Users\dalel\AppData\Roaming\npm\node_modules\@microsoft\teamsapp-cli\lib\index.js:2:1778183)                                                                                  
    at CLIEngine.<anonymous> (C:\Users\dalel\AppData\Roaming\npm\node_modules\@microsoft\teamsapp-cli\lib\index.js:2:1432651)

The only useful article I can find on this matter is using the old teamsfx CLI which is out of date and uses a different syntax to the teamsapp cli. Unable to use teamsfx account login azure in teamsfx-cli 2.1.0 but succeeds in 2.0.2 #10567

Can someone please help me get CLI authentication working for teamsapp so I can publish it without user interaction in a browser for authentication?

Thanks!!


Solution

  • I could reproduce the issue when running the teamsapp auth login azure command without the --service-principal option in local PowerShell outside pipelines.

    According to the instructions from the local PowerShell prompt together with the document on CI/CD templates - Teams | Microsoft Learn, You should add the --service-principal argument.

    teamsapp auth login azure `
    --tenant $AZURE_TENANT_ID `
    --username $AZURE_SERVICE_PRINCIPAL_CLIENT_ID `
    --password $AZURE_SERVICE_PRINCIPAL_CLIENT_SECRET `
    --service-principal true `
    --interactive false
    

    teamsapp auth login azure --help

    Please make sure your commands work before integrating in Azure Pipelines or any other automation tool.

    In addition to the information shared by @JerryYang, teamsapp auth login m365 for publishing Teams app to marketplace doesn't seem to support non-interactive sign-in. It requires to open a browser session for authentication. This is probably why the above document only introduces the teamsapp deploy step to deploy to Azure App Service without the next step to publish the Teams app even after it is packed.

    teamsapp auth login m365 --help

    As a workaround from the Azure DevOps perspective, consider running your pipeline on a self-hosted agent in interactive mode and complete the sign-in & MFA via that agent machine browser interactively.

    interactive mode