﻿# 如何避免使用密碼存取 GitHub、BitBucket 或 Azure DevOps 的 Git 儲存庫

現在資安意識抬頭，許多東西都開始採用「零信任」的基礎來進行規劃。今天這篇文章，主要針對在 CI/CD 的環境下，如何透過 Personal Access Token (`PAT`) 來存取 Git 儲存庫。

Git 預設內含一套跨平台通用的 [Git Credential Manager](https://github.blog/2022-04-07-git-credential-manager-authentication-for-everyone/)，他會自動判別你要存取的 Git Repo 位址，並自動選用適當的認證方式。

一般來說，我們要複製一個 GitHub 上面的 Private Repo (私有儲存庫) 回來，可能會這樣寫：

```bash
git clone https://github.com/doggy8088/my-private-repo.git
```

然後你就會看到 Git Credential Manager 的登入畫面：

![Git Credential Manager](https://stwillblogassets.blob.core.windows.net/files/images/external/user-images.githubusercontent.com/4875593114c30be84fdc-172560540-3fecc08f-8288-4567-84d7-e675aa5021f6.png)

如果你按下 `Escape` 關閉視窗，你就會看到傳統的帳號密碼登入畫面：

![Git Login](https://stwillblogassets.blob.core.windows.net/files/images/external/user-images.githubusercontent.com/19347604acf511cc7d62-172567963-8f974644-0f97-4ec1-a055-b23ec5106d59.png)

當然，你絕對不會想要在 CI / CD 自動化作業 (Pipelines) 的時候「人工」輸入帳號密碼對吧！

為了要讓 Pipelines 可以自動執行並通過驗證，你有兩種作法：

1.  明確指定帳號密碼來存取 Git Repo
    
    ```bash
    git push https://<GITHUB_USER>:<GITHUB_PASS>@github.com/<GITHUB_USER>/<REPO_NAME>.git
    ```
    
    這種作法有個巨大的資安風險，就是當 `<GITHUB_PASS>` 密碼不小心洩漏的之後，駭客可以取得你在 GitHub 的所有權限，因此大多數情境都不建議這樣使用！ 🔥
    
2.  透過 PAT (Personal Access Token) 來存取 Git Repo
    
    **GitHub**
    
    ```bash
    git push https://<PAT>@github.com/<GITHUB_USER>/<REPOSITORY_NAME>.git
    ```
    
    > [Creating a personal access token](https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/creating-a-personal-access-token)
    
    這裡比較特別的地方，在於這種 URL 網址結構的 `<PAT>` 部分，其實是 BASIC AUTH (基本驗證) 的「帳號」部分，而且沒有傳入「密碼」。不過，GitHub 為了開發人員方便，讓你可以用這種方式來直接通過驗證。
    
    **BitBucket**
    
    ```bash
    git push https://<User>:<AppPassword>@bitbucket.org/<ORG_NAME>/<PROJECT_NAME>.git
    ```
    
    > [App passwords | Bitbucket Cloud | Atlassian Support](https://support.atlassian.com/bitbucket-cloud/docs/app-passwords/)
    
    這裡你可以發現，BitBucket 一定要寫帳號在 URL 結構中，但密碼的部分要去申請一組 `<AppPassword>` 應用程式密碼，因此網址結構是最完整的！
    
    **Azure DevOps Services** (`AzDO`)
    
    ```bash
    git push https://<PAT>@dev.azure.com/<ORG_NAME>/<PROJECT_NAME>/_git/<REPOSITORY_NAME>
    ```
    
    > [Use personal access tokens - Azure DevOps | Microsoft Docs](https://learn.microsoft.com/en-us/azure/devops/organizations/accounts/use-personal-access-tokens-to-authenticate?view=azure-devops&tabs=Windows&WT.mc_id=DT-MVP-4015686)
    
    這裡你可以發現，這種 URL 結構與 GitHub 的用法如出一轍，也非常方便！
    
    不過 `AzDO` 也有支援以下這種比較「正式」的網址格式：
    
    ```bash
    git push https://:<PAT>@dev.azure.com/<ORG_NAME>/<PROJECT_NAME>/_git/<REPOSITORY_NAME>
    ```
    

### 相關連結

-   [Use personal access tokens - Azure DevOps | Microsoft Docs](https://learn.microsoft.com/en-us/azure/devops/organizations/accounts/use-personal-access-tokens-to-authenticate?view=azure-devops&tabs=Windows&WT.mc_id=DT-MVP-4015686)
-   [Creating a personal access token](https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/creating-a-personal-access-token)
-   [App passwords | Bitbucket Cloud | Atlassian Support](https://support.atlassian.com/bitbucket-cloud/docs/app-passwords/)
-   [git push using GitHub token \[Deprecating password authentication\] - Techglimpse](https://techglimpse.com/git-push-github-token-based-passwordless/)
