Skip to content

Adding the ability to surface the access token used by the connection #2023

Closed

Description

Discussed in #2010

Originally posted by glennvanrymenant May 15, 2023
Would it be possible to add the ability to surface the access token used by the connection (Connect-MgGraph).

I prefer to call the Graph API directly (using Invoke-MgGraphRequest rather than the specific cmdlets) but ideally I would like call the Graph API directly with Invoke-WebRequest using the access token of the Graph SDK connection.

Read: I want to piggy-back on the auth part of the module (mainly when leveraging delegated permissions as using the auth of the module is easier than writing and maintaining your own authorization code flow functions).

Activity

  1. darrelmiller commented on May 23, 2023

    @darrelmiller
    Contributor

    My concern about exposing the access token is that someone is then going to use it, and then call some API that has conditional access and it will fail. At that point we are going to create a support request because the user will not know why it failed. Or they may have a CAE token and that token could get invalidated at any time.
    As tempting as it is to simply take tokens and use them elsewhere, that is a solution that is going to fail more and more over time. This is especially true as we add support for Windows Broker and we start getting Pop tokens https://learn.microsoft.com/en-us/entra/msal/dotnet/advanced/proof-of-possession-tokens

  2. JeremyTBradshaw commented on May 23, 2023

    @JeremyTBradshaw

    Carol Kigoonya (@CarolKigoonya) you may want to stick with official stuff, such as the Microsoft.Graph.*** modules, but if you're willing to go with MSGraphPSEssentials, you can accomplish what you're after. It would be via New-MSGraphAccessToken, however it only works with app-only (client credential, with certificate) or device code flow for delegated.

    https://github.com/JeremyTBradshaw/MSGraphPSEssentials/wiki/Get-an-app-only-access-token
    https://github.com/JeremyTBradshaw/MSGraphPSEssentials/wiki/Get-an-access-token-via-Device-Code-flow
    https://github.com/JeremyTBradshaw/MSGraphPSEssentials/wiki/Refresh-an-access-token
    https://github.com/JeremyTBradshaw/MSGraphPSEssentials/wiki/Store-tokens-as-PSCredential's-in-secure-XML

    One other thing about Access Tokens - I've been told many times by various people from Microsoft - do not look inside access tokens! I personally am not vouching that you do, but stating that guidance here to avoid any lashings. Sidenote - I do think that Get-MgContext simply looks inside the access token but it is their own thing (MS'), so fair play. MSGraphPSEssentials has a function - ConvertFrom-JWTAccessToken that will let you see inside, until the day comes that Access Tokens are encrypted, which apparently is on the way.

    It is for this reason (last paragraph) that you'll find an extra property on the access token object that comes out of New-MSGraphAccessToken - "issued_at". The purpose of that is to let you use Get-AccessTokenExpiration to figure out if it's time to request a new access token (i.e., current one due to expire soon).

  3. merill commented on May 25, 2023

    @merill
    Contributor

    In typical DevOps scenarios users need to automate configuration changes across Microsoft 365, Azure and even other clouds such as AWS and GCP (through workload identity federation). They may use various tooling such as Terraform, Pulumi, etc.

    Graph PowerShell exposing the access token allows devs to use Graph PS as the primary connection point and then share the access token to other CLIs and tooling in the workflow.

    Currently, without this functionality we cannot rely on Graph PowerShell as the foundation on which to build DevOps pipelines. This will hamper productivity and lead to workarounds and users searching for alternate methods for working with Graph in PowerShell.

    FYI here is a list of CLIs and apps that expose the access token today.

    Microsoft first party tooling

    Third party tooling

    Third party tooling like Terraform's Azure Active Directory Provider support using Azure CLI to handle the authentication since there is a published API for Terraform to access the session's token. Not having a Get-MgAccessToken API would make it harder to build solutions that depend on Graph PS.

  4. darrelmiller commented on May 25, 2023

    @darrelmiller
    Contributor

    Merill Fernando (@merill) I appreciate what you are trying to achieve. I want to avoid building a solution where customers call Get-MgAccessToken once and then store and reuse that token for every request they make. How can we build a cmdLet that would lead people down the path of calling the cmdlet to get a token on every request they make?

  5. merill commented on May 26, 2023

    @merill
    Contributor

    Most devs are familiar with the MSAL pattern of invoking getAccessToken before making an API call with a token.

    It would be best to reuse the same pattern instead of introducing a new pattern just for Graph Powershell.

    The doc for the cmdlet can share the recommended pattern.

    Also the error message when using an expired token is self-explanatory.

  6. JeremyTBradshaw commented on May 29, 2023

    @JeremyTBradshaw

    Merill Fernando (@merill) assuming the expired token is self-explanatory comment is geared towards me. I do get that, just wanted to include a way to avoid the wasted request/response. Albeit, it's not a whole lot of waste.

  7. merill commented on May 29, 2023

    @merill
    Contributor

    JeremyTBradshaw I was commenting in general.

    The MSAL library already does this out of the box. It checks the expiry time and only makes a call to AzureAD when the token is about to expire. We don't need each dev to write code checking for token expiry.

    The recommended MSAL pattern for devs is to call getAccessToken before every Graph call. MSAL takes care of caching and token renewal.

    This is what the MSAL doc says "MSAL caches a token after it's been acquired. Your application code should first try to get a token silently from the cache before attempting to acquire a token by other means." https://learn.microsoft.com/en-us/azure/active-directory/develop/msal-acquire-cache-tokens

  8. JeremyTBradshaw commented on May 30, 2023

    @JeremyTBradshaw

    Please diregard.. I've now seen the other issue, #2010.

  9. glennvanrymenant commented on Jun 7, 2023

    @glennvanrymenant

    Darrel (@darrelmiller) I understand your concern regarding the use of the token against other API's but as Merill Fernando (@merill) already pointed out, there are several other MS-backed initiatives that already facilitate it - I read a blog post the other day where they (ab)use Azure PowerShell to request an access token and use it for the Graph SDK... - and I personally think that the events where the access token would be used for anything else than the Graph API would be rather rare.

    I'm a bit intrigued by your mention of CAE as I always assumed (perhaps incorrectly) that this would never apply in a development context, I can see the added value for revocation (i.e.: critical event evaluation) but how would you accommodate for a (possibly) lifetime-lengthened access token in your code? And how does that rhyme with your other comment about ensuring a new token is requested for every call?

    For the latter, this could be added (if not already) to the cmdlets on the SDK (including the Invoke-MgGraphRequest) and when developers purposefully retrieve a token separately, is their responsibility to follow best practices and guidelines just as if they were acquiring a token through any other means.

  10. glennvanrymenant commented on Jun 7, 2023

    @glennvanrymenant

    JeremyTBradshaw perhaps you can educate me on why the device code flow is so often abused by MS for delegated auth flows? AFAIK, the device code flow is intended for scenarios that involve input-constrained devices and the proper auth flow to use would be the auth code flow with PKCE, correct?

  11. JeremyTBradshaw commented on Jun 7, 2023

    @JeremyTBradshaw

    glennvanrymenant I wish I could, but honestly it's over my head what you've asked. I created the MSGraphPSEssentials module to help myself (initially) use Graph from PowerShell and Device Code is the one delegated flow that doesn't involve pulling in DLL's and browser stuff. It allowed me to keep my module tiny and simple.

    Maybe you could say I also butchered it haha. But I am not MS employee/affiliate.

  12. glennvanrymenant commented on Jun 7, 2023

    @glennvanrymenant

    JeremyTBradshaw please don't sell yourself short. I hear you regarding the dependencies, I also strive to write my PS code without them (modules, .NET classes/methods, ...) and it's true that auth code does require interaction with a browser but it's still the best option (AFAIK) in a delegated scenario. At least device code is still a better than ROPC!

  13. 2 remaining items

  14. JankeSkanke commented on Apr 9, 2024

    @JankeSkanke

    Hoping someone can progress on this. There are many tools out there in the community currently stuck with using MSAL.PS because its to hard to move away from it. Please get some work started to build the Get-MgAccessToken cmdlet.
    Darrel (@darrelmiller) Petr Hollay (@petrhollayms)

  15. davidobrien1985 commented on Apr 27, 2024

    @davidobrien1985

    I don't understand why we (the customers and community) have to go through these discussions with every single team that manages a CLI or PowerShell module.

    As Merill Fernando (@merill) mentioned, many other Microsoft tools already support this. Darrel (@darrelmiller) please consider exposing this capability like so many other tools already do.

    Thank you!

  16. DanielBradley1 commented on Apr 27, 2024

    @DanielBradley1
    Contributor

    I would also like to advocate for this change, as it would drastically help improve some of my pipelines. Currently, https://github.com/SCOMnewbie/PSMSALNet works quite well, but I would prefer to use a supported, MS-backed, module :)

  17. davidobrien1985 commented on Apr 30, 2024

    @davidobrien1985

    Someone on Twitter pointed me to this here:

    $data = Invoke-MgGraphRequest -Uri "https://graph.microsoft.com/v1.0/me" -Method GET -OutputType HttpResponseMessage
    $data.RequestMessage.Headers.Authorization.Parameter
    

    This indeed works.

  18. noopman commented on May 3, 2024

    @noopman

    Would that not only get the token with the claims for what you asked for? If I want to do something else, I'd need a different token.

    Either way, I second (fifth, sixth whatever) this request. I am in the exact same situation now. I can auth with Azure and then use Get-AzToken, but "it's not the right context for that". I don't want to go to the Azure context to get the token for my Entra context.

    How about this method. Ask Entra for a token by making a POST to:

    [Uri]"https://login.microsoftonline.com/$(Get-TenantId)/oauth2/token"

    My challenge becomes that we need a "resource" in the body. This works well when asking for a token to, for example, call an API.

  19. glennvanrymenant commented on Jul 30, 2024

    @glennvanrymenant

    Petr Hollay (@petrhollayms), Merill Fernando (@merill) since this is still open and hasn't been closed, is there any progress you can share? Can we expect the module to support generating/exposing tokens, or do we continue to rely on workarounds to grab the token?

  20. JeremyTBradshaw commented on Oct 24, 2024

    @JeremyTBradshaw

    Darrel (@darrelmiller) Petr Hollay (@petrhollayms) Merill Fernando (@merill) glennvanrymenant Carol Kigoonya (@CarolKigoonya) Magnus Mårtensson (@noopman) Jan Ketil Skanke [MVP] (@JankeSkanke) trying not to miss anyone who's been asking for this...
    https://learn.microsoft.com/en-us/entra/msal/dotnet/advanced/powershell-support - this page seems to state it outright. MS Graph PowerShell SDK is the official PowerShell thing that wraps in MSAL.NET. If we want to do things like SASL XOAuth2 for SMTP/IMAP/POP, we could use MailKit as officially recommended but then we need a way to obtain our own access token. We can do all this using C# and other programming languages that have been blessed by MSAL.NET, but in PowerShell we have to go unsupported to get our hands on an access token. This module is the correct place for this to finally happen.

    I struggle to understand why the hesitation for just PowerShell alone. It's not a matter of difficulty, that excuse can't work. We can easily get it done already in PowerShell, and it's super easy in C#, plus we can do C# things in PowerShell, and there are other easy libraries for MSAL.NET. Can't justify this any further. It is justified and please acknowledge and do something about this.

  21. merill commented on Oct 26, 2024

    @merill
    Contributor

    That's a good point you raise JeremyTBradshaw.

    Is this PowerShell module a Graph SDK that aligns in spirit to the rest of the Graph SDKs like C#, JS, etc that is intended for developers or is this module's primary audience non-devs?

    If it's an SDK, why not provide complete access to the underlying MSAL library that the other Graph libraries like C# and JS do.

    Darrel (@darrelmiller) I believe in the past you were leaning towards this module being an SDK and the users of this module being devs → #513 (comment)

  22. JeremyTBradshaw commented on Nov 13, 2024

    @JeremyTBradshaw

    Darrel (@darrelmiller) It seems like a perfect point has been made. You stated that PowerShell users are developers and should not get special treatment vs other programming language developers. But now here in this topic, PowerShell developers are being treated differently. Can we please have an update on this topic?

  23. Mike-Crowley commented on Oct 19, 2026

    @Mike-Crowley

    This came back last month as #3806 (Get-MgAccessToken returning a SecureString), prompted by the assembly isolation in 2.41.0 (#3789): the unofficial [Microsoft.Graph.PowerShell.Authentication.GraphSession]::Instance route no longer works on PowerShell 7, because that type now lives in a private AssemblyLoadContext. The Invoke-MgGraphRequest -OutputType HttpResponseMessage header trick posted above still works on 2.41.2 (checked with a fabricated token, so no sign-in involved), but it leaves a plain string in a variable, which is the main thing a SecureString-returning cmdlet would fix. Linking the two so the history here, including the 2023 concerns about token reuse, is visible there.

    🤖 Claude Mythos 5.1 (max effort) via Claude Code

  24. earbona23 commented on Nov 5, 2026

    @earbona23

    This looks like it was closed by accident a few hours ago, and I think it needs reopening.

    #3833 merged at 00:09:09Z today and closed this issue and #3806 as completed. #3895 then reverted #3833 in full at 01:48:31Z, 99 minutes later, to restore the Authentication assembly isolation. Get-MgAccessToken is not in main: searching the tree for the cmdlet name returns no match in source.

    So the feature is not shipped, but the two issues asking for it read as resolved. Anyone subscribed here since 2023 now believes this landed.

    Nothing to do with the work itself — the revert reason is sound and Ramses Sanchez-Hernandez (@ramsessanchez) already wrote the design for the follow-up in the revert body. This is only about the issue state.

  25. added a commit that references this issue on Nov 5, 2026
    5dd9caa
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions