Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Plaintext storage being forced for Azure DevOps on Linux #1549

Closed
sam-mfb opened this issue Mar 16, 2024 · 4 comments
Closed

Plaintext storage being forced for Azure DevOps on Linux #1549

sam-mfb opened this issue Mar 16, 2024 · 4 comments
Labels
auth-issue An issue authenticating to a host

Comments

@sam-mfb
Copy link

sam-mfb commented Mar 16, 2024

Version

2.4.1

Operating system

Linux

OS version or distribution

Ubuntu 22.04

Git hosting provider(s)

Azure DevOps

Other hosting provider

No response

(Azure DevOps only) What format is your remote URL?

https://{org}@dev.azure.com/{org}

Can you access the remote repository directly in the browser?

Yes, I can access the repository

Expected behavior

We are trying to access our ADO repo from inside a linux docker container using GCM and the ephemeral git credential store and the devicecode login flow. The basic idea is we use cross-platform, cross-architecture docker dev environments and we would like to be able to get our code using oauth2 (ideally) or pat (less ideal, but ok) rather than using an imported ssh key.

We basically install dotnet 7 sdk and then use that to install gcm via the Dockerfile. We then have the .gitconfig set up as follows:

[credential]
	helper = 
	helper = /home/devuser/.dotnet/tools/git-credential-manager
	credentialStore = cache
	cacheOptions = --timeout 36000
	msauthFlow = devicecode
	azreposCredentialType = oauth
[credential "https://dev.azure.com"]
	useHttpPath = true

Our expectation is that this would work, i.e., that when the user then clones the repo from the cli in the container they would get a device code that they can input in their browser to do a normal oauth flow login.

Actual behavior

It almost works, but we get this:

Cloning into 'some-repo'...
warning: cannot persist Microsoft authentication token cache securely!
warning: using plain-text fallback token cache
To sign in, use a web browser to open the page https://microsoft.com/devicelogin and enter the code [REDACTED] to authenticate.

The behavior is the same if we use pat instead of oauth

If we go forward, it "works", but obviously we are worried that the token is being persisted insecurely.

Logs

No response

@sam-mfb sam-mfb added the auth-issue An issue authenticating to a host label Mar 16, 2024
@sam-mfb
Copy link
Author

sam-mfb commented Mar 16, 2024

I am aware of this open issue: AzureAD/microsoft-authentication-library-for-dotnet#3033

Though, I'm not quite sure I understand how that relates here.

One way to state the question we have is really -- what is going on here? I.e., does the warning message we are seeing mean that we are not using git's credential cache facility, but instead things are being stored to our container's filesystem? Or does the warning just mean that MSAL is not encrypting the token, but it is still only being persisted in memory by git (albeit in plaintext, but that would be fine)? Or something else?

Our fundamental concern is we would like to not have tokens (be they oauth tokens or PATs) stored on disk in plaintext.

@sam-mfb
Copy link
Author

sam-mfb commented Mar 18, 2024

A little more digging it looks like the token is being persisted to disk in this case, specifically to the location ~/.local/.IdentityService/msal.cache with permissions 600

I have also confirmed that a token is stored here whether or not the method set is azreposCredentialType is oauth or pat

@mjcheetham
Copy link
Collaborator

A little more digging it looks like the token is being persisted to disk in this case, specifically to the location ~/.local/.IdentityService/msal.cache with permissions 600

I have also confirmed that a token is stored here whether or not the method set is azreposCredentialType is oauth or pat

Your analysis of the situation is correct here. For Azure DevOps, in either OAuth or PAT mode, GCM first needs to obtain an Azure access token which we do using the official MSAL library. After that, in OAuth mode we directly use that token with Git. In PAT mode we use the Azure token to mint a new AzDevOps PAT.

The GCM's credential storage option only affects that PAT we generate, not the Azure token from MSAL. MSAL is maintaining it's own cache of tokens. The warning message pertains to that cache being stored in plaintext.

The MSAL team do not consider implementing another encryption method that does not require the GUI for their caching extension library (that we use) a priority: AzureAD/microsoft-authentication-library-for-dotnet#3033 (comment)

Right now there's not much we can do, without a fix in that library.

@sam-mfb
Copy link
Author

sam-mfb commented Mar 18, 2024

Thanks @mjcheetham Very helpful explanation. That also explains why in PAT mode, we see a socket created in the user's directory (presumably for access to the in-memory credential cache), but not one when we use Oauth2. Based on your explanation, in the former case, that is holding the PAT (generated using the token from MSAL) whereas in the latter, you are just re-using the MSAL token.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
auth-issue An issue authenticating to a host
Projects
None yet
Development

No branches or pull requests

2 participants