msgraph-sdk-powershell icon indicating copy to clipboard operation
msgraph-sdk-powershell copied to clipboard

Add -Credential as authentification method to the Connect-MgGraph Command

Open JAmler opened this issue 3 years ago • 4 comments

Hello, I would like to request adding -Credential as authentification method to the Connect-MgGraph Command. This is needed to use the Microsoft Graph PowerShell SDK in DevOps. With the other ways there are following Problems:

  • Window opening to log in: Not possible in DevOps, as windows can't open there

  • Device code: very complicated as you don't know when you need to do it especially with longer scripts and you can miss the time slot to do it really often

  • Application with certificate: The scripts should be useable for many tenants and most of the time they only need to run once. So for another script where I use MS Graph Headers for direct command authentification I alread have a script part which creates and afterwards deletes the application, whats possible with only admin credentials, while it's not possible to just use the admin credentials to authentificate. But when I want to use Microsoft Graph PowerShell SDK cmdlets I can't do it as I need the certificate on top. Any authentification with certificate isn't possible in DevOps as I would need a certificate of the computer where I run the script, but the script runs on a unkown DevOps Server.

JAmler avatar Jul 05 '22 07:07 JAmler

@Microsoft as you've decided to create a new module for Graph, as opposed to adding the functionality to the existing Az module, we have to authenticate again, therefore, please make our lives easier and add support for PSCredential. It is a real pain with many hoops to jump through to set up certificate-based SPNs for Azure DevOps, other agent/runners or Automation Accounts. I for one with continue using AzureAD until this is "fixed".

You can be cleaver about this. Consider:

  • A Service Connection in Azure DevOps.
  • Utilisation of Azure Key Vault.
  • At the very least, support secret-based SPNs.

@JAmler, thank you for raising this. I have referenced this issue on SO, here. Hopefully, it will help get some 👍.

woter1832 avatar Jul 08 '22 00:07 woter1832

Thanks for bringing this to our attention.

@woter1832, @JAmler, by -Credential, do you mean adding username-password (ROPC) and client credentials via secrets auth grants? If so, we have historically not supported these grant types due to the security risk they pose for scripted scenarios. See MSAL's recommendation at:

  • username/password (ROPC):

    The resource owner password credentials (ROPC) flow is NOT recommended. ROPC requires a high degree of trust and credential exposure.

  • Application secrets.

    Application secrets (not recommended for production scenarios)

We plan to add managed identity support in v2 of the module. Managed identity is more secure than client credentials grants via secrets since it eliminates the need to manage secrets on your own. See tracking issue at https://github.com/microsoftgraph/msgraph-sdk-powershell/issues/721 for more details. Is adding managed identity enough to support your CI/CD scenario?

Please note that you can use the following as workarounds to your scenarios:

  • Use Az module to acquire an access token from resources running in Azure and pass the token to Connect-MgGraph -AccessToken. This assumes MSI is supported in your environment. See the comment at https://github.com/microsoftgraph/msgraph-sdk-powershell/issues/721#issuecomment-929383638.
  • Use Azure Key Vault task to securely fetch a certificate and pass it to Connect-MgGraph -Certificate in Azure DevOps.

In summary,

  • Azure Key Vault can be used today to fetch a certificate (Get-AzKeyVaultCertificate or Azure Key Vault task) and pass it to Connect-MgGraph -Certificate in Azure DevOps.
  • Secret-based SPNs and username-password grant are not recommended for scripting scenarios due to security reasons linked above.
  • Service Connection in Azure DevOps is something that we can explore with the AzureDevOps team but is outside the scope of this SDK.

We will use this issue to discuss this as a potential feature request. cc\ @maisarissi, @ddyett

peombwa avatar Jul 08 '22 22:07 peombwa

Hi @peombwa,

What I mean by supporting the -Credential parameter is the same as Connect-AzAccount using a Secret-based service principal. Here is your (incomplete) example: https://docs.microsoft.com/en-us/powershell/module/az.accounts/connect-azaccount?view=azps-8.1.0#example-3-connect-to-azure-using-a-service-principal-account

I notice Connect-MgGraph supports -AccessToken, however when logged in using an SPN with Graph API access, generating a token with Get-AzToken, Connect-MgGraph doesn't accept it. However, I found this article, which works.

# Populate with the App Registration details and Tenant ID
$appid = ''
$tenantid = ''
$secret = ''
 
$body =  @{
    Grant_Type    = "client_credentials"
    Scope         = "https://graph.microsoft.com/.default"
    Client_Id     = $appid
    Client_Secret = $secret
}
 
$connection = Invoke-RestMethod `
    -Uri https://login.microsoftonline.com/$tenantid/oauth2/v2.0/token `
    -Method POST `
    -Body $body
 
$token = $connection.access_token
 
Connect-MgGraph -AccessToken $token

MSIs won't work when running scripts on a laptop/PC. The Azure DevOps agent will need to be running on an Azure VM. Not all agents run on Azure VMs.

It doesn't matter where the cert comes from. Certificates are an overhead and a headache when compared to the above authentication method.

Thinking about automation, it would be awesome if you could do some cleverness where logging in with Connect-AzAccount would log in to MS Graph too. This was the big advantage of the xxx-AzAd... cmdlets.

Using -Scopes is almost pointless. You must assume that nobody has the required admin rights to grant permissions. (Is there an AAD role (other than global admin) that could grant rights?

Many thanks

woter1832 avatar Jul 19 '22 15:07 woter1832

As pointed out by @darrelmiller here, we may want to consider add clientSecret support to this PowerShell SDK to keep consistency with CLI SDK. @peombwa @timayabi2020

maisarissi avatar Aug 23 '22 20:08 maisarissi

I'd like to address something in the original issue -- it's simply not the case that certificates won't work in an Azure DevOps environment. Certificates with Connect-MgGraph will work just fine for Azure DevOpos!

In an ADO pipeline, you can just use the AzureKeyVault@2 task to download a certificate from a keyvault resource such that it is accessible to the job:

  • Update your pipeline to use AzureKeyVault@2 and populate a pipeline variable -- here's an example: (https://github.com/adamedx/autographps-sdk/blob/adamedx/integration-test/azure-pipelines.yml#L38-L43) which use the certificate from keyvault to authenticate as an AAD application to access Microsoft Graph just as one might with Connect-MgGraph which already supports certificate authentication.
  • For the task in the ADO pipeline that needs the certificate, you'll need to decode the cert value in the pipeline variable above. Here's PowerShell code that does this: https://github.com/adamedx/autographps-sdk/blob/adamedx/integration-test/test/CI/Get-CIPipelineCredential.ps1.
  • You'll need to provide access to the keyvault via the pipeline's service principal of course.

So if we're trying to help someone enable this scenario, it can be done today without waiting for new features to be added to Connect-MgGraph. And best of all the certificate approach is the safest mechanism for exercising this scenario at the moment.

adamedx avatar Oct 12 '22 20:10 adamedx

Closed by https://github.com/microsoftgraph/msgraph-sdk-powershell/pull/1555. Feature will be available in v2 of the module.

peombwa avatar Oct 13 '22 15:10 peombwa