iT邦幫忙

2025 iThome 鐵人賽

DAY 17
0
DevOps

連DevSecOps都不知道怎麼發音怎麼開始學習?系列 第 17

Day.17 別把鑰匙 commit 上 GitHub:Secrets Management 入門

  • 分享至 

  • xImage
  •  

前言

之前我們談過 如何用工具掃程式碼,檢查是否有人不小心把金鑰 commit 上 GitHub。(點此)
那是一種「事後抓包」的防線:

  • 鑰匙掉到地上 → 我趕快去撿。

但更理想的作法是:
鑰匙一開始就不應該出現在馬路上。

這就是Secrets Management要處理的問題。
它不是幫你找外洩,而是幫你確保憑證從頭到尾都放在正確的位置。

如果要打個比方:

  • 程式碼掃描工具(ex.gitleaks) = 巡邏隊,路上看到武器掉了就撿回來。
  • Secrets Management = 保管庫,武器永遠不會隨便出現在街上。

有了這層保障,安全性不再只是「亡羊補牢」,而是「根本不讓羊跑出去」。

1. 為什麼不能把金鑰寫死在程式碼?

這個問題對新手最常見:
反正這是測試用的 key,放在 app.py 裡應該沒差吧?

事實上,這樣做會引爆三個麻煩:

  1. 一旦 commit,就算刪掉也還在 Git 歷史裡
    這代表 key 可能被永久保存,任何人都能翻到。

  2. 無法輪替
    Key 是有壽命的,尤其在公司環境會要求定期更換。
    如果硬寫在程式碼裡,每次換 key 都要修改程式、重新部署,非常低效。

  3. 權限過大,影響範圍廣
    開發者往往圖方便,直接用一把「超級 key」開大門。
    一旦外洩,就不是單一服務掛掉,而是整個雲端帳號被接管。

這就好比 RPG 遊戲裡的傳送卷軸,你原本只想留一張在背包,但卻把一疊丟在城門口。
結果 NPC 和怪物都能拿來亂跳,場面直接失控。

2. 最簡單的入門:GitHub Actions Secrets

對入門者來說,最容易上手的方式就是用 GitHub Actions Secrets
它就像是一個「隱藏保險箱」,放在 GitHub repo 的設定裡,專門存金鑰、密碼、token。
程式碼看不到它,只有 pipeline 在需要時能讀取。

建立 Secret

GitHub 專案SettingsSecrets and variablesActionsNew repository secret
新增一個,例如:

MY_API_KEY = abcdefg123456

在 workflow 使用 Secret

接著在 .github/workflows/ci.yml 中這樣寫:

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: 使用 Secret
        run: echo "API key is ${{ secrets.MY_API_KEY }}"

這樣 workflow 執行時,就能安全取用 MY_API_KEY,而且金鑰不會出現在程式碼或 commit 裡。
就好比保管庫裡的寶物,不會放在城鎮廣場,而是只有在「打魔王的時候」才會被交到你手上。

3. 和寫死在程式碼的對比

很多人會說:「我只是圖方便,先把金鑰寫在程式碼裡,反正 repo 只有我自己在用。」
但這就是最常見的陷阱。

❌ 壞例子(寫死在程式碼)

# app.py
API_KEY = "abcdefg123456"   # 永遠不要這樣做

只要這個檔案被 push 上 GitHub,就算 repo 是 private,金鑰還是會存在 Git 歷史裡,甚至被意外分享出去。
而且 gitleaks、trufflehog 這類工具一掃,全都會被抓出來。

✅ 好例子(讀環境變數)

# app.py
import os
API_KEY = os.getenv("MY_API_KEY")

然後在 CI/CD 或系統環境裡注入 MY_API_KEY,程式就能安全使用。

這樣做的好處是:

  • 金鑰不會寫在程式碼,降低洩漏風險。
  • 隨時可輪替,不用修改程式,只要更新 Secret。
  • 權限清楚,不同環境(開發、測試、正式)可以有不同金鑰。

就好比玩家身上的武器不是直接「刻死在角色皮膚上」,而是需要在倉庫裡領出來用,用完再放回去。

4. 更進階的 Secrets 管理

GitHub Secrets 已經能解決大部分入門需求,但在更大規模高敏感環境還需要更專業的工具來管理 Secrets。

常見解法

  • HashiCorp Vault
    功能:集中式保管庫,支援「動態金鑰」和「存取租期」。
    意義:不只是存放,還能定期自動換鑰匙。

  • AWS Secrets Manager
    功能:雲端原生,跟 AWS 服務無縫整合。
    意義:適合已經全面跑在 AWS 生態的團隊。

  • Mozilla SOPS / Git-crypt
    功能:把 Secrets 加密後存進 Git。
    意義:適合 GitOps 工作流,讓配置和 Secrets 同步,但依然安全。

這些工具解決的問題

  1. 自動輪替:不需要人手換金鑰。
  2. 權限分級:不同角色只能取用不同 Secrets。
  3. 審計紀錄:誰在什麼時間存取過 Secrets,一清二楚。

這些工具不只是把鑰匙放進保險櫃,而是連「誰能開櫃子、鑰匙多久自動換一次、誰打開過」都會管好。

總結

Secrets Management 並不是額外的「加分題」,而是基礎題。
就像城鎮裡的倉庫系統,本來就應該存在,否則所有玩家的物品都亂丟在地圖上,混亂只是遲早的事。

同樣的道理,程式碼的價值在於「功能可分享」,但金鑰卻永遠屬於「環境私有」
這兩者必須切開:

  • 程式碼 → 上 GitHub,讓團隊協作、版本管理。
  • Secrets → 放在保管庫,由 CI/CD 在執行時動態注入

一旦你接受這個分工,很多後續麻煩自然消失:

  • 不用擔心某個實習生 commit 上 AWS root key
  • 不用為了輪替金鑰,把整個程式碼改來改去
  • 不用怕 gitleaks 掃出一堆紅字,才驚覺自己早已裸奔

更重要的是,這樣的設計把安全「左移」到了開發階段:
不是等鑰匙掉了再去撿,而是一開始就讓鑰匙放在正確的地方

所以,當你下次打開 app.py,忍不住想寫下一串 key 時,停下來想想:
這不只是個小小的偷懶,而是等於把整個世界線放到黑市去拍賣。


上一篇
Day.16 刀劍神域的規則書:用 tfsec 守住雲端 IaC 的致命設定
下一篇
Day.18 容器不是黑盒子:用 Trivy 掃描 Docker 鏡像漏洞
系列文
連DevSecOps都不知道怎麼發音怎麼開始學習?20
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言