Gerenciamento e segurança de chaves de API

1. Introdução

Historicamente, as chaves de API do Google eram usadas para acessar APIs do Google quando outros métodos não estavam disponíveis ou eram considerados inconvenientes. Os casos de uso mais comuns foram o acesso à API Google Maps e às APIs do Google expostas pelo Firebase. Com a introdução de modelos de IA, agentes de IA como o Gemini e estruturas de desenvolvimento de AI Studio e de agentes, como o Kit de Desenvolvimento de Agente, as chaves de API se tornaram o principal método de acesso aos modelos de linguagem grandes do Google.

As chaves de API oferecem um baixo nível de proteção. Embora o Google Cloud ofereça vários métodos para evitar o uso indevido das chaves, ter uma chave de API ativa permite o acesso às APIs do Google sem outras validações de autenticação ou autorização. Os métodos para restringir o uso de chaves de API estão descritos na documentação. A postagem Proteja suas chaves de API do Gemini e do Google no blog do Cloud oferece mais recomendações sobre a manutenção de chaves de API. Neste codelab, você vai colocar essas recomendações em prática.

Atividades deste laboratório

  • Revise as restrições aplicadas ao criar novas chaves de API no Google Cloud
  • Catalogar todas as chaves de API e encontrar as que não têm proteção de segurança
  • Aplicar restrições às chaves de API atuais com base no uso delas
  • Defina uma automação que exclua a chave em caso de uso anormal

O que é necessário

  • Um navegador da Web moderno, como o Chrome.
  • Uma Conta do Google

2. Configuração

As instruções deste codelab pressupõem que você execute comandos no Cloud Shell no console do Google Cloud. Se você tiver a CLI gcloud no seu ambiente local, poderá executar os comandos lá.

Embora as operações nas etapas possam ser feitas usando a interface do console do Cloud, os métodos são diferentes. Este codelab usa a interface de linha de comando para simplificar as interações e facilitar a integração com agentes de IA modernos, como a CLI do Antigravity.

Iniciar um terminal do Cloud Shell

  1. Abra o console do Google Cloud usando https://console.cloud.google.com/ em uma nova janela do navegador. Recomendamos usar o Chrome para ter a melhor experiência do usuário.
  2. Faça login na sua Conta do Google no Google Cloud.
  3. Clique em Ativar o Cloud Shell Ícone "Ativar Cloud Shell" na parte de cima do console do Google Cloud.
    Se aparecer, clique nas seguintes janelas:
    • Continue na janela de informações do Cloud Shell.
    • Autorize o Cloud Shell a usar suas credenciais para fazer chamadas de APIs do Google Cloud.

Selecione um projeto do Google Cloud

Depois de abrir o console do Cloud, você será autenticado, e geralmente há uma seleção de projetos para seu trabalho. O ID do projeto é uma sequência de 6 a 30 caracteres de letras minúsculas, números e símbolos de traço, por exemplo, qwiklabs-gcp-04-3075fc9fd77f. O terminal do Cloud Shell configura a CLI gcloud com o projeto selecionado. Você verá um resultado semelhante a este:

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

Isso significa que seus outros comandos para gcloud vão usar o ID do projeto qwiklabs-gcp-04-3075fc9fd77f.

Defina o ID do projeto como uma variável de ambiente PROJECT_ID. Para conferir a lista de todos os seus projetos, use o seguinte comando:

gcloud projects list
  • Substitua your-project-id e execute o comando se quiser usar um ID de projeto diferente do configurado em gcloud.
    export PROJECT_ID="your-project-id"
    
    Por exemplo:
    export PROJECT_ID="qwiklabs-gcp-04-3075fc9fd77f"
    
  • Execute o comando a seguir se quiser usar o ID do projeto selecionado:
    export PROJECT_ID=$(gcloud config get project)
    

3. Restringir uma nova chave de API

Antes, os usuários podiam criar chaves de API sem restrições. As chaves sem restrições podem ser usadas para chamar QUALQUER API do Google ativada no projeto em que a chave foi criada. Embora o console do Google Cloud impeça os usuários de criar chaves sem restrições, ainda é possível usar a CLI gcloud ou chamadas de API diretas.

As etapas a seguir mostram como criar uma chave de API restrita que limita o uso à API específica e ao site especificado.

  1. Para criar uma chave de API restrita ao uso com a API Geolocation do Google Maps, execute o seguinte comando no terminal do shell:
    gcloud services api-keys create --key-id=restricted-api-key \
      --display-name="restricted api key" \
      --api-target=service=geolocation.googleapis.com \
      --project=${PROJECT_ID}
    
    Esse comando cria uma nova chave de API que pode ser usada SOMENTE para chamar o serviço de geolocalização do Google Maps.
  2. Aumente a segurança da chave adicionando uma restrição de aplicativo. Limite o uso da chave a todos os caminhos no site example.com. Execute o comando a seguir para adicionar a restrição de aplicativo à chave:
    gcloud services api-keys update restricted-api-key \
      --location=global \
      --allowed-referrers="example.com/*" \
      --project=${PROJECT_ID}
    
    Em vez de permitir o uso da chave em sites específicos, use --allowed-application para definir o app Android permitido ouallowed-ips para definir os endereços IP permitidos. Consulte a documentação completa para todas as opções.

Limpar

Exclua a chave de API criada, a menos que você planeje usá-la:

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

4. Catalogar suas chaves de API

Nesta etapa, você vai usar a CLI gcloud para receber um inventário das suas chaves de API. A lista resultante mostra todas as chaves de API ativas (não excluídas) a que você tem acesso.

  1. Execute o comando a seguir para conferir todos os nomes, IDs e datas de criação das chaves:
    gcloud services api-keys list --project=${PROJECT_ID} \
      --format='value(displayName,name.basename(),createTime.date())'
    
    A saída vai mostrar o nome legível da chave, o ID dela e a data de criação. Ele será semelhante a este:
    api key 1	api-key-1	2024-05-10T07:53:24
    api key 2	api-key-2	2025-06-12T14:47:57
    
  2. Escolha um dos IDs de chave e cole o seguinte comando para verificar se a chave tem restrições. Substitua your-key-id pelo valor do ID da chave selecionada:
    gcloud services api-keys describe "your-key-id" --project=${PROJECT_ID}
    

A saída (em YAML) vai conter uma lista de restrições em 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'

Se a chave nunca foi atualizada, os campos createTime e updateTime terão o mesmo carimbo de data/hora.

  1. Faça o download e execute o script que percorre todos os seus projetos e imprime todas as chaves de API que NÃO têm restrições:
    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
    
    Depois de executar o script, você vai receber uma saída no formato:
    DISPLAY NAME    KEY ID    PROJECT ID    CREATION DATE
    Key 1    1a2b3c4d-1234-abcd-1234-a1b2c3d4e5f6    my-project-1    2024-05-10T07:53:24.071228Z
    
    Todos os scripts usados neste codelab estão na pasta "Security" do repositório devrel-demos no GitHub.

5. Descobrir o uso de uma chave de API

Nesta etapa, você vai consultar as métricas do Google Cloud que ajudam a encontrar quais APIs foram chamadas usando sua chave de API. Com essas informações, é possível analisar o uso atual das chaves e aplicar restrições de API com base em informações reais, em vez de fazer uma estimativa.

  1. Use o mesmo ID de chave da etapa anterior ou escolha outro. Substitua your-key-id pelo ID da chave escolhida no seguinte comando:
    export KEY_UID=$(
       gcloud services api-keys describe "your-key-id" \
       --format='value(uid)' \
       --project=${PROJECT_ID})
    
  2. Defina a pesquisa para analisar o histórico de uso de um ano. Se quiser procurar por um período mais longo ou mais curto, substitua 365 (número de dias) por outro número positivo.
    export DAYS=365
    
  3. Atualize o Application Default Credentials (ADC) para ativar a chamada direta à API Cloud Monitoring. Execute o comando a seguir e siga as instruções no terminal:
    gcloud auth application-default login
    
  4. Execute o comando a seguir para enviar uma solicitação de dados de métricas de uso do serviço à API Cloud Monitoring:
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

O comando consulta a métrica integrada serviceruntime/api/request_count para pontos de dados com o rótulo credential_id que correspondem ao ID exclusivo da chave de API escolhida. Em seguida, ele recupera os valores do rótulo service e os imprime, eliminando repetições.

Reforço da proteção da chave de API

Nesta etapa, você vai usar as informações coletadas nas etapas anteriores para atualizar a configuração de restrição da chave de API com base nas informações de uso.

Você vai usar a mesma chave de API da etapa anterior. Se necessário, execute novamente as instruções das etapas anteriores para garantir que as variáveis de ambiente PROJECT_ID, KEY_UID e DAYS estejam definidas.

  1. Execute o seguinte comando para recuperar a lista de APIs do Google chamadas usando a chave de 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
  1. Substitua a lista de APIs restritas pela lista não vazia:
    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. Definir a detecção de uso anômalo

As etapas anteriores mostraram como explorar e proteger chaves de API. Esta etapa mostra como automatizar uma resposta a um pico inesperado de uso da chave com a ajuda dos Alertas do Monitoring.

As instruções a seguir criam um alerta que é acionado quando uma taxa de chamadas de API que usam uma chave de API aumenta em mais de 10% nos últimos 5 minutos. O alerta é configurado para acionar um script do Cloud Build que exclui a chave de API para evitar mais uso. A chave pode ser restaurada nos próximos 30 dias. Consulte a documentação para saber como recuperar a chave.

As instruções reutilizam as variáveis PROJECT_ID e KEY_UID que você usou nas etapas anteriores. Se você quiser selecionar uma chave e/ou um projeto diferente, defina os novos valores para essas variáveis conforme descrito nas etapas de configuração e descoberta do uso de uma chave de API.

  1. Execute o script a seguir para criar um arquivo de política de alertas:
    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
    
    A política de alertas usa o seguinte filtro PromQL para acionar o alerta:
     (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)
    
    Ela calcula a taxa de aumento e a compara com uma janela anterior. e só aciona o alerta se for mais de 10% maior. Para evitar o acionamento do alerta quando o número total de chamadas é insignificante, ele condiciona o acionamento a ter mais de 50 chamadas de API na janela. Para evitar o cálculo de NaN (exclusão por zero) quando a taxa de 5 minutos anterior era 0, o denominador é substituído por 1 se a taxa da janela anterior for zero.É possível mudar os parâmetros de alerta, como a duração da janela (5m), o limite mínimo (50) ou o limite de aumento de 10% (1.10).Outros parâmetros de política definem que, quando a condição for atingida, o alerta será acionado (duration) e que a condição será verificada a cada 60 segundos (evaluationInterval).
  2. Execute o comando a seguir para criar um tópico do Pub/Sub que será usado para postar notificações de alerta:
    gcloud pubsub topics create api-key-alert-notifications --project=$PROJECT_ID
    
  3. Execute o comando a seguir para criar canais de notificação para alertas que usam o 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)
    
    Você vai usar a variável de ambiente CHANNEL_NAME na etapa de limpeza.
  4. Execute o comando a seguir para criar um novo alerta de monitoramento:
    gcloud monitoring policies create --policy-from-file=alert_policy.json \
      --project=$PROJECT_ID
    
  5. Execute o comando a seguir para conceder permissões ao serviço do Cloud Build e excluir as chaves de API no projeto.
    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"
    
    É possível limitar a função apikeys.admin para manipular apenas uma instância específica das chaves de API. Consulte Condições do IAM para mais detalhes.
  6. Execute o script a seguir para criar um gatilho de build do Cloud Build que exclui a chave de API.
    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. Execute o comando a seguir para criar um gatilho de alerta do Monitoring:
    gcloud builds triggers create pubsub \
      --trigger-config=trigger_config.yaml \
      --project=$PROJECT_ID
    

Agora é possível excluir os arquivos de configuração da política de alertas e do gatilho de build do Cloud Build:

rm alert_policy.json trigger_config.yaml

Como alternativa, é possível configurar essa automação usando o plano do Terraform. Faça o download dos arquivos do Terraform na pasta abnormal-usage-detection do repositório do Google Cloud DevRel. O plano aceita um ID do projeto e um UID da chave de API como parâmetros de entrada e configura os recursos e as configurações que você viu nesta etapa.

7. Limpar

Para evitar cobranças inesperadas na sua conta do Google Cloud, exclua o tópico do Pub/Sub, o gatilho de build do Cloud Build e as políticas de alerta criados durante este exercício.

Execute os comandos a seguir para excluir todos os recursos criados:

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

Neste codelab, você implementou um framework robusto de segurança de ponta a ponta e automação para chaves de API do Google Cloud:

  1. Configurações padrão reforçadas: você criou e restringiu chaves de API para limitar o acesso exclusivamente às APIs necessárias e plataformas confiáveis (como referenciadores HTTP específicos).
  2. Auditoria do inventário de chaves: você analisou os ambientes do projeto para detectar e isolar chaves sem restrições que apresentam um risco de segurança imediato.
  3. Dados de uso analisados: você consultou programaticamente dados de métricas do Cloud Monitoring para criar um perfil do uso histórico de chaves, permitindo restringir chaves com base em rastros de uso verificados.
  4. Mitigação automática de ameaças: você estabeleceu um "disjuntor" reativo ao conectar uma política de alertas do Cloud Monitoring a um tópico do Pub/Sub e a um gatilho de build do Cloud Build. Isso permite excluir automaticamente chaves comprometidas durante picos anormais de tráfego.

Próximas etapas

  • Aplique restrições a todas as suas chaves de API: use o que você aprendeu neste laboratório para detectar todas as chaves de API parcialmente restritas ou sem restrições e aplique restrições de API e de cliente.
  • Configurar um "disjuntor" nas chaves de API: proteja ainda mais suas chaves de API contra uso inesperado configurando a exclusão automática em caso de aumento repentino no consumo. Use os comandos gcloud ou o Terraform mostrado no laboratório. Considere restringir as permissões usando as condições do IAM.
  • Conheça os alertas do Monitoring: saiba mais sobre como configurar alertas usando o serviço do Google Cloud Monitoring.
  • Saiba mais sobre o controle de acesso disponível no Google Cloud: confira as políticas de limite de acesso e a propagação de mudanças de acesso.