本文說明如何使用 X.509 憑證,為 Workload Identity Federation 設定憑證式存取權。
憑證型存取權會使用相互傳輸層安全標準 (mTLS) 在 TLS 握手期間驗證用戶端和伺服器。在這個程序中,mTLS 繫結會根據傳輸環境納入政策,並使用 TLS 工作階段中用戶端憑證的狀態來做出授權決策。
如果是 X.509 工作負載身分聯盟,mTLS 繫結可確保整個驗證流程安全地繫結至受信任的工作負載。由於驗證程序會繫結至特定信任端點,因此可降低憑證遭竊的風險。
Workload Identity Federation 設定總覽:以憑證為基礎的存取權
以下概略說明如何設定 Workload Identity Federation 的憑證式存取權:
設定 X.509 憑證的信任錨點,建立工作負載身分聯盟。
建立憑證式存取的存取層級。
將存取層級新增至強制執行 mTLS 繫結的情境感知存取權政策。
事前準備
請確認您符合下列必要條件:
最新版 Google Cloud CLI
如要更新至最新版 Google Cloud CLI,請執行下列指令:
gcloud components update
如需安裝 Google Cloud CLI,請參閱「安裝 Google Cloud CLI」。
使用 X.509 憑證信任錨點的 Workload Identity 聯盟設定
如要使用這項功能,請填寫下列表單,將您加入許可清單:許可清單要求表單。 加入許可清單後,我們會與你聯絡。
建立憑證的存取層級
建立 mTLS 存取層級。判斷資源存取權時,mTLS 存取層級會驗證憑證。
主控台
在 Access Context Manager 中建立自訂存取層級,然後在 CEL 運算式欄位中輸入下列運算式:
request.auth.matchesMtlsTokens(origin) == true
。gcloud
如要建立自訂存取層級,請執行下列指令:
gcloud access-context-manager levels create ACCESS_LEVEL_NAME
--title=TITLE
--custom-level-spec=FILE
--description=DESCRIPTION
--policy=POLICY_NAME更改下列內容:
ACCESS_LEVEL_NAME
:存取層級的名稱。TITLE
:存取層級的標題。FILE
:包含下列內容的 YAML 檔案:request.auth.matchesMtlsTokens(origin) == true
。DESCRIPTION
:存取層級的說明。POLICY_NAME
:存取權政策的名稱。
將您建立的存取層級匯出至環境變數。後續步驟會用到這個變數。
export ACCESS_LEVEL_ID=ACCESS_LEVEL_ID
將
ACCESS_LEVEL_ID
替換為存取層級名稱,例如accessPolicies/12345/accessLevels/acl_1
。
為工作負載身分集區建立情境感知存取權繫結
設定下列環境變數。
export ORG_ID=ORG_ID export CALLER_PROJECT_ID=CALLER_PROJECT_ID export FEDERATED_PRINCIPAL=FEDERATED_PRINCIPAL
更改下列內容:
ORG_ID
:貴機構的 ID。CALLER_PROJECT_ID
:用於呼叫 API 的專案 ID。FEDERATED_PRINCIPAL
:工作負載身分識別集區中身分主體的名稱,必須符合情境感知存取權政策。你可以使用下列任一選項:格式為 -
principal://iam.googleapis.com/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/POOL_ID/subject/SUBJECT_ATTRIBUTE_VALUE
的單一身分或
集區中的所有身分,格式為 -
principalSet://iam.googleapis.com/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/POOL_ID/*
gcloud
gcloud alpha access-context-manager cloud-bindings create \ --organization=
ORG_ID
\ --federated-principal=FEDERATED_PRINCIPAL
\ --level=ACCESS_LEVEL_ID
--dry-run-level=DRY_RUN_ACCESS_LEVEL_ID
更改下列內容:
ACCESS_LEVEL_ID
:存取層級名稱。DRY_RUN_ACCESS_LEVEL_ID
:模擬測試存取層級名稱。建議您先啟用模擬執行政策繫結,瞭解對現有流量的潛在影響。
curl
建立含有情境感知存取權繫結的 JSON 檔案。
即使欄位重複,您在要求中也只能提供一個存取層級。您可以使用下列類型的同盟主體:
- 單一身分:
principal://iam.googleapis.com/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/POOL_ID/subject/SUBJECT_ATTRIBUTE_VALUE
- 集區中的所有身分:
principalSet://iam.googleapis.com/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/POOL_ID/*
echo { \ \"principal\": { \ \"federatedPrincipal\": \"${FEDERATED_PRINCIPAL:?}\" \ },\ \"accessLevels\": [\"${ACCESS_LEVEL_ID:?}\"] \ } \ >> request.json
- 單一身分:
請使用
curl
傳送下列 HTTP 要求。curl -H "X-Goog-User-Project: ${CALLER_PROJECT_ID:?}" -X POST \ -H "Authorization: Bearer $(gcloud auth print-access-token)" \ -H "Content-Type: application/json; charset=utf-8" \ -d @request.json \ "https://accesscontextmanager.googleapis.com/v1alpha/organizations/${ORG_ID:?}/gcpUserAccessBindings"
使用 Google Cloud 用戶端程式庫授權
如要使用Google Cloud 用戶端程式庫授權 Workforce Identity Federation 工作負載,請完成下列步驟。
建立為員工身分聯盟驗證設定的應用程式預設憑證 (ADC) 檔案。
gcloud iam workload-identity-pools create-cred-config IDENTITY_POOL_ID \ --credential-cert-path WORKLOAD_CERTIFICATE_PATH \ --credential-cert-private-key-path WORKLOAD_KEY_PATH \ --output-file ADC_FILE_OUTPUT_PATH
更改下列內容:
IDENTITY_POOL_ID
:工作負載身分集區的 ID。WORKLOAD_CERTIFICATE_PATH
:工作負載憑證檔案的路徑。WORKLOAD_KEY_PATH
:工作負載私密金鑰檔案的路徑。ADC_FILE_OUTPUT_PATH
:ADC 檔案的輸出路徑。
這個指令也會在 gcloud CLI 預設設定目錄中產生憑證設定檔。憑證設定檔支援初始驗證,並為後續對 Google Cloud 資源的要求建立 mTLS 交握。
設定環境變數,指向 ADC 檔案。這樣 Google 用戶端程式庫就能探索您的憑證。
export GOOGLE_APPLICATION_CREDENTIALS=${application_default_credentials.json}
如果您在產生 ADC 檔案時省略
--output-file
引數,則可略過這個步驟。如果省略引數,系統會從 gcloud CLI 預設設定目錄建立及讀取 ADC 檔案。如要建立及測試對 Google Cloud API 的存取權,請完成下列步驟。您可以使用 Go 或 Python。
Go
請使用下列範例建立 Go 檔案,例如
golang_test.go
。package golang_test import ( "io" "log" "testing" "cloud.google.com/go/auth/credentials" "cloud.google.com/go/auth/httptransport" ) func TestGoExample(t *testing.T) { scopes := []string{ "https://www.googleapis.com/auth/pubsub", // Scope for Pub/Sub access // Add other scopes as needed } dopts := credentials.DetectOptions{ Scopes: scopes, } // Create httptransport.Options with the scopes opts := &httptransport.Options{ DetectOpts: &dopts, } hc, err := httptransport.NewClient(opts) if err != nil { t.Fatalf("NewHTTPClient: %v", err) } resp, err := hc.Get("https://pubsub.mtls.googleapis.com/v1/projects/PROJECT_ID/topics") if err != nil { t.Fatalf("Get: %v", err) } t.Logf("Status: %s", resp.Status) t.Cleanup(func() { resp.Body.Close() }) b, err := io.ReadAll(resp.Body) if err != nil { t.Fatal(err) } log.Println(string(b)) }
將 PROJECT_ID 替換為您的 gcloud CLI 專案 ID。
如要在 Compute Engine VM 上執行測試,請使用下列指令。
go mod init example.com go mod tidy go test -v golang_test.go --count=1
Python
請使用下列範例建立測試檔案,例如
python_test.py
。import google.auth import google.auth.transport.requests import requests def test_go_example(): # Define the required scopes for your application scopes = [ "https://www.googleapis.com/auth/pubsub", # Scope for Pub/Sub access # Add other scopes as needed ] # Obtain Application Default Credentials (ADC) with the specified scopes credentials, _ = google.auth.default(scopes=scopes) # Create an authorized HTTP session using the ADC credentials authed_session = google.auth.transport.requests.AuthorizedSession(credentials) try: # Make a GET request to the Pub/Sub API endpoint response = authed_session.get( "https://pubsub.mtls.googleapis.com/v1/projects/PROJECT_ID/topics" ) # Check if the request was successful response.raise_for_status() # Raise an exception for error statuses # Log the response status and content print(f"Status: {response.status_code}") print(response.text) except requests.exceptions.RequestException as e: print(f"Error making the request: {e}") if __name__ == "__main__": test_go_example()
將 PROJECT_ID 替換為您的 gcloud CLI 專案 ID。
如要在 Compute Engine VM 上執行測試,請完成下列步驟。
- 設定 Python 虛擬環境。
安裝必要的程式庫。
pip install google-auth google-auth-httplib2 requests
執行測試:
python3 python_test.py
使用純文字 HTTP 要求授權
如要使用純 HTTP 要求授權 Workforce Identity Federation 工作負載,請完成下列步驟。
透過標準 mTLS 交握程序,從 Google Cloud 安全權杖服務取得與憑證綁定的存取權杖。
使用從 Security Token Service 取得的存取權杖呼叫 Google Cloud 服務。這個範例會查詢 Cloud Storage。
$ curl --key ${workload_key.pem} --cert ${workload_cert.pem} -X GET 'https://storage.mtls.googleapis.com/{replace_with_your_resources}' -H "Authorization: Bearer $ACCESS_TOKEN"
mTLS 繫結會強制使用 mTLS。執行下列指令,確認非 mTLS 連線會因未經授權而失敗。
$ curl -X GET 'https://storage.googleapis.com/{replace_with_your_resources}' -H "Authorization: Bearer $ACCESS_TOKEN"
列出政策繫結
如要列出 Workload Identity 聯盟的政策繫結,請執行下列指令。
gcloud
下列指令會列出指定機構內的特定繫結,並篩選適用於聯盟主體的繫結。
gcloud alpha access-context-manager cloud-bindings list \
--organization=ORG_ID
\
--filter='principal:federatedPrincipal'
curl
curl -H "X-Goog-User-Project: ${CALLER_PROJECT_ID:?}" -X GET \
-H "Authorization: Bearer $(gcloud auth print-access-token)" \
"https://accesscontextmanager.googleapis.com/v1alpha/organizations/${ORG_ID:?}/gcpUserAccessBindings?filter=principal%3Afederated_principal"
更新政策繫結
如要更新政策繫結,請將新的存取層級新增至 JSON 檔案,然後執行下列指令。
gcloud
gcloud alpha access-context-manager cloud-bindings update \ --binding=BINDING_ID
\ --level=NEW_ACCESS_LEVEL_ID
curl
curl -H "X-Goog-User-Project: ${CALLER_PROJECT_ID:?}" -X PATCH \
-H "Authorization: Bearer $(gcloud auth print-access-token)" \
-H "Content-Type: application/json; charset=utf-8" \
-d @request.json \
"https://accesscontextmanager.googleapis.com/v1alpha/organizations/${ORG_ID:?}/gcpUserAccessBindings/${BINDING_ID:?}?updateMask=access_levels"
刪除政策繫結
如要刪除政策繫結,請執行下列指令。
gcloud
gcloud alpha access-context-manager cloud-bindings delete \
--binding=BINDING_ID
curl
curl -H "X-Goog-User-Project: ${CALLER_PROJECT_ID:?}" -X DELETE \
-H "Authorization: Bearer $(gcloud auth print-access-token)" \
"https://accesscontextmanager.googleapis.com/v1alpha/organizations/${ORG_ID:?}/gcpUserAccessBindings/${BINDING_ID:?}"
疑難排解
以下列出幾個常見問題和建議解決方法:
錯誤:
403 Forbidden, user does not have permission.
動作:檢查 IAM 政策,確認工作負載身分集區有權存取 Google Cloud 資源。
錯誤:
Unauthorized_client: Could not obtain a value for google.subject from the given credential.
動作:後端無法根據屬性對應,從用戶端憑證中擷取
google.subject
的值。檢查用戶端憑證,確認您用來對應的欄位有值。啟用情境感知存取權後,如果遇到非預期的存取遭拒情況,可以使用下列指令移除情境感知存取權繫結,快速解除封鎖流量:
gcloud alpha access-context-manager cloud-bindings delete
存取權恢復後,請查看稽核記錄,判斷要求遭拒的原因。