Join our Newsletter — 33% off our NHI Course
Home› Guides› Google App Engine Security: Default Service Account, Firewall…
Guide Cloud Security

Google App Engine Security: Default Service Account, Firewall and Legacy Risks

← All guides
By NHI Mgmt Group, edited by Lalit Choda Updated 8 November 2026 13 min read
On this page

Many App Engine applications have run quietly for a decade, still using the project's default service account, open ingress and a runtime that has passed its end of support date. App Engine handles the servers, patching of supported runtimes and TLS for you; the identity each version runs as, who can deploy, which networks and users can reach the app, and when to move off an old runtime are the customer's settings. This guide covers those controls for the App Engine standard environment: service accounts, deployer roles, the App Engine firewall, ingress, Identity-Aware Proxy, secrets, logging and runtime lifecycle planning. It is for platform engineers, application owners and cloud security reviewers who look after long-lived App Engine estates. For newer serverless services on Google Cloud, see the Cloud Run and Cloud Functions Security Guide.

This is an independent guide from NHI Mgmt Group, based on Google Cloud's public documentation as of November 2026. It is not sponsored or reviewed by Google. Product features change, so confirm settings against Google Cloud's current documentation.

Key takeaways

  • Give each version its own service account. Set service_account in app.yaml (or on deploy) to a user-managed account with only the roles the app needs, instead of the default [email protected].
  • Stop automatic Editor grants. Enforce iam.automaticIamGrantsForDefaultServiceAccounts and replace Editor on existing default accounts with narrow roles, checking impact with Policy Simulator first.
  • Deploy rights include actAs. Deploying needs Service Account User on the app's service account, so whoever can deploy can run code as that identity. Grant Deployer plus actAs on one account, not project-wide.
  • Layer firewall, ingress and IAP. The firewall filters by IP range, ingress filters by network origin, and IAP checks the user's identity. Internal apps want all three.
  • Plan runtime moves against published dates. Legacy runtimes (Python 2.7, Java 8, Go 1.11, PHP 5.5) are deprecated and scheduled for decommissioning on 31 January 2027, after which apps may be disabled.

How identity and access work in App Engine

App Engine involves three identities: the people and pipelines that administer and deploy, the service account each version runs as, and the users or services that call the app. All are Google Cloud IAM principals except anonymous internet callers.

IdentityDefaultWhat it reachesRecommended setting
Runtime identityApp Engine default service account [email protected], created on first useEvery API the account's roles allow; depending on organisation policy it may hold Editor on the projectA user-managed service account per app or version, set with service_account in app.yaml
DeployerWhoever holds App Engine Admin or Editor-type rolesNew versions, traffic, settingsApp Engine Deployer plus Service Account User on the one runtime account
CallerAnyone on the internet (ingress accepts all origins by default)Every public URL, including version-specific -dot- URLsFirewall rules, ingress setting and IAP for internal apps

Per-version service accounts have three documented rules: the account must be in the same project, it can be set only when deploying a new version, and a value given on the gcloud command line takes precedence over app.yaml. Use that to move an app off the default identity one version at a time: deploy a new version with the user-managed account, test it with a version-specific URL, then migrate traffic.

For organisations created after 3 May 2024, Google enforces iam.automaticIamGrantsForDefaultServiceAccounts by default, so new default accounts no longer receive Editor automatically. Older organisations should enforce it themselves and then right-size existing grants. See the Google Cloud IAM and Service Accounts Guide and the Google Cloud Organization Policy Guide.

Admin roles and privileged access

App Engine has a fine-grained set of predefined roles. Two titles are reused for different role IDs, so always work from the ID.

Role IDTitleWhat it allowsUse for
roles/appengine.adminApp Engine Service AdminFull access to App Engine resourcesBreak-glass platform administrators
roles/appengine.appAdminApp Engine AdminAll application configuration, traffic, versions, instances, dispatch rules, disabling the appPlatform team
roles/appengine.deployerApp Engine DeployerRead configuration, create versions, delete versions not receiving trafficCI/CD service accounts
roles/appengine.serviceAdminApp Engine Service AdminService and version settings, traffic splits and migration; no new deploys or application-level changesRelease managers
roles/appengine.appViewerApp Engine ViewerRead-only configuration and settingsAuditors, support
roles/appengine.codeViewerApp Engine Code ViewerViewer rights plus deployed source codeOnly where source review is needed
roles/appengine.appCreatorApp Engine CreatorCreate the App Engine application for a projectProject provisioning only

Google's recommended deploy-only setup is App Engine Deployer plus Service Account User (roles/iam.serviceAccountUser) on the app's service account, with Cloud Build Editor and Storage Object Admin added when deploying through gcloud. Treat that bundle as privileged:

  • Scope actAs to one account: grant Service Account User on the specific runtime service account, never at project level, or a deployer can run code as any service account in the project.
  • Split deploy from traffic: Deployer creates versions but cannot migrate traffic; Service Admin moves traffic but cannot deploy. Giving them to different identities adds a review step before code takes production traffic.
  • Restrict Code Viewer: deployed source often includes configuration; grant it only where needed.
  • Protect the firewall: firewall changes need App Engine Admin, Editor or Owner. Keep basic roles out of production projects so firewall changes stay with the platform team.

Integrations, API tokens and service accounts

Long-lived App Engine apps often accumulate non-human credentials: service account keys added years ago, API keys in configuration, and default credentials used to reach other projects. Bring each one under a named identity.

  • Calling Google APIs: use the version's service account through Application Default Credentials. There is no need for key files inside the deployment. If an old app ships a JSON key, replace it; see the guide to replacing Google Cloud service account keys.
  • Secrets: environment variables in app.yaml are part of the deployed configuration and readable by anyone who can view it. Store passwords and tokens in Secret Manager, grant roles/secretmanager.secretAccessor on each secret to the runtime service account, and read them at start-up. See the Secrets Management Guide.
  • Pub/Sub push into App Engine: use an authenticated push subscription. For an app behind IAP, Google documents granting the push auth service account the IAP-secured Web App User role and using the IAP client ID as the token audience. See Google Cloud Pub/Sub Security.
  • Outbound calls to private systems: by default only traffic to private IP addresses goes through your VPC (Direct VPC egress or a Serverless VPC Access connector). Set egress to all-traffic with Cloud NAT and static IPs when partners allowlist your source address, because default outbound traffic uses a shared regional pool.
  • CI/CD: run deployments from a dedicated service account, federated from your CI system with Workload Identity Federation rather than a stored key. See the Cloud Workload Identity Guide.

Protecting the front door

ControlWhat it checksDefaultKey settings
App Engine firewallSource IP rangeA default rule at priority 2147483647 covering all IPs, evaluated lastRules at priority 1 to 2147483646 with allow or deny (deny returns 403); gcloud app firewall-rules create, test-ip, list
Ingress settingNetwork origin of the requestAccepts traffic from all originsRestrict to internal traffic, or internal plus Cloud Load Balancing, for apps fronted by a load balancer
Identity-Aware ProxyThe caller's Google identityOffgcloud iap web enable --resource-type=app-engine; grant roles/iap.httpsResourceAccessor to groups
HTTPSTransportHTTPS available on appspot.com URLsManaged SSL certificates for custom domains; set secure: always on handlers to redirect HTTP

For internal apps, turn on IAP and grant access to groups only; Owner and Editor do not automatically pass IAP, which keeps administration and application access separate. Set the firewall default rule to deny once explicit allow rules cover the ranges you need (for example a corporate range during testing, or only the ranges a WAF forwards from). Remember version-specific URLs (VERSION-dot-SERVICE-dot-PROJECT_ID.REGION_ID.r.appspot.com): firewall, ingress and IAP apply to them too, which is why they are the right layer rather than in-app checks on the default URL. See the Identity-Aware Proxy Guide.

For the standard environment, Google's security overview positions the App Engine firewall, ingress controls and IAP as the network boundary for the app. Place VPC Service Controls perimeters around the data services the app calls, such as Cloud Storage and BigQuery, and allow the app's service account through them. See the VPC Service Controls Guide.

Logging and detection

App Engine writes Admin Activity audit logs under appengine.googleapis.com, request logs for every HTTP request, and application logs. Route all three to a central sink; see the Google Cloud Audit Logs and Log Sinks Guide.

EventAudited methodAlert on
New or changed versionapps.services.versions.create, apps.services.versions.patchDeploys by anyone other than the CI service account, or a change of runtime service account
Firewall changeapps.firewall.ingressRules.create, .patch, .batchUpdate, .deleteAny change to the default rule or a broad allow range
Application settingsapps.patchChanges to serving status or application-level settings
IAM on runtime accountSetIamPolicy on the service account (IAM service)New Service Account User or Token Creator grants
Service account key creationCreateServiceAccountKey (IAM service)Any new key for an App Engine runtime account

In request logs, watch for traffic to non-serving versions by URL, spikes of 403s from the firewall (blocked traffic is not billed, so the rule is doing its job), and unusual user agents on admin paths. Map detections to MITRE ATT&CK T1078.004 Cloud Accounts for misuse of the runtime identity. Web Security Scanner, run by a project owner from the console, crawls the app for common web vulnerabilities and is a useful periodic check for legacy apps.

Metrics that show it is working

  • Share of serving versions running as user-managed service accounts (target: all).
  • Default App Engine service accounts still holding Editor (target: zero).
  • Principals with project-level Service Account User (target: zero).
  • Internal apps with IAP on and a restrictive firewall default (target: all).
  • Serving versions on runtimes past end of support, with a dated migration plan for each.
  • Service account keys for App Engine runtime accounts (target: zero).

Hardening baseline

Apply in this order, testing each change on a non-production version with a version-specific URL before migrating traffic. Rollback is a traffic migration back to the previous version, so keep it deployed until the new one is proven.

  1. Inventory: list services, serving versions, runtimes, the service account each version uses, firewall rules, ingress settings and IAP status per project.
  2. Enforce the organisation policy: turn on iam.automaticIamGrantsForDefaultServiceAccounts so no new default account gets Editor.
  3. Move versions to user-managed service accounts: create an account per app with the roles it needs, deploy a new version with service_account, test, migrate traffic.
  4. Right-size the default account: once no serving version uses it, remove Editor (check with Policy Simulator first), and then disable it if nothing else depends on it.
  5. Tighten deployers: give CI Deployer plus Service Account User on the one runtime account; remove project-level actAs and basic roles.
  6. Close the front door: add explicit firewall allow rules, set the default to deny where the audience is known, restrict ingress, and turn on IAP for internal apps.
  7. Move secrets: move credentials from app.yaml and source into Secret Manager.
  8. Plan runtime migrations: map every version to the runtime support schedule (below) and schedule moves well before deprecation.
  9. Log and alert: route logs centrally and alert on the events above.

Runtime lifecycle and legacy apps

Google publishes a support schedule for each runtime and defines three stages. At end of support, Google stops applying security updates to runtime components, apps keep serving traffic, and new deploys and updates on that runtime are blocked (an organisation policy can re-enable deploys in some cases); in-app notifications start 90 days before. At deprecation, existing workloads still run, but creation, redeployment and configuration updates are blocked and the re-enable option is removed. At decommissioning, apps still using the runtime may be disabled without further notice.

Runtime (examples)End of supportStatus in the schedule (checked 8 Nov 2026)
Python 2.7, Java 8, Go 1.11, PHP 5.5 (legacy)January 2024Deprecated 31 January 2026; decommissioning scheduled 31 January 2027
Python 3.104 October 2026Past end of support
Node.js 2030 April 2026Past end of support
PHP 8.231 December 2026Upcoming
Node.js 2230 April 2027Upcoming
Python 3.1124 October 2027Upcoming

Google notes that key dates may move, so confirm against the live schedule. Legacy apps that rely on bundled services usually need code changes as well as a runtime bump; Google publishes migration guides per legacy runtime. A move is also a good moment to reconsider the platform: many teams move such workloads to Cloud Run while they are changing code anyway. Track unsupported components under NIST SP 800-53 SA-22.

Framework mapping

Control areaApp Engine settingNIST SP 800-53 Rev 5
Least privilegeUser-managed runtime accounts, Deployer role, scoped actAsAC-6, AC-2
Boundary protectionFirewall rules, ingress settingsSC-7
Access enforcementIdentity-Aware ProxyAC-3
Authenticator managementSecret Manager, no key filesIA-5
Unsupported componentsRuntime lifecycle planningSA-22
Transport protectionHTTPS, managed certificates, secure: alwaysSC-8
AuditAdmin Activity and request logsAU-2, AU-6

Common misconfigurations

  • Every version on the default service account: a bug in any handler then acts with the default account's project roles. Assign user-managed accounts per version.
  • Project-level Service Account User for the CI pipeline: the pipeline can then deploy as any account in the project. Grant it on the runtime account only.
  • Firewall default left at allow for internal tools: an internal app is then reachable from anywhere. Add allow rules for known ranges and set the default to deny, plus IAP.
  • Secrets in app.yaml: anyone with Viewer-type access to the configuration can read them. Use Secret Manager.
  • Old versions left serving on version URLs: a non-default version can still be reached directly. Delete versions that are not needed and keep only a rollback candidate.
  • Waiting for the runtime deadline: once a runtime is deprecated, even a configuration fix cannot be deployed. Migrate before deprecation.

Practitioner checklist

  • Enforce iam.automaticIamGrantsForDefaultServiceAccounts and remove Editor from App Engine default service accounts.
  • Run every serving version as a user-managed service account set through service_account.
  • Grant deployers App Engine Deployer plus Service Account User on the one runtime account, federated from CI.
  • Configure firewall allow rules and a deny default where the audience is known, restrict ingress, and turn on IAP for internal apps.
  • Move credentials from app.yaml and source to Secret Manager.
  • Map every version to the runtime support schedule and migrate legacy runtimes before 31 January 2027.
  • Delete unused versions and keep one rollback candidate.
  • Alert on version deploys, firewall changes, actAs grants and key creation.

Standards and references

Related NHI Mgmt Group resources: Cloud Run and Cloud Functions Security Guide · Identity-Aware Proxy Guide · Google Cloud IAM and Service Accounts Guide · Google Cloud Security Guide

Free weekly newsletter

Subscribe to the NHI & AI Identity Journal

The latest on NHI and Agentic AI security – articles, research, breaches, news and events every week.

Bonus 33% off our NHI Course when you subscribe.

NHIMG Editorial Note
Researched and written by the NHI Mgmt Group editorial team using AI tools, under the editorial direction of Lalit Choda. Facts are drawn from the sources listed on this page and checked by our automated quality process. Last updated 8 November 2026. Spotted an error? Use our contact page.
NHI Mgmt Group, the independent authority on Non-Human Identity, IAM and Agentic AI security. nhimg.org