|
| 1 | +# Bitbucket Authentication, 2FA and OAuth |
| 2 | + |
| 3 | +By default for authenticating against private Git repositories Bitbucket supports SSH and username/password Basic Auth over HTTPS. |
| 4 | +Username/password Basic Auth over HTTPS is also available for REST API access. |
| 5 | +Additionally Bitbucket supports App-specific passwords which can be used via Basic Auth as username/app-specific-password. |
| 6 | + |
| 7 | +To enhance security Bitbucket offers optional Two-Factor Authentication (2FA). When 2FA is enabled username/password Basic Auth access to the REST APIs and to Git repositories is suspended. |
| 8 | +At that point users are left with the choice of username/apps-specific-password Basic Auth for REST APIs and Git interactions, OAuth for REST APIs and Git/Hg interactions or SSH for Git/HG interactions and one of the previous choices for REST APIs. |
| 9 | +SSH and REST API access are beyond the scope of this document. |
| 10 | +Read about [Bitbucket's 2FA implementation](https://confluence.atlassian.com/bitbucket/two-step-verification-777023203.html). |
| 11 | + |
| 12 | +App-specific passwords are not particularly user friendly as once created Bitbucket hides their value, even from the owner. |
| 13 | +They are intended for use within application that talk to Bitbucket where application can remember and use the app-specific-password. |
| 14 | +[Additional information](https://confluence.atlassian.com/display/BITBUCKET/App+passwords). |
| 15 | + |
| 16 | +OAuth is the intended authentication method for user interactions with HTTPS remote URL for Git repositories when 2FA is active. |
| 17 | +Essentially once a client application has an OAuth access token it can be used in place of a user's password. |
| 18 | +Read more about information [Bitbucket's OAuth implementation](https://confluence.atlassian.com/bitbucket/oauth-on-bitbucket-cloud-238027431.html). |
| 19 | + |
| 20 | +Bitbucket's OAuth implementation follows the standard specifications for OAuth 2.0, which is out of scope for this document. |
| 21 | +However it implements a comparatively rare part of OAuth 2.0 Refresh Tokens. |
| 22 | +Bitbucket's Access Token's expire after 1 hour if not revoked, as opposed to GitHub's that expire after 1 year. |
| 23 | +When GitHub's Access Tokens expire the user must anticipate in the standard OAuth authentication flow to get a new Access Token. Since this occurs, in theory, once per year this is not too onerous. |
| 24 | +Since Bitbucket's Access Tokens expire every hour it is too much to expect a user to go through the OAuth authentication flow every hour. |
| 25 | +Bitbucket implements refresh Tokens. |
| 26 | +Refresh Tokens are issued to the client application at the same time as Access Tokens. |
| 27 | +They can only be used to request a new Access Token, and then only if they have not been revoked. |
| 28 | +As such the support for Bitbucket and the use of its OAuth in the Git Credentials Manager differs significantly from how VSTS and GitHub are implemented. |
| 29 | +This is explained in more detail below. |
| 30 | + |
| 31 | +## Multiple User Accounts |
| 32 | + |
| 33 | +Unlike the GitHub implementation within the Git Credential Manager, the Bitbucket implementation stores 'secrets', passwords, app-specific passwords, or OAuth tokens, with usernames in the [Windows Credential Manager](https://msdn.microsoft.com/en-us/library/windows/desktop/aa374792(v=vs.85).aspx) vault. |
| 34 | + |
| 35 | +Depending on the circumstances this means either saving an explicit username in to the Windows Credential Manager/Vault or including the username in the URL used as the identifying key of entries in the Windows Credential Manager vault, i.e. using a key such as `git:https://[email protected]/` rather than `git:https://bitbucket.org`. |
| 36 | +This means that the Bitbucket implementation in the GCM can support multiple accounts, and usernames, for a single user against Bitbucket, e.g. a personal account and a work account. |
| 37 | + |
| 38 | +## Authentication User Experience |
| 39 | + |
| 40 | +When the GCM is triggered by Git, the GCM will check the `host` parameter passed to it. |
| 41 | +If it contains `bitbucket.org` it will trigger the Bitbucket related processes. |
| 42 | + |
| 43 | +### Basic Authentication |
| 44 | + |
| 45 | +If the GCM needs to prompt the user for credentials they will always be shown an initial dialog where they can enter a username and password. If the `username` parameter was passed into the GCM it is used to pre-populate the username field, although it can be overridden. |
| 46 | +When username and password credentials are submitted the GCM will use them to attempt to retrieve a token, for Basic Authentication this token is in effect the password the user just entered. |
| 47 | +The GCM retrieves this `token` by checking the password can be used to successfully retrieve the User profile via the Bitbucket REST API. |
| 48 | + |
| 49 | +If the username and password credentials sent as Basic Authentication credentials works, then the password is identified as the token. The credentials, the username and the password/token, are then stored and the values returned to Git. |
| 50 | + |
| 51 | +If the request for the User profile via the REST API fails with a 401 return code it indicates the username/password combination is invalid, nothing is stored and nothing is returned to Git. |
| 52 | + |
| 53 | +However if the request fails with a 403 (Forbidden) return code, this indicates that the username and password are valid but 2FA is enabled on the Bitbucket Account. |
| 54 | +When this occurs the user it prompted to complete the OAuth authentication process. |
| 55 | + |
| 56 | +### OAuth |
| 57 | + |
| 58 | +OAuth authentication prompts the User with a new dialog where they can trigger OAuth authentication. |
| 59 | +This involves opening a browser request to `_https://bitbucket.org/site/oauth2/authorize?response_type=code&client_id={consumerkey}&state=authenticated&scope={scopes}&redirect_uri=http://localhost:34106/_`. |
| 60 | +This will trigger a flow on Bitbucket where the user must login, potentially including a 2FA prompt, and authorize the GCM to access Bitbucket with the specified scopes. |
| 61 | +The GCM will spawn a temporary, local webserver, listening on port 34106, to handle the OAuth redirect/callback. |
| 62 | +Assuming the user successfully logins into Bitbucket and authorizes the GCM this callback will include the Access and Refresh Tokens. |
| 63 | + |
| 64 | +The Access and Refresh Tokens will be stored against the username and the username/Access Token credentials returned to Git. |
| 65 | + |
| 66 | +# On-Premise Bitbucket |
| 67 | + |
| 68 | +On-premise Bitbucket, more correctly known as Bitbucket Server or Bitbucket DC, has a number of differences compared to the cloud instance of Bitbucket, https://bitbucket.org. |
| 69 | + |
| 70 | +As far as GCMC is concerned the main difference it doesn't support OAuth so only Basic Authentication is available. |
| 71 | + |
| 72 | +It is possible to test with Bitbucket Server by running it locally using the following command from the Atlassian SDK: |
| 73 | + |
| 74 | + ❯ atlas-run-standalone --product bitbucket |
| 75 | + |
| 76 | +See https://developer.atlassian.com/server/framework/atlassian-sdk/atlas-run-standalone/. |
| 77 | + |
| 78 | +This will download and run a standalone instance of Bitbucket Server which can be accessed using the credentials `admin`/`admin` at |
| 79 | + |
| 80 | + https://localhost:7990/bitbucket |
0 commit comments