API Gateway Backend Security And Rate Limiting
GoogleOfficialPublished by Google
- Skill
- Tool integration
- Cloud and DevOps
- Apache-2.0
- Low risk
- Has scripts
AutoGineer summary
Written by AutoGineer from the skill’s own files, not by the author
This skill provides a structured workflow for securing backend services behind Google Cloud API Gateway. It covers the implementation of API key and JWT authentication, the configuration of dedicated service accounts for secure backend invocation, and the setup of per-project rate limits using OpenAPI 2.0 and 3.0 specifications. The skill includes a validation loop to prevent quota-related errors and ensures zero-downtime transitions when locking down backend services.
What it does
- Configures API key and JWT authentication for API Gateway endpoints.
- Implements secure gateway-to-backend communication using dedicated service accounts.
- Sets per-project request quotas and rate limits via OpenAPI definitions.
- Provides a validation script to check quota metrics before deployment.
- Guides users through a zero-downtime lockdown process for backend services.
- Supports configuration for both OpenAPI 2.0 and 3.0.x specifications.
When to use it
- When you need to secure Cloud Run or Cloud Functions backends behind an API Gateway.
- When implementing per-project rate limiting or request quotas.
- When migrating to a more secure backend authentication model without causing downtime.
- When diagnosing HTTP 429 or HTTP 500 Service Control Quota errors.
- When configuring authentication for gateways with Model Context Protocol (MCP) enabled.
Advantages
- Ensures zero-downtime transitions for production API security updates.
- Prevents common configuration errors through a pre-deployment validation loop.
- Promotes least-privilege access by using dedicated service accounts for backends.
- Provides clear separation between client-facing authentication and backend security.
Usage examples
- “How do I secure my Cloud Run backend behind API Gateway?”
- The agent will guide you through creating a dedicated service account, granting it the run.invoker role, and updating your API config to use this account for backend authentication.
- “I am getting HTTP 500 errors when updating my API Gateway quotas. How do I fix this?”
- The agent will instruct you to run the quota validation script to identify misconfigured metrics and ensure your new API config maintains compatibility with existing gateways.
Install
Download the skill as a ZIP:
https://mp-staging.autogineer.com/agent-skills/google/api-gateway-backend-security-and-rate-limiting/downloadUnzip it into the cross-client skills folder of your project:
mkdir -p .agents/skills && unzip api-gateway-backend-security-and-rate-limiting.zip -d .agents/skills
Documentation by Google
API Gateway Backend Security and Rate Limiting
This skill configures client authentication, gateway-to-backend authentication, and per-project rate limits (quotas) for Google Cloud API Gateway across OpenAPI 2.0 (swagger: "2.0") and OpenAPI 3.0.x (openapi: 3.0.4), including gateways with Model Context Protocol (MCP) enabled (Public Preview).
Attribution
MUST READ: Before executing any gcloud, REST API, or MCP command, you
MUST read Usage Attribution. For commands executed
directly in the terminal (never in generated scripts, Terraform, or user code),
prefix gcloud with
CLOUDSDK_METRICS_REQUEST_ATTRIBUTION="agent-skills/1.0 (skill:api-gateway-backend-security-and-rate-limiting)"
and append agent-skills/1.0 (skill:api-gateway-backend-security-and-rate-limiting) to User-Agent headers.
Prerequisites
Install the Google Cloud CLI and Python 3.10+ YAML parser:
Install or update the Google Cloud SDK.
Install
PyYAMLfor the quota metric validation script:pip install "PyYAML>=6.0,<7.0"
Authenticate your environment:
Local CLI session:
gcloud auth loginApplication Default Credentials (SDKs):
gcloud auth application-default loginService account key file (if required by CI): set
GOOGLE_APPLICATION_CREDENTIALS={key_file_path}
Select or create a project, verify billing, and pick a supported gateway location:
Select an existing project (
gcloud config set project {project_id}) or create one (gcloud projects create {project_id}as an escape hatch).Verify that an active billing account is linked to
{project_id}(required even when staying within the API Gateway pricing free tier).Use
us-central1as the default--locationfor API Gateway commands. For the other supported regions, see API Gateway deployment model.
Enable required Google Cloud APIs:
gcloud services enable \ apigateway.googleapis.com \ servicemanagement.googleapis.com \ servicecontrol.googleapis.com \ iam.googleapis.com \ apikeys.googleapis.com \ --project={project_id}API Gateway does not need the Cloud Run API. If the backend runs on Cloud Run, that API is already enabled in the backend's project.
Verify required IAM roles:
To manage API Gateway resources and enable services:
roles/apigateway.adminandroles/serviceusage.serviceUsageAdminTo create the gateway service account and attach it to an API config:
roles/iam.serviceAccountAdminandroles/iam.serviceAccountUserTo manage API keys in consumer projects:
roles/serviceusage.apiKeysAdminFor the gateway service account to invoke the backend:
roles/run.invoker(Cloud Run or 2nd gen functions) orroles/cloudfunctions.invoker(1st gen functions)
Decision Matrix: Client Authentication, Backend Security, and Quotas
Select the layer that matches the security requirement:
| Goal | Mechanism to Configure | Key Constraint | Detailed Reference |
|---|---|---|---|
| Identify the calling consumer project for quotas and billing | API key (x-api-key header convention; key query parameter escape hatch) | NEVER rely on an API key alone to authenticate end-user identity. Rationale: API keys identify a Google Cloud project rather than a user, and clients can extract them. | Client Authentication |
| Authenticate end users or calling services | JWT (oauth2 scheme with x-google-issuer / x-google-jwks_uri in OAS 2.0, or x-google-auth in OAS 3.x) | Operation-level security overrides root security. Include api_key: [] and the JWT scheme in the same security requirement object when an endpoint needs both user identity and quotas. | Client Authentication |
| Block direct calls to the backend service | Dedicated gateway service account (--backend-auth-service-account) + roles/run.invoker + backend --no-allow-unauthenticated | Roll out the gateway config with --backend-auth-service-account BEFORE setting --no-allow-unauthenticated on a live backend to avoid 403 downtime. | Backend Security |
Rate limit requests per consumer project (1/min/{project}) | x-google-management (OAS 2.0) or x-google-api-management (OAS 3.x) + x-google-quota | NEVER rename or remove a quota metric when creating a new API config while any gateway of the API runs an older config referencing that metric. Rationale: Creating the config immediately overwrites API-wide quotas and causes HTTP 500 Failed to call Service Control Quota on older gateways. | Quotas and Rate Limiting |
Secure MCP tools/list and tools/call on /mcp (Public Preview) | x-google-api-management.mcp.tools-list.security (exactly one JWT or API key scheme) + operation security and x-google-mcp-tool: false | x-google-mcp-tool: false hides an operation from MCP only; the underlying REST route remains live unless secured or removed. | MCP Traffic Security |
Execution Workflow and Validation Loop
Follow this zero-downtime sequence when authoring or updating an API Gateway security or quota configuration:
Create the gateway service account and grant backend invoker permissions:
Follow Steps 1–3 of Backend Security to create
{gateway_sa_name}and request human approval before grantingroles/run.invokeron{backend_service}.Update backend handler code to decode verified user claims from
X-Apigateway-Api-Userinfo(base64url-encoded JSON) instead ofAuthorization.
Author the OpenAPI authentication and quota definitions:
Use the OpenAPI 2.0 or OpenAPI 3.0.x templates and provider tables in Client Authentication and Quotas and Rate Limiting.
If the specification enables MCP (
x-google-api-management.mcp), configure exactly one JWT or API key scheme ontools-list(also list a JWT scheme in the rootsecuritylist), and review operation opt-outs using MCP Traffic Security.
Run the quota metric validation loop BEFORE running
api-configs create:If neither the active specs nor
{candidate_openapi_spec}define quota metrics (x-google-management.metricsorx-google-api-management.metrics), skip this step.Request human approval before creating an API config that defines or modifies quotas, because
api-configs createimmediately replaces quota definitions across all gateways of the API.By default, run
scripts/check_quota_metrics.pyagainst all active gateways deployed for{api_id}in{project_id}:python3 scripts/check_quota_metrics.py \ --spec={candidate_openapi_spec} \ --project={project_id} \ --api={api_id}Escape hatch for offline environments without
gcloudaccess (pass--baseline-specfor every config currently served by a gateway of the API):python3 scripts/check_quota_metrics.py \ --spec={candidate_openapi_spec} \ --baseline-spec={previous_openapi_spec} \ --dry-runIf
scripts/check_quota_metrics.pyexits with code1(status: "FAIL"), add the missing metrics and limits back to{candidate_openapi_spec}, move eachx-google-quotalisted inignored_quota_extensionsinto the operations it applies to, and re-run the script until it exits with code0(status: "PASS"). If the user wants to remove a limit on purpose, confirm the removal with the user, because it removes that limit from every gateway of the API. Ifskipped_configsis not empty, tell the user that the script did not inspect those API configs (for example, gRPC configs), and check their quota metrics and limits manually. If it exits with code2, fix the problem printed to stderr: the CLI arguments,gcloudauthentication, or an API config that the script cannot inspect.
Create the API config, update the gateway, enable the managed service, and lock down the backend:
Follow Steps 4–5 of Backend Security to run
gcloud api-gateway api-configs createandgcloud api-gateway gateways update(request human approval before updating a production gateway), enable the API'smanagedServicein consumer projects (Client Authentication), and then restrict{backend_service}with--no-allow-unauthenticated.Verify that direct calls to the backend
*.run.appURL return403, unauthenticated calls to the gatewaydefaultHostnamereturn401, and authenticated calls return200.
Pre-Deployment Checklist
[ ] Dedicated
{gateway_sa_name}is grantedroles/run.invoker(orroles/cloudfunctions.invoker), and--no-allow-unauthenticatedis applied after the gateway config is active.[ ] Backend code decodes
X-Apigateway-Api-Userinfofor user claims.[ ] Security enforcement does not depend solely on a load balancer or Google Cloud Armor in front of the gateway, because the gateway's
defaultHostname(*.gateway.dev) cannot be disabled.[ ] Every quota-enforced operation requires an API key (
api_key: []), and the API'smanagedServiceis enabled and allowed on the API key in each consumer project.[ ]
python3 scripts/check_quota_metrics.pyreturnsstatus: "PASS"(exit code0) against active gateway configs or all baseline specs beforeapi-configs create.[ ] If MCP is enabled,
x-google-api-management.mcp.tools-list.securitynames exactly one JWT or API key scheme (a JWT scheme is also in the rootsecuritylist), and administrative endpoints are secured on REST in addition tox-google-mcp-tool: false.
Resource Cleanup
To avoid ongoing charges when tearing down a test or staging environment, request human approval and delete the gateway, all API configs, the API, and the service account in dependency order:
gcloud api-gateway gateways delete {gateway_id} --location={region} --project={project_id}
gcloud api-gateway api-configs delete {config_id} --api={api_id} --project={project_id}
gcloud api-gateway apis delete {api_id} --project={project_id}
gcloud iam service-accounts delete {gateway_sa_name}@{project_id}.iam.gserviceaccount.com --project={project_id}Files
- ATTRIBUTION.mdAdded by AutoGineer910 B
- LICENSELicence file added by AutoGineer11.1 KiB
- SKILL.md11.2 KiB
- references/attribution.md1.9 KiB
- references/backend-security.md7.8 KiB
- references/client-authentication.md9.0 KiB
- references/mcp-traffic-security.md9.5 KiB
- references/quotas-and-rate-limiting.md7.5 KiB
- scripts/check_quota_metrics.pyScript15.7 KiB
references/client-authentication.md
Client Authentication Reference (API Keys and JWT)
API Key Configuration: Lines 9-36
API Key Restrictions and Managed Service: Lines 38-58
JWT Configuration in OpenAPI 2.0 and 3.x: Lines 60-111
Identity Provider JWT Settings Table: Lines 113-122
Security Composition and Override Rules: Lines 124-136
API Key Configuration
Use an API key to identify the calling Google Cloud consumer project for quota enforcement, billing, and usage tracking. Do not use an API key alone to authenticate end-user identity. Rationale: An API key identifies a Google Cloud project rather than a user or service principal, and callers can extract API keys from client applications.
Pass the API key in the x-api-key HTTP header as the standard convention. Use the key query parameter only as an escape hatch when the client cannot set custom HTTP headers. Rationale: URL query parameters appear in proxy logs, browser history, and access logs.
OpenAPI 2.0 (securityDefinitions)
securityDefinitions:
api_key:
type: "apiKey"
name: "x-api-key"
in: "header"OpenAPI 3.x (components.securitySchemes)
components:
securitySchemes:
api_key:
type: apiKey
name: x-api-key
in: headerReference: Authenticate with an API key
API Key Restrictions and Managed Service
Before a consumer project can call an API with an API key, enable the managed service of the API in that consumer project and allow it on the API key:
Inspect the API to find its
managedServicevalue (note that a newly created managed service can take up to 30 minutes to appear in the Google Cloud API Library):gcloud api-gateway apis describe {api_id} --project={project_id} --format="value(managedService)"Enable the managed service in the consumer project (
{consumer_project_id}):gcloud services enable {managed_service_name} --project={consumer_project_id}Add API restrictions and application restrictions to every production API key (request human approval before creating or updating production API keys). If a restricted API key gets HTTP
403because its API restrictions do not include the API, add{managed_service_name}to the key's allowed API targets:gcloud services api-keys update {key_id} \ --api-target=service={managed_service_name} \ --project={consumer_project_id}If you restrict an API key by HTTP referrer (website), you MUST include the URL scheme (
https://{domain}/*instead of{domain}/*). Rationale: Unrestricted API keys can be used against any enabled API in the project, and referrer entries without a scheme fail validation.
Reference: Restrict API keys
JWT Configuration in OpenAPI 2.0 and 3.x
Use JSON Web Tokens (JWTs) to authenticate end users or calling service accounts.
You MUST specify
x-google-jwks_uri(OpenAPI 2.0) orx-google-auth.jwksUri(OpenAPI 3.x) on every JWT security definition. Rationale: API Gateway requires the public key set URI to verify the signature of incoming JWTs and caches the JWKS for 5 minutes (publish rotated signing keys at least 5 minutes before signing traffic).Give each JWT security scheme a unique
issuervalue. Rationale: API Gateway routes token verification by matching theissclaim to a unique security definition.Required JWT claims are
iss,sub,aud,iat, andexp. Theaudclaim cannot be an internal address or an IPv4/IPv6 address.audiences(x-google-audiencesin OpenAPI 2.0) is optional. If omitted, API Gateway accepts JWTs whoseaudclaim matcheshttps://{service_name}, where{service_name}is the API GatewaymanagedServicename (hostin OpenAPI 2.0 orservers.urlwithx-google-endpointin OpenAPI 3.x). In OpenAPI 2.0, specify multiple audiences as a single comma-separated string ("aud1,aud2"); in OpenAPI 3.x, specify a YAML list.API Gateway validates JWT claims and signatures, but does not check IAM permissions of a calling service account and ignores OAuth
scopesdeclared in the OpenAPI document.
OpenAPI 2.0 JWT Definition
securityDefinitions:
service_jwt:
authorizationUrl: ""
flow: "implicit"
type: "oauth2"
x-google-issuer: "{service_account_email}"
x-google-jwks_uri: "https://www.googleapis.com/robot/v1/metadata/x509/{service_account_email}"
x-google-audiences: "https://{managed_service_name}"OpenAPI 3.x JWT Definition (x-google-auth)
In OpenAPI 3.x, place issuer, jwksUri, audiences, and jwtLocations inside x-google-auth and remove the x-google- field prefixes used in OpenAPI 2.0:
components:
securitySchemes:
service_jwt:
type: oauth2
flows:
implicit:
authorizationUrl: ""
scopes: {}
x-google-auth:
issuer: "{service_account_email}"
jwksUri: "https://www.googleapis.com/robot/v1/metadata/x509/{service_account_email}"
audiences:
- "https://{managed_service_name}"
jwtLocations:
- header: X-Forwarded-Authorization
valuePrefix: "Bearer "
- query: auth_tokenBy default, API Gateway reads JWTs from Authorization: Bearer , X-Goog-Iap-Jwt-Assertion, or the access_token query parameter. Configure jwtLocations (header with optional valuePrefix, or query) only when the client sends the token in a custom header or query parameter.
References:
Identity Provider JWT Settings Table
| Identity Provider | issuer (x-google-issuer) | jwksUri (x-google-jwks_uri) | audiences (x-google-audiences) |
|---|---|---|---|
| Firebase Authentication | https://securetoken.google.com/{project_id} | https://www.googleapis.com/service_accounts/v1/metadata/x509/[email protected] | {project_id} |
| Auth0 | https://{your_auth0_domain}/ (trailing slash required) | https://{your_auth0_domain}/.well-known/jwks.json | Auth0 API Identifier or Client ID |
| Okta | https://{your_okta_domain}/oauth2/default | https://{your_okta_domain}/oauth2/default/v1/keys | Okta Client ID or Audience |
| Google ID token (user sign-in with an OAuth client) | https://accounts.google.com | https://www.googleapis.com/oauth2/v3/certs | OAuth 2.0 Client ID |
Google ID token for a service account (gcloud auth print-identity-token --impersonate-service-account={caller_sa_email} --audiences={jwt_audience}) | https://accounts.google.com | https://www.googleapis.com/oauth2/v3/certs | The same {jwt_audience} value. Any Google identity can mint such a token, so check the email claim in the backend (X-Apigateway-Api-Userinfo), or use the self-signed row to accept only one service account. |
Service account self-signed JWT (gcloud iam service-accounts sign-jwt) | {service_account_email} | https://www.googleapis.com/robot/v1/metadata/x509/{service_account_email} | https://{managed_service_name} |
Security Composition and Override Rules
Operation-level security replaces root-level security: If an operation declares its own security block with only a JWT scheme (- service_jwt: []), it overrides the document-level security block and removes any root api_key requirement. To preserve per-project quota tracking on an operation that overrides security, you MUST include api_key: [] in the same security requirement object (- api_key: [] and service_jwt: [] together).
| Requirement Pattern | OpenAPI Syntax | Supported in API Gateway |
|---|---|---|
| Require API key AND JWT (conjunction) | Single list item with two keys: - api_key: [] and service_jwt: [] in the same object | Yes. Use this pattern when an operation requires both user authentication and consumer project quota tracking. |
| Require JWT scheme A OR JWT scheme B (disjunction) | Two list items: - jwt_a: [] followed by - jwt_b: [] | Yes. Each scheme must have a distinct issuer. |
| Require JWT scheme A AND JWT scheme B (conjunction) | Single list item with two OAuth2 schemes | No. API Gateway does not support conjunctions of multiple OAuth2 schemes unless the additional scheme is an API key. |
| Require API key OR JWT (disjunction) | Two list items where one is an apiKey scheme | No. API Gateway rejects logical OR security requirements between an API key and another scheme. |
| Optional API key | - {} alongside - api_key: [] | Yes (special-case exception for API keys only). Do not use - {} to make OAuth2/JWT optional. |
Reference: OpenAPI 3.x feature limitations
Requirements and compatibility
Works with: Claude Code, Claude apps, OpenAI Codex, GitHub Copilot, Cursor, Gemini CLI, Kiro, OpenCode, Goose, Amp, Roo Code, JetBrains Junie, Factory Droid, Devin (ex-Windsurf), Mistral Vibe, OpenHands, Letta
“Works with” means the tool reads the open Agent Skills format; a skill written for one tool may use features others lack.
Needs: Needs an API key, Needs a command-line tool, Needs Python
Security
What our scanner noticed· Low risk
- Instructions that use the network
- Scripts that your agent may run
This skill includes scripts that your agent may run. Read them before you use it.
A static scan is not a guarantee. Skills are third-party content: review a skill before you let an agent use it.
Attribution and licence
- Published by
- Publisher
- Google (Official)
- Source
- google/skills · skills/cloud/api-gateway-backend-security-and-rate-limiting · commit 2194d3b
- Licence
- Apache License 2.0 (redistribution allowed)
- LICENSE (added by AutoGineer from LICENSE)
- ATTRIBUTION.md (written by AutoGineer)
- Synced
AutoGineer is not affiliated with or endorsed by Google.
Download ZIP
The ZIP holds the skill’s files, its licence files and an ATTRIBUTION.md. Download api-gateway-backend-security-and-rate-limiting.zip