1. 簡介
過去,如果無法使用其他方法或覺得不方便,就會使用 Google API 金鑰存取 Google API。熱門用途包括存取 Google Maps API 和 Firebase 公開的 Google API。隨著 AI 模型、Gemini 等 AI 代理、AI Studio,以及 Agent Development Kit 等代理開發架構的推出,API 金鑰已成為存取 Google 大型語言模型的主要方法。
API 金鑰提供的保護等級較低。雖然 Google Cloud 提供多種方法來防止金鑰遭到濫用,但只要擁有有效的 API 金鑰,就能存取 Google API,不必進行任何額外的驗證或授權驗證。如要瞭解如何限制 API 金鑰的使用方式,請參閱說明文件。Cloud 網誌的「保護 Gemini 和 Google API 金鑰」一文,提供 API 金鑰維護的其他建議。在本程式碼研究室中,您將實際運用這些建議。
學習內容
- 在 Google Cloud 中建立新的 API 金鑰時,請查看強制執行的限制
- 列出所有 API 金鑰,找出沒有安全防護的 API 金鑰
- 根據現有 API 金鑰的使用情形強制執行限制
- 定義自動化動作,在異常使用時刪除金鑰
軟硬體需求
- 新版網路瀏覽器 (例如 Chrome)。
- Google 帳戶
2. 設定
本 Codelab 的操作說明假設您在 Google Cloud 控制台的 Cloud Shell 中執行指令。如果您在本機環境中安裝了 gcloud CLI,即可在本機執行指令。
雖然步驟中的作業可以使用 Cloud 控制台 UI 完成,但方法不同。本程式碼研究室使用指令列介面簡化互動,並讓您更輕鬆地與新式 AI 代理 (例如 Antigravity CLI) 整合。
啟動 Cloud Shell 終端機
- 在新瀏覽器視窗中,使用 https://console.cloud.google.com/ 開啟 Google Cloud 控制台。建議使用 Chrome,以獲得最佳使用者體驗。
- 在 Google Cloud 中登入 Google 帳戶。
- 點選 Google Cloud 控制台頂端的「啟用 Cloud Shell」
。
如果系統顯示視窗,請按照下列步驟操作:- 繼續操作 Cloud Shell 視窗。
- 授權 Cloud Shell 使用您的憑證發出 Google Cloud API 呼叫。
選取 Google Cloud 專案
開啟 Cloud 控制台後,系統會驗證您的身分,通常也會提供專案選取畫面,方便您進行工作。專案 ID 是由 6 至 30 個小寫英文字母、數字和破折號組成的字串,例如 qwiklabs-gcp-04-3075fc9fd77f。Cloud Shell 終端機會使用所選專案設定 gcloud CLI。畫面會顯示類似以下的輸出:
Your Cloud Platform project in this session is set to qwiklabs-gcp-04-3075fc9fd77f
這表示您後續的 gcloud 指令將使用專案 ID qwiklabs-gcp-04-3075fc9fd77f。
將專案 ID 設為環境變數 PROJECT_ID。您可以使用下列指令查看所有專案的清單:
gcloud projects list
- 如要使用與
gcloud中設定的專案 ID 不同的專案 ID,請替換your-project-id並執行指令。 舉例來說:export PROJECT_ID="your-project-id"export PROJECT_ID="qwiklabs-gcp-04-3075fc9fd77f" - 如要使用所選專案 ID,請執行下列指令:
export PROJECT_ID=$(gcloud config get project)
3. 限制新的 API 金鑰
過去,使用者可以建立完全不受限制的 API 金鑰。未設限制的金鑰可用於呼叫在建立金鑰的專案中啟用的任何 Google API。Google Cloud 控制台會禁止使用者建立不受限制的金鑰,但使用者仍可透過 gcloud CLI 或直接呼叫 API 建立這類金鑰。
下列步驟說明如何建立受限的 API 金鑰,限制只能由特定 API 和指定網站使用。
- 如要建立新的 API 金鑰,並限制只能搭配 Google 地圖地理位置 API 使用,請在 Shell 終端機中執行下列指令:
這項指令會建立新的 API 金鑰,只能用來呼叫 Google 地圖地理位置服務。gcloud services api-keys create --key-id=restricted-api-key \ --display-name="restricted api key" \ --api-target=service=geolocation.googleapis.com \ --project=${PROJECT_ID} - 新增應用程式限制,提高金鑰安全性。限制金鑰只能用於網站中的所有路徑
example.com。執行下列指令,將應用程式限制新增至金鑰: 除了允許在特定網站使用金鑰,您也可以使用gcloud services api-keys update restricted-api-key \ --location=global \ --allowed-referrers="example.com/*" \ --project=${PROJECT_ID}--allowed-application定義允許的 Android 應用程式或allowed-ips定義允許的 IP 位址。如要瞭解所有選項,請參閱完整說明文件。
清除所用資源
除非您打算使用建立的 API 金鑰,否則請刪除該金鑰:
gcloud services api-keys delete --key-id=restricted-api-key \
--project=${PROJECT_ID}
4. 列出 API 金鑰
在本步驟中,您將使用 gcloud CLI 取得 API 金鑰清單。結果清單會顯示您有權存取的所有有效 (未刪除) API 金鑰。
- 執行下列指令,查看所有金鑰名稱、ID 和建立日期:
輸出結果會顯示金鑰的易讀名稱、金鑰 ID 和金鑰建立日期。類似以下範例:gcloud services api-keys list --project=${PROJECT_ID} \ --format='value(displayName,name.basename(),createTime.date())'api key 1 api-key-1 2024-05-10T07:53:24 api key 2 api-key-2 2025-06-12T14:47:57
- 選取其中一個金鑰 ID,然後貼上下列指令,檢查金鑰是否有任何限制。將
your-key-id替換為所選金鑰 ID 的值:gcloud services api-keys describe "your-key-id" --project=${PROJECT_ID}
輸出內容 (YAML 格式) 的 restrictions 底下會列出限制。
createTime: '2024-05-10T07:53:24.986528Z'
displayName: api key 1
etag: W/"u1WuY41K2tPKUZd7cfLoKg=="
name: projects/123456789012/locations/global/keys/api-key-1
restrictions:
apiTargets:
- service: geolocation.googleapis.com
browserKeyRestrictions:
allowedReferrers:
- https://example.com/*
uid: 1a2b3c4d-1234-abcd-1234-a1b2c3d4e5f6
updateTime: '2024-05-10T07:53:24.071228Z'
請注意,如果金鑰從未更新,createTime 和 updateTime 欄位會顯示相同的時間戳記。
- 下載並執行指令碼,逐步檢查所有專案,並列印沒有限制的所有 API 金鑰:
執行指令碼後,您會看到以下格式的輸出內容:curl -fsSL -o unrestricted_api_keys.sh \ "https://github.com/GoogleCloudPlatform/devrel-demos/blob/main/security/api-key-audit/unrestricted_api_keys.sh" chmod +x unrestricted_api_keys.sh ./unrestricted_api_keys.sh 您可以在 GitHub 上的 devrel-demos 存放區中,找到本程式碼研究室使用的所有指令碼,位置在 Security 資料夾。DISPLAY NAME KEY ID PROJECT ID CREATION DATE Key 1 1a2b3c4d-1234-abcd-1234-a1b2c3d4e5f6 my-project-1 2024-05-10T07:53:24.071228Z
5. 瞭解 API 金鑰的使用情形
在本步驟中,您將查詢 Google Cloud 指標,找出使用 API 金鑰呼叫的 API。您可以根據這項資訊查看金鑰目前的使用情形,並根據實際資訊對金鑰套用 API 限制,而不是隨意猜測。
- 使用與上一個步驟相同的金鑰 ID,或選擇其他金鑰 ID。在下列指令中,將
your-key-id替換為所選金鑰 ID:export KEY_UID=$( gcloud services api-keys describe "your-key-id" \ --format='value(uid)' \ --project=${PROJECT_ID}) - 將搜尋範圍設為一年內的使用記錄。如要尋找更長或更短的時間範圍,請將
365(天數) 替換成其他正數。export DAYS=365 - 重新整理應用程式預設憑證 (ADC),直接呼叫 Cloud Monitoring API。執行下列指令,並按照終端機中的指示操作:
gcloud auth application-default login - 執行下列指令,將服務用量指標資料的要求傳送至 Cloud Monitoring API:
curl -s -G -H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
--data-urlencode "filter=metric.type=\"serviceruntime.googleapis.com/api/request_count\" AND resource.labels.credential_id=\"apikey:${KEY_UID}\"" \
--data-urlencode "interval.startTime=$(date -u -d "${DAYS} days ago" +%Y-%m-%dT%H:%M:%SZ)" \
--data-urlencode "interval.endTime=$(date -u +%Y-%m-%dT%H:%M:%SZ)" \
"https://monitoring.googleapis.com/v3/projects/${PROJECT_ID}/timeSeries" \
| jq -r '.timeSeries[]?.resource.labels.service' | sort -u
這項指令會查詢 serviceruntime/api/request_count 內建指標,找出標籤為 credential_id 且符合所選 API 金鑰專屬 ID 的資料點。然後擷取 service 標籤的值,並在排除重複項目後列印這些值。
強化 API 金鑰
在這個步驟中,您將使用先前步驟收集的資訊,根據使用資訊更新 API 金鑰的限制設定。
您會使用上一個步驟中使用的相同 API 金鑰。如有必要,請重新執行上一個步驟中的操作說明,確保已設定環境變數 PROJECT_ID、KEY_UID 和 DAYS。
- 執行下列指令,擷取使用 API 金鑰呼叫的 Google API 清單:
SERVICES=$(curl -s -G -H "Authorization: Bearer $(gcloud auth application-default print-access-token)"
–data-urlencode "filter=metric.type="serviceruntime.googleapis.com/api/request_count" AND resource.labels.credential_id="apikey:${KEY_UID}""
–data-urlencode "interval.startTime=$(date -u -d "${DAYS} days ago" +%Y-%m-%dT%H:%M:%SZ)"
–data-urlencode "interval.endTime=$(date -u +%Y-%m-%dT%H:%M:%SZ)"
"https://monitoring.googleapis.com/v3/projects/${PROJECT_ID}/timeSeries"
| jq -r ‘.timeSeries[]?.resource.labels.service' | sort -u)
1. Build the list of arguments to restrict the API usage for the API key based
on the retrieved list.
```shell
API_TARGET_ARGS=()
for SERVICE in $SERVICES; do
API_TARGET_ARGS+=("--api-target=service=${SERVICE}")
done
- 取代非空白清單的受限 API 清單:
if [ ${#API_TARGET_ARGS[@]} -gt 0 ]; then gcloud services api-keys update "projects/${PROJECT_ID}/locations/global/keys/${KEY_UID}" \ ${API_TARGET_ARGS} fi
6. 定義異常使用情形偵測
先前的步驟說明如何探索及強化 API 金鑰。這個步驟說明如何運用監控快訊,在金鑰用量突然達到高峰時自動採取因應措施。
下列操作說明會建立快訊,當使用 API 金鑰的 API 呼叫率在過去 5 分鐘內增加超過 10% 時,系統就會觸發快訊。系統已設定警報,觸發 Cloud Build 指令碼來刪除 API 金鑰,防止進一步使用。您可以在接下來 30 天內還原金鑰。如要瞭解如何取消刪除金鑰,請參閱說明文件。
這些指令會重複使用您在先前步驟中使用的 PROJECT_ID 和 KEY_UID 變數。如要選取其他金鑰和/或專案,請按照「設定及探索 API 金鑰的使用方式」步驟中的說明,為這些變數設定新值。
- 執行下列指令碼來建立快訊政策檔案:
警告政策會使用下列 PromQL 篩選器觸發警告:cat <<EOF > alert_policy.json { "displayName": "Credential API Request Count Increase Alert (Project: ${PROJECT_ID})", "combiner": "OR", "conditions": [ { "displayName": "API Request Count Increase > 10% in 5m with Min Volume", "conditionPrometheusQueryLanguage": { "query": "(sum(increase(serviceruntime_googleapis_com:api_request_count{metric_label_credential_id=\\"apikey:${KEY_UID}\\"}[5m])) / (sum(increase(serviceruntime_googleapis_com:api_request_count{metric_label_credential_id=\\"apikey:${KEY_UID}\\"}[5m] offset 5m)) or on() vector(1)) > 1.10) and (sum(increase(serviceruntime_googleapis_com:api_request_count{metric_label_credential_id=\\"apikey:${KEY_UID}\\"}[5m])) > 50)", "duration": "0s", "evaluationInterval": "60s" } } ], "enabled": true } EOF 系統會計算成長率,並與前一個時間範圍的成長率進行比較。只有在超過 10% 時才會觸發快訊。為避免在呼叫總數可忽略不計時觸發快訊,系統會設定觸發條件,要求視窗中的 API 呼叫超過 50 次。為避免(sum( increase( serviceruntime_googleapis_com:api_request_count{metric_label_credential_id="API_KEY_UID"}[5m]) ) / (sum( increase( serviceruntime_googleapis_com:api_request_count{metric_label_credential_id="API_KEY_UID"}[5m] offset 5m) ) or on() vector(1)) > 1.10) and (sum( increase( serviceruntime_googleapis_com:api_request_count{metric_label_credential_id=\"YOUR_CREDENTIAL_ID_HERE\"}[5m])) > 50)NaN(除以零) 計算,如果前 5 分鐘的速率為 0,系統會將分母替換為 1。您可以變更快訊參數,例如時間範圍長度 (5m)、最小門檻 (50) 或 10% 增幅門檻 (1.10)。其他政策參數會定義達到條件時應觸發快訊 (duration),以及每 60 秒應探查條件 (evaluationInterval)。 - 執行下列指令,建立用於發布快訊通知的 Pub/Sub 主題:
gcloud pubsub topics create api-key-alert-notifications --project=$PROJECT_ID - 執行下列指令,為使用 Pub/Sub 的快訊建立通知管道。
您會在「清除」步驟中使用CHANNEL_NAME=$(gcloud beta monitoring channels create \ --display-name="Pub/Sub Alert Channel" \ --type="pubsub" \ --channel-labels="topic=projects/$PROJECT_ID/topics/api-key-alert-notifications" \ --format='value(name)' \ --project=$PROJECT_ID)CHANNEL_NAME環境變數。 - 執行下列指令,建立新的監控快訊:
gcloud monitoring policies create --policy-from-file=alert_policy.json \ --project=$PROJECT_ID - 執行下列指令,授予 Cloud Build 服務權限,刪除專案中的 API 金鑰。
您可以限制PROJECT_NUMBER=$(gcloud projects describe $PROJECT_ID --format="value(projectNumber)") gcloud projects add-iam-policy-binding $PROJECT_ID \ --member="serviceAccount:${PROJECT_NUMBER}@cloudbuild.gserviceaccount.com" \ --role="roles/apikeys.admin"apikeys.admin角色,只允許操作特定 API 金鑰執行個體。詳情請參閱「IAM 條件」。 - 執行下列指令碼,建立會刪除 API 金鑰的 Cloud Build 自動建構觸發條件。
cat <<EOF > trigger_config.yaml name: "delete-compromised-api-key" description: "Triggered by Pub/Sub alert to automatically delete the leaking API Key" pubsubConfig: topic: "projects/${PROJECT_ID}/topics/api-key-alert-notifications" build: steps: - name: "gcr.io/google.com/cloudsdktool/cloud-sdk:slim" args: - "gcloud" - "services" - "api-keys" - "delete" - "${KEY_UID}" - "--quiet" EOF - 執行下列指令,建立新的監控快訊觸發條件:
gcloud builds triggers create pubsub \ --trigger-config=trigger_config.yaml \ --project=$PROJECT_ID
現在可以刪除快訊政策和 Cloud Build 觸發條件設定檔:
rm alert_policy.json trigger_config.yaml
或者,您也可以使用 Terraform 方案設定這項自動化功能。從 Google Cloud DevRel 存放區的 abnormal-usage-detection 資料夾下載 Terraform 檔案。這項計畫會接受專案 ID 和 API 金鑰 UID 做為輸入參數,並設定您在本步驟中看到的資源和設定。
7. 清理
為避免 Google Cloud 帳戶產生預期外的費用,請務必刪除本練習中建立的 Pub/Sub 主題、Cloud Build 自動建構觸發條件和快訊政策。
執行下列指令,刪除您建立的所有資源:
gcloud builds triggers delete delete-compromised-api-key \
--project=$PROJECT_ID
gcloud beta monitoring channels delete $CHANNEL_NAME \
--project=$PROJECT_ID \
--quiet
gcloud pubsub topics delete api-key-alert-notifications \
--project=$PROJECT_ID
gcloud projects remove-iam-policy-binding $PROJECT_ID \
--member="serviceAccount:${PROJECT_NUMBER}@cloudbuild.gserviceaccount.com" \
--role="roles/apikeys.admin"
8. 摘要
在本程式碼研究室中,您為 Google Cloud API 金鑰實作了強大的端對端安全性和自動化架構:
- 強化預設設定:您已建立並限制 API 金鑰,只允許存取必要的 API 和可信任的平台 (例如特定 HTTP 參照網址)。
- 稽核金鑰清單:您掃描了專案環境,偵測並隔離會造成立即安全風險的不受限金鑰。
- 分析使用資料:您以程式輔助方式查詢 Cloud Monitoring 指標資料,以剖析金鑰的歷史使用情況,並根據經過驗證的使用足跡限制金鑰。
- 自動化威脅緩解:您將 Cloud Monitoring 快訊政策連結至 Pub/Sub 主題和 Cloud Build 自動建構觸發條件,建立反應式「斷路器」,以便在異常流量尖峰期間自動刪除遭入侵的金鑰。
後續步驟
- 對所有 API 金鑰套用限制:運用在本實驗室學到的知識,偵測所有部分受限或未設限的 API 金鑰,並套用 API 和用戶端限制。
- 為 API 金鑰設定「斷路器」:如果用量突然增加,請設定自動刪除金鑰,進一步保護 API 金鑰,避免遭到意外使用。請使用實驗室中顯示的
gcloud指令或 Terraform。考慮使用 IAM 條件來縮緊權限 - 探索 Monitoring 快訊功能:進一步瞭解如何使用 Google Cloud Monitoring 服務設定快訊。
- 進一步瞭解 Google Cloud 提供的存取控管機制:請參閱存取權界線政策和存取權變更傳播。