Zarządzanie kluczami interfejsu API i ich bezpieczeństwo

1. Wprowadzenie

W przeszłości klucze interfejsu API Google służyły do uzyskiwania dostępu do interfejsów API Google, gdy inne metody były niedostępne lub niewygodne. Popularne przypadki użycia to dostęp do interfejsu API Map Google i interfejsów API Google udostępnianych przez Firebase. Wraz z wprowadzeniem modeli AI, agentów AI takich jak Gemini oraz środowiska AI Studio i platform programistycznych agentów, takich jak pakiet Agent Development Kit, klucze interfejsu API stały się podstawową metodą uzyskiwania dostępu do dużych modeli językowych Google.

Klucze interfejsu API zapewniają niski poziom ochrony. Chociaż Google Cloud udostępnia kilka metod zapobiegania nadużyciom kluczy, posiadanie aktywnego klucza interfejsu API umożliwia dostęp do interfejsów API Google bez dodatkowego uwierzytelniania ani weryfikacji autoryzacji. Metody ograniczania użycia kluczy interfejsu API są opisane w dokumentacji. Dodatkowe zalecenia dotyczące konserwacji kluczy interfejsu API znajdziesz w poście na blogu Cloud pt. Securing Your Gemini and Google API keys. W tym ćwiczeniu zastosujesz te zalecenia w praktyce.

Jakie zadania wykonasz

  • Sprawdzisz ograniczenia wymuszane podczas tworzenia nowych kluczy interfejsu API w Google Cloud.
  • Sklasyfikujesz wszystkie klucze interfejsu API i znajdziesz klucze bez zabezpieczenia.
  • Wymusisz ograniczenia dotyczące istniejących kluczy interfejsu API na podstawie ich użycia.
  • Zdefiniujesz automatyzację, która usuwa klucz w przypadku nietypowego użycia.

Czego potrzebujesz

  • Nowoczesna przeglądarka (np. Chrome).
  • Konto Google.

2. Konfiguracja

Instrukcje w tym ćwiczeniu zakładają, że polecenia są uruchamiane w Cloud Shell w konsoli Google Cloud. Jeśli masz gcloud CLI w środowisku lokalnym, możesz uruchamiać polecenia w tym środowisku.

Operacje opisane w tych krokach można wykonać za pomocą interfejsu konsoli Cloud, ale metody są inne. To ćwiczenie korzysta z interfejsu wiersza poleceń, aby uprościć interakcje i ułatwić integrację z nowoczesnymi agentami AI (takimi jak Antigravity CLI).

Uruchamianie terminala Cloud Shell

  1. Otwórz konsolę Google Cloud w nowym oknie przeglądarki, używając adresu https://console.cloud.google.com/. Aby zapewnić najlepszą wygodę użytkownikom, zalecamy korzystanie z Chrome.
  2. Zaloguj się na swoje konto Google w Google Cloud.
  3. U góry konsoli Google Cloud kliknij Aktywuj Cloud Shell Ikona aktywowania Cloud Shell.
    Jeśli się pojawią, kliknij te okna:
    • Przejdź przez okno z informacjami o Cloud Shell.
    • Zezwól Cloud Shell na używanie Twoich danych logowania w celu wywoływania interfejsu Google Cloud API.

Wybieranie projektu w chmurze Google

Po otwarciu konsoli Cloud następuje uwierzytelnienie i zwykle wyświetla się selektor projektu. Identyfikator projektu to ciąg znaków o długości od 6 do 30 znaków, składający się z małych liter, cyfr i łączników, np. qwiklabs-gcp-04-3075fc9fd77f. Terminal Cloud Shell konfiguruje interfejs wiersza poleceń gcloud z wybranym projektem. Zobaczysz dane wyjściowe podobne do tych:

Your Cloud Platform project in this session is set to qwiklabs-gcp-04-3075fc9fd77f

Oznacza to, że dalsze polecenia gcloud będą używać identyfikatora projektu qwiklabs-gcp-04-3075fc9fd77f.

Ustaw identyfikator projektu jako zmienną środowiskową PROJECT_ID. Listę wszystkich projektów możesz wyświetlić za pomocą tego polecenia:

gcloud projects list
  • Jeśli chcesz użyć identyfikatora projektu innego niż skonfigurowany w gcloud, zastąp your-project-id i uruchom polecenie.
    export PROJECT_ID="your-project-id"
    
    Na przykład:
    export PROJECT_ID="qwiklabs-gcp-04-3075fc9fd77f"
    
  • Jeśli chcesz użyć wybranego identyfikatora projektu, uruchom to polecenie:
    export PROJECT_ID=$(gcloud config get project)
    

3. Ograniczanie nowego klucza interfejsu API

W przeszłości użytkownicy mogli tworzyć klucze interfejsu API bez żadnych ograniczeń. Klucze bez ograniczeń można było używać do wywoływania DOWOLNEGO interfejsu API Google włączonego w projekcie, w którym został utworzony klucz. Chociaż konsola Google Cloud uniemożliwia użytkownikom tworzenie kluczy bez ograniczeń, nadal można to zrobić za pomocą interfejsu wiersza poleceń gcloud lub bezpośrednich wywołań interfejsu API.

Poniższe kroki pokazują, jak utworzyć klucz interfejsu API z ograniczeniami, który ogranicza użycie do określonego interfejsu API i określonej witryny.

  1. Aby utworzyć nowy klucz interfejsu API, który będzie można używać tylko z interfejsem Google Map Geolocation API, uruchom w terminalu powłoki to polecenie:
    gcloud services api-keys create --key-id=restricted-api-key \
      --display-name="restricted api key" \
      --api-target=service=geolocation.googleapis.com \
      --project=${PROJECT_ID}
    
    To polecenie tworzy nowy klucz interfejsu API, którego można używać TYLKO do wywoływania usługi geolokalizacji Google Map.
  2. Zwiększ bezpieczeństwo klucza, dodając ograniczenie aplikacji. Ogranicz użycie klucza tylko do wszystkich ścieżek w witrynie example.com. Aby dodać ograniczenie aplikacji do klucza, uruchom to polecenie:
    gcloud services api-keys update restricted-api-key \
      --location=global \
      --allowed-referrers="example.com/*" \
      --project=${PROJECT_ID}
    
    Zamiast zezwalać na używanie klucza w określonych witrynach, możesz użyć --allowed-application, aby zdefiniować dozwoloną aplikację na Androida, luballowed-ips, aby zdefiniować dozwolone adresy IP. Więcej informacji o wszystkich opcjach znajdziesz w pełnej dokumentacji.

Zwalnianie miejsca

Usuń utworzony klucz interfejsu API, chyba że planujesz go używać:

gcloud services api-keys delete --key-id=restricted-api-key \
  --project=${PROJECT_ID}

4. Katalogowanie kluczy interfejsu API

W tym kroku użyjesz interfejsu wiersza poleceń gcloud, aby uzyskać spis kluczy interfejsu API. Wynikowa lista zawiera wszystkie aktywne (nieusunięte) klucze interfejsu API, do których masz dostęp.

  1. Aby wyświetlić wszystkie nazwy kluczy, identyfikatory i daty utworzenia, uruchom to polecenie:
    gcloud services api-keys list --project=${PROJECT_ID} \
      --format='value(displayName,name.basename(),createTime.date())'
    
    Dane wyjściowe będą zawierać nazwę klucza, jego identyfikator i datę utworzenia. Będą one podobne do tych:
    api key 1	api-key-1	2024-05-10T07:53:24
    api key 2	api-key-2	2025-06-12T14:47:57
    
  2. Wybierz jeden z identyfikatorów kluczy i wklej to polecenie, aby sprawdzić, czy klucz ma jakieś ograniczenia. Zastąp your-key-id wartością wybranego identyfikatora klucza:
    gcloud services api-keys describe "your-key-id" --project=${PROJECT_ID}
    

Dane wyjściowe (w formacie YAML) będą zawierać listę ograniczeń w sekcji 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'

Pamiętaj, że jeśli klucz nigdy nie był aktualizowany, pola createTime i updateTime będą miały tę samą sygnaturę czasową.

  1. Pobierz i uruchom skrypt, który przechodzi przez wszystkie Twoje projekty i wyświetla wszystkie klucze interfejsu API, które NIE MAJĄ ograniczeń:
    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
    
    Po uruchomieniu skryptu zobaczysz dane wyjściowe w postaci:
    DISPLAY NAME    KEY ID    PROJECT ID    CREATION DATE
    Key 1    1a2b3c4d-1234-abcd-1234-a1b2c3d4e5f6    my-project-1    2024-05-10T07:53:24.071228Z
    
    Wszystkie skrypty używane w tym ćwiczeniu znajdziesz w folderze Security w repozytorium devrel-demos na GitHubie.

5. Odkrywanie użycia klucza interfejsu API

W tym kroku będziesz wysyłać zapytania do wskaźników Google Cloud, które pomogą Ci znaleźć interfejsy API wywoływane za pomocą Twojego klucza interfejsu API. Na podstawie tych informacji możesz sprawdzić bieżące użycie kluczy i zastosować ograniczenia interfejsu API do klucza na podstawie rzeczywistych informacji, a nie przypuszczeń.

  1. Użyj tego samego identyfikatora klucza, którego używasz w poprzednim kroku, lub wybierz inny identyfikator klucza. W tym poleceniu zastąp your-key-id wybranym identyfikatorem klucza:
    export KEY_UID=$(
       gcloud services api-keys describe "your-key-id" \
       --format='value(uid)' \
       --project=${PROJECT_ID})
    
  2. Ustaw wyszukiwanie tak, aby obejmowało historię użycia z ostatniego roku. Jeśli chcesz wyszukać dane z dłuższego lub krótszego okresu, zastąp 365 (liczbę dni) inną liczbą dodatnią.
    export DAYS=365
    
  3. Odśwież domyślne uwierzytelnianie aplikacji (ADC), aby umożliwić bezpośrednie wywoływanie interfejsu Cloud Monitoring API. Uruchom to polecenie i postępuj zgodnie z instrukcjami w terminalu:
    gcloud auth application-default login
    
  4. Aby wysłać żądanie danych wskaźników użycia usługi do interfejsu Cloud Monitoring API, uruchom to polecenie:
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

Polecenie wysyła zapytanie do wbudowanego wskaźnika serviceruntime/api/request_count w celu uzyskania punktów danych z etykietą credential_id, które pasują do unikalnego identyfikatora wybranego klucza interfejsu API. Następnie pobiera wartości etykiety service i wyświetla je, eliminując powtórzenia.

Wzmacnianie zabezpieczeń klucza interfejsu API

W tym kroku użyjesz informacji zebranych w poprzednich krokach, aby zaktualizować konfigurację ograniczeń klucza interfejsu API na podstawie informacji o użyciu.

Użyjesz tego samego klucza interfejsu API, który został użyty w poprzednim kroku. W razie potrzeby ponownie wykonaj instrukcje z poprzednich kroków, aby upewnić się, że zmienne środowiskowe PROJECT_ID, KEY_UID i DAYS są ustawione.

  1. Aby pobrać listę interfejsów API Google wywoływanych za pomocą klucza interfejsu API, uruchom to polecenie:

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
  1. Zastąp listę ograniczonych interfejsów API listą niepustą:
    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. Definiowanie wykrywania anomalii użycia

W poprzednich krokach pokazaliśmy, jak eksplorować i zabezpieczać klucze interfejsu API. Ten krok pokazuje, jak zautomatyzować reakcję na nieoczekiwany wzrost użycia klucza za pomocą alertów usługi Monitoring.

Poniższe instrukcje tworzą alert, który jest wywoływany, gdy liczba wywołań interfejsu API, które używają klucza interfejsu API, wzrośnie o ponad 10% w ciągu ostatnich 5 minut. Alert jest skonfigurowany tak, aby wywoływać skrypt Cloud Build, który usuwa klucz interfejsu API, aby zapobiec dalszemu użyciu. Klucz można przywrócić w ciągu najbliższych 30 dni. Informacje o tym, jak cofnąć usunięcie klucza, znajdziesz w dokumentacji.

Instrukcje ponownie używają zmiennych PROJECT_ID i KEY_UID, których używasz w poprzednich krokach. Jeśli chcesz wybrać inny klucz lub projekt, ustaw nowe wartości tych zmiennych zgodnie z opisem w krokach Konfiguracja i Odkrywanie użycia klucza interfejsu API.

  1. Aby utworzyć plik zasad alertów, uruchom ten skrypt:
    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
    
    Zasady alertów używają tego filtra PromQL do wywoływania alertu:
     (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)
    
    Oblicza on tempo wzrostu i porównuje je z poprzednim oknem. Alert jest wywoływany tylko wtedy, gdy jest ono większe o ponad 10%. Aby uniknąć wywoływania alertu, gdy łączna liczba wywołań jest pomijalna, warunkuje on wywoływanie alertu na podstawie liczby wywołań interfejsu API w oknie, która musi być większa niż 50. Aby uniknąć obliczania NaN (dzielenia przez zero), gdy poprzednie 5-minutowe tempo wynosiło 0, zastępuje mianownik wartością 1, jeśli tempo w poprzednim oknie wynosi zero.Możesz zmienić parametry alertu, takie jak długość okna (5m), minimalny próg (50) lub próg wzrostu o 10% (1.10).Dodatkowe parametry zasad określają, że po osiągnięciu warunku alert powinien zostać wywołany (duration), a warunek powinien być sprawdzany co 60 sekund (evaluationInterval).
  2. Aby utworzyć temat Pub/Sub, który będzie używany do publikowania powiadomień o alertach, uruchom to polecenie:
    gcloud pubsub topics create api-key-alert-notifications --project=$PROJECT_ID
    
  3. Aby utworzyć kanały powiadomień o alertach, które korzystają z Pub/Sub, uruchom to polecenie:
    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)
    
    W kroku Czyszczenie danych użyjesz zmiennej środowiskowej CHANNEL_NAME.
  4. Aby utworzyć nowy alert usługi Monitoring, uruchom to polecenie:
    gcloud monitoring policies create --policy-from-file=alert_policy.json \
      --project=$PROJECT_ID
    
  5. Aby przyznać usłudze Cloud Build uprawnienia do usuwania kluczy interfejsu API w projekcie, uruchom to polecenie:
    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"
    
    Możesz ograniczyć rolę apikeys.admin tak, aby można było manipulować tylko określonymi instancjami kluczy interfejsu API. Więcej informacji znajdziesz w sekcji Warunki Cloud IAM.
  6. Aby utworzyć aktywator kompilacji Cloud Build, który usuwa klucz interfejsu API, uruchom ten skrypt:
    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
    
  7. Aby utworzyć nowy aktywator alertu usługi Monitoring, uruchom to polecenie:
    gcloud builds triggers create pubsub \
      --trigger-config=trigger_config.yaml \
      --project=$PROJECT_ID
    

Teraz możesz usunąć pliki konfiguracyjne zasad tworzenia alertów i aktywatora kompilacji Cloud Build:

rm alert_policy.json trigger_config.yaml

Możesz też skonfigurować tę automatyzację za pomocą planu Terraform. Pobierz pliki Terraform z folderu abnormal-usage-detection w repozytorium Google Cloud DevRel . Plan przyjmuje jako parametry wejściowe identyfikator projektu i identyfikator klucza interfejsu API oraz konfiguruje zasoby i ustawienia, które zostały opisane w tym kroku.

7. Zwalnianie miejsca

Aby uniknąć nieoczekiwanych opłat na koncie Google Cloud, pamiętaj o usunięciu tematu Pub/Sub, aktywatora kompilacji Cloud Build i zasad tworzenia alertów utworzonych podczas tego ćwiczenia.

Aby usunąć wszystkie utworzone zasoby, uruchom te polecenia:

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. Podsumowanie

W tym ćwiczeniu zaimplementowano niezawodną platformę kompleksowych zabezpieczeń i automatyzacji dla kluczy interfejsu API Google Cloud:

  1. Zabezpieczone konfiguracje domyślne: utworzono i ograniczono klucze interfejsu API, aby ograniczyć dostęp wyłącznie do niezbędnych interfejsów API i zaufanych platform (takich jak określone strony odsyłające HTTP).
  2. Sprawdzono spis kluczy: przeskanowano środowiska projektu, aby wykryć i odizolować klucze bez ograniczeń, które stanowią bezpośrednie zagrożenie dla bezpieczeństwa.
  3. Przeanalizowano dane o użyciu: programowo wysłano zapytanie do danych wskaźników Cloud Monitoring, aby utworzyć profil historycznego wykorzystania kluczy, co umożliwia ograniczenie kluczy na podstawie zweryfikowanych śladów użycia.
  4. Zautomatyzowano ograniczanie zagrożeń: utworzono reaktywny „wyłącznik”, łącząc zasady alertów Cloud Monitoring z tematem Pub/Sub i aktywatorem Cloud Build, co umożliwia automatyczne usuwanie naruszonych kluczy podczas nietypowych skoków ruchu.

Następne kroki

  • Zastosuj ograniczenia do wszystkich kluczy interfejsu API: wykorzystaj wiedzę zdobytą w tym ćwiczeniu, aby wykryć wszystkie częściowo ograniczone lub nieograniczone klucze interfejsu API i zastosować ograniczenia interfejsu API oraz klienta.
  • Skonfiguruj „wyłącznik” dla kluczy interfejsu API: dodatkowo zabezpiecz klucze interfejsu API przed nieoczekiwanym użyciem, konfigurując automatyczne usuwanie kluczy w przypadku nagłego wzrostu zużycia. Użyj poleceń gcloud lub Terraform pokazanych w ćwiczeniu. Rozważ zaostrzenie uprawnień za pomocą warunków Cloud IAM.
  • Poznaj alerty usługi Monitoring: dowiedz się więcej o konfigurowaniu alertów za pomocą usługi Google Cloud Monitoring.
  • Dowiedz się więcej o kontroli dostępu dostępnej w Google Cloud: zapoznaj się z zasadami dotyczącymi granic dostępu i propagacją zmian dostępu.