API key is restricted to specific Google APIs when the Gemini (Generative Language) API is enabled
The Gemini API (a.k.a. Generative Language API, generativelanguage.googleapis.com) uses API keys to authenticate requests for uploaded files and cached content. For projects with the Gemini API enabled, each API key should have API restrictions configured to limit access to specific services.
Risk
Leaked, unrestricted API keys allow access to sensitive uploaded files and cached content, impacting their confidentiality. The risk of leaks is particularly high because traditionally, Google API keys were not considered sensitive and might be embedded in website source code, mobile apps, etc.
Run this check with Prowler
Run in Prowler Cloudprowler gcp --checks apikeys_api_restricted_with_gemini_apiRecommendation
Apply API restrictions so that each key only has access to specific APIs. Do not allow access to the "Generative Language API" in particular. If access to the "Generative Language API" is required, be aware of the consequences. Only use the key for this specific purpose and ensure adequate secrets storage.
Alternatively, completely disable the Gemini API (a.k.a. Generative Language API, generativelanguage.googleapis.com) in the project's enabled services.
Remediation
CLI
gcloud services api-keys update <KEY_ID> --api-target=service=<SERVICE_NAME>Terraform
resource "google_apikeys_key" "key" {
display_name = "<example_resource_name>"
restrictions {
api_targets {
service = "<SERVICE_NAME>" # Critical: restricts the key to a specific API, removing any "All Google APIs" (cloudapis.googleapis.com)
}
}
}Other
Check Code
from prowler.lib.check.models import Check, Check_Report_GCP
from prowler.providers.gcp.lib.constants import GEMINI_SERVICE_NAME
from prowler.providers.gcp.services.apikeys.apikeys_client import apikeys_client
from prowler.providers.gcp.services.serviceusage.serviceusage_client import (
serviceusage_client,
)
class apikeys_api_restricted_with_gemini_api(Check):
def execute(self) -> Check_Report_GCP:
findings = []
for key in apikeys_client.keys:
report = Check_Report_GCP(
metadata=self.metadata(),
resource=key,
location=apikeys_client.region,
)
report.status = "PASS"
report.status_extended = f"API key {key.name} has restrictions configured."
genlang_enabled = any(
active_service.name == GEMINI_SERVICE_NAME
for active_service in serviceusage_client.active_services.get(
key.project_id, []
)
)
if not genlang_enabled:
report.status = "PASS"
report.status_extended = f"Gemini (Generative Language) API is not enabled for project {key.project_id} of key {key.name}"
findings.append(report)
continue
key_restrictions = key.restrictions.get("apiTargets", [])
if len(key_restrictions) > 1 and any(
target.get("service") == GEMINI_SERVICE_NAME
for target in key_restrictions
):
report.status = "FAIL"
report.status_extended = f"API key {key.name} has access to Gemini (Generative Language) API as well as other APIs."
elif not key_restrictions or any(
target.get("service") == "cloudapis.googleapis.com"
for target in key_restrictions
):
report.status = "FAIL"
report.status_extended = f"API key {key.name} does not have restrictions configured and Gemini (Generative Language) API is enabled for project {key.project_id}."
findings.append(report)
return findings