1641 字
8 分鐘

Cloudflare API Shield 支援 HS256 了:對稱 JWT 驗證怎麼設定

Cloudflare API Shield 的 JWT validation 在 2026 年 8 月 25 日加入對稱金鑰支援,現在可以驗證使用 HS256、HS384 或 HS512 簽署的 token。這適合由 issuer 和 validator 共用 HMAC secret 的 API,但也代表 secret 的產生、交付與輪替都要由你自己維護。

直接答案是:在 token configuration 放入 kty: "oct" 的 HMAC JWK,讓 alg 和 JWT header 的 alg 一致,讓 kid 能對應到正在使用的 key;接著用規則決定無效或缺少 JWT 的請求要 log 還是 block。 API Shield 只負責驗證簽章與 claims,不會替你設計完整的 authorization policy。

對稱與非對稱 JWT 的差異#

驗證方式Cloudflare 需要什麼適合的情境主要風險
RSA/EC 非對稱issuer 發布的 public JWKS多個驗證端、希望只公開公鑰JWKS 更新與 key cache
HMAC 對稱和 issuer 共用的 secret服務數量有限、現有 token 使用 HS 系列secret 任何一方外洩都能簽發 token

Cloudflare 公告表示,對稱 credential 不會以明文儲存,API 回應也不會回傳 credential;但 issuer 端仍必須保管原始 secret。這不是「可以把 secret 放在 repository」的理由,也不會阻止拿到 secret 的人偽造合法 JWT。

先準備符合 JWT header 的 HMAC JWK#

API 的 credentials.keys 使用 JWK 形式。下面是結構示例,k 只放示意值,不能把真實 secret 寫進文章、issue 或 shell history:

{
"credentials": {
"keys": [
{
"kty": "oct",
"alg": "HS256",
"kid": "api-2026-08",
"k": "<base64url-secret>"
}
]
},
"title": "internal-api-hmac",
"description": "JWT verification for internal API",
"token_sources": [
"http.request.headers[\"authorization\"][0]"
],
"token_type": "JWT"
}

這裡的四個欄位各自扮演不同角色:

  • kty: "oct" 表示對稱 key;alg 必須是 HS256HS384HS512
  • kid 要和 issuer 放在 JWT header 的 key ID 對上,不能只更新 Cloudflare 端的 secret 字串。
  • k 是建立或更新設定時提供的對稱 key material;它不應出現在 log、Terraform plan 輸出或 PR diff。
  • token_sources 決定 Cloudflare 從哪個 header 或 cookie 取 token。若使用 Authorization,請確認 issuer 與 client 的格式一致。

不要把 alg 當成可由請求者任意選擇的安全開關。驗證設定應固定允許的算法,並在測試中確認使用錯誤算法、錯誤 kid、過期與錯誤簽章的 token 都會得到預期結果。

用 API 建立 token configuration#

Cloudflare API 的建立 endpoint 是 zone scoped。示例只展示結構,不包含真實 credential:

Terminal window
curl --request POST \
--url "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/token_validation/config" \
--header "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \
--header "Content-Type: application/json" \
--data @token-config.json

token-config.json 應由 secret manager 或受控部署流程產生;不要先把檔案加入 Git,再用 .gitignore 補救。部署後保存回應中的 configuration ID 與非敏感 metadata,之後規則要用到它,但不要期待 GET 回應能讓你重新取回 HMAC secret。

Dashboard 的路徑則是 Security Settings → API abuse → Token configurations → Configure tokens。先在低風險 hostname 或測試端點驗證,再把同一套設定帶到 production;不要用 production token 當作第一個測試輸入。

Token configuration 和 enforcement rule 是兩件事#

Cloudflare 的流程分成「找到並驗證 JWT」和「依結果採取動作」兩部分。只有建立 configuration,不等於無效 token 已經被阻擋。

如果需要依 claims 或其他訊號做 zone-wide policy,優先考慮 WAF custom rules;如果只想套用到 Endpoint Management 的特定 operation,才使用 JWT validation rules。可以用已驗證的 claim 寫條件,例如:

lookup_json_string(
http.request.jwt.claims["<TOKEN_CONFIGURATION_ID>"][0],
"role"
) eq "admin"

在規則中還要明確決定「缺少 JWT」的行為:

行為代表什麼適合情境
Ignore沒有 JWT 的請求不因缺少 token 被視為不合規;若有 token 仍會驗證公開與登入後流量共用 endpoint
Mark as non-compliant預期每個選定端點都應有 JWT純受保護的 API 路徑

先用 log 觀察合法 client、過期 token、錯誤 kid 和缺少 header 的比例,再切換 block。若規則直接 block,會很難分辨是 JWT 內容錯誤、token source 選錯,還是 CORS preflight 被誤判。

輪替時同時處理 kid 與 issuer#

HMAC 輪替不是只在 Cloudflare 貼上新 secret。比較穩妥的順序是:

  1. 先建立新的 key material 與新的 kid,在受控的 token configuration 中讓驗證端同時認得舊、新 key。
  2. 更新 issuer,讓新簽發的 JWT 使用新的 kid;保留舊 key 直到所有 client 與 token TTL 都跨過切換窗口。
  3. 用實際 API 請求確認新 token 通過、舊 token 在預期的寬限期內仍符合策略,並觀察 Cloudflare log。
  4. 到期後移除舊 key,將 secret manager、部署紀錄與回復文件一起更新。

如果 API 更新 endpoint 要求提交完整的 key set,就不要用只包含新 key 的 payload 意外刪掉仍在使用的舊 key。先讀取該 endpoint 的 PUT/PATCH 語意,在 staging 做一次輪替,再安排 production 窗口。這種遷移和 Cloudflare Access Service Token 的 Grace Period 輪替相似:兩者都需要先切換使用端,再讓舊 credential 失效,但 API Shield 的 key matching 還多了一層 algkid 對應。

別忘了 CORS 和 token 位置限制#

Cloudflare 文件特別提醒,瀏覽器的 CORS OPTIONS preflight 通常不帶 authentication header 或 cookie。如果把所有 OPTIONS 都套用「缺少 JWT 就 block」,前端真正的 GET 或 POST 可能永遠到不了 API;公開 API 的規則可視情況加入 or http.request.method eq "OPTIONS"

此外,JWT validation 只處理 request header 或 cookie 中的 token,不處理放在 POST body 的 JWT。若你的 client 把 token 放在 body,應先重新評估 API contract,不要只改 token source 期待 Cloudflare 自動找到它。

結論是:HS256 支援讓使用 HMAC 的 API 可以直接接上 API Shield,但也把共享 secret 的治理責任帶進來。先固定 JWK 的 algkid 和 token source,再用 log-to-block 的順序驗證規則,最後用可觀察的雙 key 窗口完成輪替,才不會把一次小改動變成全站驗證中斷。

常見問題#

API Shield 可以直接把 HMAC secret 讀回來嗎?#

不行。Cloudflare 表示不會以明文儲存對稱 credential,API 回應也不會包含 credential。原始 secret 應保留在 issuer 與受控的 secret manager,遺失時要依輪替流程建立新 key。

JWT header 的 kid 不同,但 secret 一樣,可以通過嗎?#

不能假設可以。Cloudflare 會依設定的 key identity 和算法驗證,kid 是 key matching 的一部分。若要切換 key,應讓 issuer 和 token configuration 同時使用相同的 kid

為什麼 token configuration 建立後,錯誤 JWT 還沒有被擋下來?#

因為 configuration 負責找到和驗證 JWT,規則才負責對不合規結果採取 logblock。請另外檢查 rule selector、缺少 JWT 的處理方式與 CORS OPTIONS 例外。

參考資料:

Cloudflare Changelog:Symmetric key support for JWT validation

Cloudflare API Shield:JSON Web Tokens validation

Cloudflare API:Create a token validation configuration

Cloudflare API Shield 支援 HS256 了:對稱 JWT 驗證怎麼設定
https://laplusda.com/posts/cloudflare-api-shield-symmetric-jwt-validation/
作者
Zero
發佈於
2026-08-30
許可協議
CC BY-NC-SA 4.0
這篇文章有幫助嗎?

回報錯字、失效連結,或告訴我你想看的延伸主題。