iT邦幫忙

2026 iThome 鐵人賽

DAY 6
0
Claude AI

Claude × Playwright:30 天打造你的 Agentic SDET 同事系列 第 6

Day 06|申請帳號與權限:讓 Agent 安全登入產品

  • 分享至 

  • xImage
  •  

前言

新同事報到,IT 開的是他自己的帳號,不是把你的密碼抄一份給他。能開哪些系統看職務,不是一次全開。

這件事我們都覺得理所當然。但很多人讓 AI 上工的時候,是直接把密碼貼進對話框的。

今天要處理的就是這件事。而且「權限」在這裡不是一件事:前四件是一般 coding agent 也有的本機與工具控制,第五件是任務授權,最外面還有受測系統本身的強制控制。

為什麼 SDET 的權限題比一般 agent 大一圈

一般 coding agent 的副作用是改你的碼。它改壞了,git checkout 就回來了,最糟糕的是浪費了你半小時。

這位同事的副作用打到別人身上

  • 開一張 issue,會通知一整個 channel 的人
  • 重置共享測試環境,會擋掉別人正在跑的 pipeline
  • 刪測試資料,可能毀掉同事跑到一半的驗證
  • 對正式站做安全測試,那是另一種等級的麻煩

這些動作的共同點是收不回來。沒有 git checkout 可以按,而且事情發生的時候,承擔後果的不是你。

所以權限這一題不能只想「它會不會弄壞我的東西」,要想「它會不會替我對別人做事」。這也是為什麼下面那份授權分級裡,「不需要人點頭」那一層現在是空的。

四件事,不要混成一件

讀者最常把這四件混在一起,但它們住在四個不同的檔案裡:

# 是什麼 住在哪 比喻
1 身分:用誰的身分登入受測產品 環境變數 IT 開他自己的帳號
2 動作:在你機器上能做什麼 .claude/settings*.json 門禁卡刷得開哪幾道門
3 工具:裝了什麼就能做什麼 .mcp.json 發哪些工具給他
4 外部服務:能不能代表你對外做事 Connector 給不給公司信箱

一、帳號與密碼

規矩兩條,沒有例外。

用專用的測試帳號,不要用你自己的。 理由跟真人一樣:出事的時候要分得出是誰做的,而且你離職不會把它一起帶走。

帳密只記變數名,不記值。 config/ 裡寫的是 env:TOOLSHOP_TEST_USER,值走環境變數,檔案裡一個字元都不留。

有人會問:公開練習站的帳密本來就印在首頁上,何必這麼麻煩?因為習慣要一致。你一旦養成「反正這個不重要,貼一下沒關係」,總有一天會貼到真的那一組。分辨哪些能貼、哪些不能貼,是每次都要做一次的判斷;一律走環境變數,是一次做完的決定。

至於 storageState(把登入後的 cookie 存下來重用),現在還沒建。它省的是每輪重登的時間,但也等於把一份有效憑證落地成檔案,在還沒有清理機制之前先不用。

二、動作相關權限

Claude Code 的權限規則有 allow、ask、deny 三段,寫在 .claude/settings.json(專案共用、進版控)或 .claude/settings.local.json(只有你自己的,不進版控)。

這個 repo 的專案共用那份放了 10 條 deny

"deny": [
  "Bash(rm -rf *)",
  "Bash(sudo *)",
  "Bash(git push --force*)",
  "Bash(git push -f *)",
  "Bash(git reset --hard*)",
  "Bash(git clean -fd*)",
  "Bash(gh pr merge*)",
  "Bash(docker compose down -v*)",
  "Bash(docker-compose down -v*)",
  "Bash(dropdb*)"
]

後四條刻意對應到待會要講的那份禁止清單。

allow 那一段要講清楚一件事:允許不代表不用問。allow 的作用是省掉重複確認(每次跑 npx playwright test 都跳一次視窗會讓人放棄使用),不是授權它做任何事。

三、MCP:工具就是能力的邊界

裝了什麼就能做什麼,沒裝就是做不到。這是最硬也最好用的一道界線 —— 它不依賴任何人的理解,沒裝就是沒有那個工具可以呼叫。

要停用某個 MCP server,關掉比刪掉好。這個 repo 的 .claude/settings.local.json 現在就只有一件事:

{
  "disabledMcpjsonServers": ["playwright"]
}

.mcp.json 裡的設定留著,但這台機器上不啟用(Day 3 選了 CLI,成本差異會在 Day 7 算給你看)。留著設定的好處是換一台機器、或哪天要比較兩種做法時,不用重寫。

還有一個容易忽略的:用了外掛,工具可能是外掛帶進來的,你自己沒裝也會有。要盤點能力,得連外掛一起盤。

四、外部服務:能代表你對外做事的那一類

Connector 跟 MCP 的差別,不在技術,在後果。MCP 給的是能力,Connector 給的是代表你對外做事的資格

這個系列最關鍵的是 GitHub:開 issue 會通知人、開 PR 會進別人的 review 佇列。這兩件事都不是「在你機器上」發生的。

deny 是護欄,不是保險箱

上面那 10 條 deny 很有用,但不能把它當成完整的安全邊界。Claude Code 會解析常見的 shell 分隔符,像 &&||; 和 pipe,並逐一檢查每個子命令;萬用字元也可以放在規則中間。因此,cd /tmp && rm -rf x 並不會因為前面多了 cd 就自然繞過檢查。

真正的限制在於:permission rule 比對的是工具呼叫與命令形狀,不是底層所有可能產生相同副作用的行為。

你寫的規則 還要考慮 為什麼
Bash(rm *) /bin/rmfind -delete 不同命令形狀可能產生相同副作用
Bash(git push --force*) git push origin main --force 這條規則只涵蓋旗標緊跟在 push 後面的形狀
Bash(dropdb*) 經由資料庫 client 送出的 DROPTRUNCATE 危險動作發生在另一個程式或遠端系統裡

所以 deny 值得寫,它可以攔下已知的危險命令;但更硬的保護要交給 sandbox、PreToolUse hook、受測系統本身的最小權限,以及下一節的授權分級與人審。每一層處理的風險不同,不能用一份字串清單代替全部。

第五件事:授權分級

前面四件一般 agent 也有,這一件是這個角色專屬的。它住在 config/governance.yaml

tiers:
  autonomous: []                 # 目前沒有任何動作免人審
  needs_review:                  # 需人審才能做
    - file_local_report          # 寫報告前,先列 title 加摘要給人確認
    - open_pr                    # 開 PR 前先確認
    - override_gate              # 品質閘門被硬推放行時需留痕
  forbidden:                     # 永遠禁止
    - merge_pr
    - reset_shared_env
    - truncate_shared_db
override:
  require_reason: true           # 硬推閘門必須留痕(誰/何時/理由)

autonomous 是空的。這不是還沒填,是刻意的:新人第一週沒有任何事情可以不問。這一層會隨著它證明自己而慢慢長出東西,但那是第四週以後的事。

forbidden 那三條跟前面 deny 清單的後四條是同一件事的兩層寫法。為什麼要寫兩次?因為 deny 擋的是指令字串,governance.yaml 擋的是動作意圖TRUNCATE 那條 deny 寫不出來,但 truncate_shared_db 這個意圖寫得出來,而每一支會產生副作用的 skill 動手前都要先讀它。

第六件事:受測環境的權限,不等於你機器的權限

這兩套東西最常被混在一起,但它們是不同的兩層。

.claude/settings.json 管的是它在你電腦上能做什麼。受測環境的權限管的是它在別人的伺服器上能做什麼。後者不該只靠寫下來的約定,還要盡量由受測系統強制執行:使用專用且最小權限的帳號、隔離的測試 tenant、付款服務的 test mode、API rate limit,以及只允許清理自己建立資料的 server-side 權限。

實際會遇到的:

  • 共用練習站不能亂建帳號、不能刪別人留下的資料,因為那是幾千個人共用的
  • 正式站不能做任何安全類測試,即使技術上做得到
  • 有真金流的環境不能按下最後那顆送出鈕

這些限制不是只靠你機器上的設定就能完成。若受測站沒有最小權限、隔離或 rate limit,你把 settings.json 開得再嚴,它仍可能對共用站送出一百筆註冊;charter 可以記錄授權範圍,但不能取代 server-side 的強制控制。

單次任務的臨時授權

全域規章之外,還需要一張「這次任務」的條子。它寫在 charter 裡(Day 15 會正式介紹這份檔案):

authorization:
  allowed:
    - "註冊:可真的送出建立帳號,但 email 必須帶唯一時間戳標記
       (例:sdet+<ts>@example.com),只建測試帳號"
    - "付款:可完整走完結帳含按下最後的下單/確認鈕(demo sandbox,無真金流)"
    - "安全(非破壞性):SQL injection 只驗證『能否不用密碼登入』後立即登出、
       觀察密碼提示是否外洩、量測帳號鎖定閾值"
  forbidden:
    - "不得寫入或修改『既有』他人資料(只能動自己新建的測試帳號)"

這一段最像真實的職場:主管針對這一次的任務簽一張條子,事情做完條子就失效。

它也解釋了後面幾天的差異 —— 為什麼 Day 7 那一輪停在付款前,而 Day 10 對 with-bugs 那個 build 可以探得更深。不是同事變大膽了,是那次任務的條子寫得不一樣。

最後埋一條伏筆:不確定就問。 明天會把它變成一條明確的規則 —— 同一個障礙卡兩次就回來找人,不要自己想辦法繞過去。

小結

權限拆成六層來想:身分走環境變數只記變數名、動作靠 settings.json 的 allow/ask/deny、能力靠裝或不裝哪些 MCP、對外做事的資格靠 Connector、任務意圖靠授權分級,最後由受測系統本身的最小權限與隔離承接真正的後果。這個角色跟一般 coding agent 最大的差別,就在於它的副作用可能落到別人與遠端系統身上。

        身分          動作          工具        外部服務
      env 變數    settings.json   .mcp.json   Connector
      只記變數名   allow/ask/deny  裝了才有能力  能代表你對外
          │            │            │            │
          └────────────┴─────┬──────┴────────────┘
                             ▼
                  這四層控制本機與外部工具
                  deny 只涵蓋已知的命令形狀
                             │
                             ▼
                第五層:config/governance.yaml
              autonomous: []  ← 空的,第一週什麼都要問
              needs_review    ← 先列給人看再動手
              forbidden       ← 連權限都沒有
                             │
              ┌──────────────┴──────────────┐
              ▼                             ▼
      受測系統的強制控制              單次任務的條子
    最小權限/隔離/rate limit     charter 的 authorization
          管真正後果                  做完就失效

開他自己的帳號,不要把你的密碼抄給他,而且一律走環境變數,不分這組重不重要。deny 是護欄不是保險箱:它攔已知的命令形狀,sandbox 與 hook 補本機的強制邊界,受測系統的最小權限與隔離則管遠端後果。再用 charter 記錄這次任務獲准做什麼、用人審處理不確定性。這個角色的副作用會打到別人身上,才是「不需要人點頭」那一層到現在仍然空著的原因。

下一步

環境有了、規則有了、產品知識有了、帳號權限也有了。

明天讓它做第一件真正的事:完整走一次產品流程。


參考資料

  1. Claude Code Docs — Configure permissions - allow/ask/deny 規則與 permission mode
  2. Model Context Protocol — Security Best Practices - confused deputy、token passthrough、scope 最小化
  3. Playwright — Authentication - storageState 重用登入狀態、專用測試帳號的做法
  4. 本專案 .claude/settings.json - 10 條 deny
  5. 本專案 config/governance.example.yaml - 授權分級範本
  6. 本專案 charters/toolshop-login-cart.yaml - 單次任務授權的實例

上一篇
Day 05|產品新人訓練:讓 Claude 看懂系統與功能
系列文
Claude × Playwright:30 天打造你的 Agentic SDET 同事6
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言