本卡屬 FR-077(母卡 CM-1591),R1(CM-1592)的補掃棒:只掃
common/agent_auth/六支密碼學原語+enroll token 全鏈(10 檔)。只掃不修。
R1 那棒掃了 42 檔,但驗證面板因額度全滅一票沒投。研究員回報的 7 條全落在「註冊/心跳/任務端點」,而簽憑證(ca.py)、簽 token(jwt_util.py)、通行碼管理(enroll token)這三塊零發現。面板沒跑的情況下,分不出「讀過判定沒問題」與「根本沒讀到」——FR-075 的 S2 就是這樣八檔零發現卻藏著真洞。業界對密碼學核心的標準是「必須有人明確看過並簽字」,零發現不算數。
所以補一小棒,只掃這 10 檔。棒小 → 候選少 → 面板票少 → 撞額度風險低。
這 10 檔是「agent 身分的密碼學基礎」:CA 怎麼簽 agent 的憑證、雲端怎麼簽短效 JWT 給 agent、通行碼怎麼產/驗/撤。R1 已找到的問題是「雲端不驗」;這棒要問的是「就算開始驗了,被驗的東西本身站不站得住」——例如簽出來的憑證能不能被拿去冒充別的東西。
首腦讀碼後標的,是思考起點不是檢查清單。R1 的 HIGH 就是 runner 照卡片重點人工追出來的,工具當時沒報。
sign_csr() 直接沿用 CSR 自帶的 subject(ca.py:60-62 csr.subject)。subject 完全由 agent 決定——能不能簽出一張 subject 看起來像雲端自己(或別台 agent)的憑證?有沒有任何 subject 白名單/格式檢查?base_url 推導(san_from_base_url())。agent 說自己是 api.example.com,憑證 SAN 就綁 api.example.com——這張憑證能拿去對誰做 TLS 伺服器?SERVER_AUTH 與 CLIENT_AUTH(ca.py:70-73)。CLIENT_AUTH 讓它能對任何信任這顆 CA 的服務做 mTLS——雲端自己的 client 憑證(cloud_client_cert_path)是不是同一顆 CA 簽的?如果是,一台 agent 的憑證能不能冒充雲端去打另一台 agent?status=revoked——對「直接拿憑證做 TLS 的一方」(nginx、別台 agent)完全無效。這與 CM-A 卡補 nginx ssl_verify_client 之後的組合要一起想:nginx 驗的是「這顆 CA 簽的」,已 revoked 的 agent 憑證照樣過。mint() 的 op claim(jwt_util.py)。op 由 caller 傳(例如 f"GET {path}",remote_agent_service.py:_agent_sha256_get()),path 含 save_file_name——有沒有路徑穿越/注入進 claim 的面?aud=agent_uid 由 caller 傳,哪些 caller、來源可信嗎?_load_ca()/mint() 的金鑰檔路徑來自 settings。settings 由宿主組(R3 範圍),但這裡要看:路徑可控會怎樣?password=None 載入私鑰——金鑰檔本身無密碼保護,落地版的檔案權限誰管?agent_enroll_token_service.py、get_enabled_by_hash())。sha256 後拿去 DB 查——DB 查詢的字串比對是不是常數時間(通常不是,但 token 有 256 bits 熵,timing 實際可利用性要評估);token_entity.tenant_id is None 那個守門為什麼需要、什麼情況會 None?settings.py 預設值全偏不安全那一邊(mode="none"、路徑全空字串)。這棒範圍內要問的是:AgentAuthSettings 有沒有任何「不一致設定」的防呆(例如 mode=full 但 ca_cert_path 空)?enabled property 只看 mode 字串——"Full"/" full " 會怎樣(有 .strip().lower(),但要驗)?.env 越界。修正卡已開(CM-A/C/D/E,卡號見母卡)。本棒若再撞到這些,標「重複 R1 Fn」即可。followup_agent_cert_expiry_no_renewal.md)——同 R1 卡的已知對照,不重報。以上皆未經本輪面板驗證的參照。