Pricing

Why Your IT Team Won't Whitelist Google Apps Script IPs, and How to Connect Your Database Without Opening the Firewall

MySQLPostgreSQLSQL ServerRedshiftGoogle Sheet
JW
James Whitfield

Google does not publish stable Apps Script egress IPs. IT teams refuse to whitelist massive shared Google CIDR ranges. Here are five practical solutions for connecting your database to Google Sheets without touching the firewall.

You have written the Apps Script. It fetches data from your internal database, formats it, and drops it into a Google Sheet. It works perfectly in your local development environment with a VPN. You deploy it. It fails. You ask IT to whitelist the IP addresses. They say no.

This is not an unusual story. It is, in fact, one of the most common dead ends in the Google Sheets automation space, and it has a structural cause that is unlikely to change.

This guide explains why the problem exists, why IT's refusal is technically correct, and what the five practical solutions look like, including their tradeoffs.

Why Google Apps Script Has No Stable Egress IPs

Google Apps Script runs on Google's shared infrastructure. When your script executes and makes an outbound HTTP request or database connection, that request originates from one of Google's data center IP addresses, but Google does not guarantee which one.

Google publishes its IP ranges via a JSON endpoint:

Code
https://www.gstatic.com/ipranges/goog.json

As of mid-2025, this list contains over 5,000 individual IP ranges, covering hundreds of thousands of individual addresses. These ranges are shared across all Google services: Google Search crawlers, YouTube CDN, Google Cloud customer workloads, Gmail servers, and yes, Apps Script executions.

There is no sub-list for "Apps Script only" IPs. Google has never published one, and there is no indication they plan to. The runtime is built on a multi-tenant infrastructure that does not support static egress by design.

Some developers have attempted to infer a smaller subset of IPs by running scripts repeatedly and logging the originating IP. The results are inconsistent. The IPs change between executions, between days, and presumably between geographic regions depending on where Google decides to run your script.

The core problem: You cannot give IT a bounded, stable list of IP addresses that uniquely identify Apps Script traffic, because that list does not exist.

Why IT Teams Refuse the Whitelist Request

When a developer asks IT to whitelist "Google's IPs" so that Apps Script can reach an internal database, the request looks like this from a security perspective:

  1. "Whitelist 5,000+ IP ranges that cover hundreds of thousands of addresses."
  2. "These IPs are shared with every other Google service and every Google Cloud customer globally."
  3. "Any traffic from any of those addresses will be permitted to reach our internal database."

This is not a firewall rule. It is an open door. Any Google Cloud customer who spins up a VM in the right region could potentially route traffic through one of those IPs.

Security-conscious IT teams are not being obstructionist when they refuse. They are doing their job. Whitelisting Google's full CIDR range creates an attack surface that is impossible to audit or monitor. You would have no way of knowing whether a connection came from your Apps Script or from an unrelated party.

Even if IT were willing, the whitelist would need to be updated regularly as Google adds or changes IP ranges. Automation of that update is possible but adds operational overhead and creates a brief exposure window every time ranges change.

The result: The standard Apps Script approach to database connectivity is architecturally incompatible with reasonable firewall policies. The solution has to come from a different direction.

Solution 1: Connector with Fixed Egress IPs

The cleanest solution for most teams is to use a data connector that provides fixed, published egress IPs, and route all database traffic through that connector rather than through Apps Script directly.

How it works:

  1. The connector (a third-party service, not Google) establishes the connection to your database from its own infrastructure.
  2. The connector's infrastructure has a fixed, documented set of egress IP addresses.
  3. IT whitelists those specific IPs: a small, stable list, typically two to four addresses for redundancy.
  4. Your Google Sheet queries the connector, which queries the database on your behalf and returns the results.

The key difference: Instead of asking IT to whitelist "Google," you are asking IT to whitelist "four specific IP addresses owned by a specific company with a specific business purpose." That is a request a security team can evaluate and approve.

What to ask your connector vendor:

  • What are your fixed egress IP addresses?
  • Do these IPs change? Under what circumstances?
  • Do you notify customers in advance of IP changes?
  • Can you provide documentation for our security team?

Any serious connector vendor will have clear answers to all of these. If they do not, treat that as a red flag.

Solution 2: Intermediate API Proxy

If you want to keep the Apps Script architecture, you can insert a controlled API layer between the script and the database. The API runs on infrastructure you control, with a fixed IP, and exposes only the specific data endpoints your script needs.

Architecture:

Code
Apps Script → Your API (fixed IP, you control it) → Internal Database

How to build it:

  1. Spin up a small server on a cloud provider (AWS EC2, Google Cloud VM, DigitalOcean Droplet, etc.) with a static IP. Static IPs on these platforms cost around $4–$8/month.
  2. Deploy a lightweight API (Python/FastAPI, Node.js/Express, or similar) that accepts authenticated requests and queries your database.
  3. IT whitelists the static IP of your server.
  4. Your Apps Script sends requests to your API, not directly to the database.

Authentication between Apps Script and your API: Use a long, randomly generated API key stored in Apps Script's Properties Service (not hardcoded in the script). The API validates the key on every request.

javascript
// In Apps Script
const API_KEY = PropertiesService.getScriptProperties().getProperty('API_KEY');

function fetchData() {
  const response = UrlFetchApp.fetch('https://your-api.example.com/data', {
    headers: { 'Authorization': 'Bearer ' + API_KEY }
  });
  return JSON.parse(response.getContentText());
}

Strengths:

  • You own and control the proxy, no third-party dependency.
  • Fixed IP that you control.
  • You can log and monitor every request.
  • The API can enforce query limits and data access controls.

Limitations:

  • Requires you to build and maintain a server and API.
  • Adds operational overhead (server updates, certificate renewals, monitoring).
  • A single-point failure if the server goes down.

When to use it: You have engineering resources, want full control, and do not want to depend on a third-party connector.

Solution 3: Google Cloud SQL with Auth Proxy

If your database is a new deployment (or you have the ability to migrate), hosting it in Google Cloud SQL and using the Cloud SQL Auth Proxy is a well-supported approach that sidesteps the firewall problem entirely.

How it works:

Cloud SQL Auth Proxy is a client-side daemon that creates an encrypted connection to Cloud SQL without requiring you to open any network ports. Authentication is handled via Google IAM, not network IP rules. Apps Script connects to Cloud SQL via the Cloud SQL API, which uses OAuth credentials rather than direct TCP connections.

Architecture:

Code
Apps Script → Cloud SQL Admin API (OAuth) → Cloud SQL instance

Setup steps:

  1. Create a Cloud SQL instance (PostgreSQL, MySQL, or SQL Server) in Google Cloud.
  2. Create a service account with the Cloud SQL Client role.
  3. In Apps Script, use the Cloud SQL Admin API to execute queries via REST calls authenticated with the service account.

Strengths:

  • No firewall rules at all: connection is API-based, not network-based.
  • Managed database. Google handles backups, patches, and failover.
  • Fine-grained IAM controls for who can access what.

Limitations:

  • Only works if your database can live in Google Cloud SQL. Not suitable if your data must remain on-premises or in a different cloud.
  • Cloud SQL costs are higher than self-managed databases at equivalent specs.
  • Migrating an existing database is a significant undertaking.

When to use it: You are starting fresh, have flexibility about where the database lives, and want the tightest possible integration with Google's ecosystem.

Solution 4: SSH Tunnel Approach

An SSH tunnel creates an encrypted connection between two endpoints through a jump host (bastion server). You can use this to route Apps Script traffic through a fixed IP jump host into your private network.

Architecture:

Code
Apps Script → Jump Host (fixed IP, SSH) → Internal Database

How it works:

  1. Set up a bastion/jump host in your network perimeter with a fixed public IP. This is often already present in enterprise networks.
  2. IT whitelists Apps Script's Google IP ranges for SSH connections to the bastion only (port 22). This is a smaller ask than whitelisting database port access.
  3. A service running on the bastion accepts authenticated connections from Apps Script and proxies them to the internal database.

Practical note: Apps Script itself cannot establish an SSH connection. UrlFetchApp is HTTP only. To use an SSH tunnel, you need an intermediary service (similar to Solution 2) that runs the SSH connection on your behalf. In practice, this usually means the API proxy approach (Solution 2) with an SSH tunnel from the proxy to the database.

When to use it: Your organization already uses a bastion host pattern, and you want to use existing security infrastructure rather than building new components.

Solution 5: brooked.io (Fixed IPs for Whitelisting)

brooked.io is a data connector for Google Sheets that is specifically designed to address the Apps Script IP problem. It connects to your database from its own infrastructure, which uses a fixed, documented set of egress IP addresses, and delivers query results directly to Google Sheets on a schedule.

How it works:

  1. Connect your database to brooked.io using standard database credentials and connection string.
  2. brooked.io provides its egress IPs for you to give to IT: a short, stable list.
  3. IT whitelists those IPs on your database's firewall.
  4. In Google Sheets, install the brooked.io add-on and write a SQL query.
  5. The query runs on brooked.io's infrastructure on your schedule and delivers results to the sheet.

What this means for IT conversations:

Instead of: "We need to whitelist all of Google's IP ranges."

You say: "We need to whitelist four specific IP addresses owned by brooked.io, documented here, for connections to port 5432 only."

That is a request with a defined scope, a specific vendor accountable for traffic from those IPs, and a clear audit trail. Security teams can approve it with confidence.

Strengths:

  • Fixed, documented egress IPs. The core problem is solved by design.
  • SQL interface: write the query you actually need, not a pre-built report format.
  • Scheduled delivery to Google Sheets with no Apps Script required.
  • Works with PostgreSQL, MySQL, Snowflake, BigQuery, Redshift, and others.

Limitations:

  • Your database connection details are stored with a third-party service: evaluate their security posture and data handling policies before connecting.
  • Not suitable for databases that require complete on-premises data isolation.

Solution Comparison Table

SolutionFixed IPsIT Ask ScopeEngineering EffortApps Script RequiredCost
Connector with fixed IPsYesSmall, specificLowNo$$
API Proxy (self-built)YesSmall, specificHighOptional$4–$20/mo infra
Cloud SQL Auth ProxyN/A (no firewall)NoneMediumOptionalCloud SQL rates
SSH TunnelYes (bastion)MediumHighNoInfra cost
brooked.ioYesSmall, specificLowNo$$

How to Make the Case to IT

If you are bringing any of these solutions to your IT or security team for approval, frame the request correctly.

What to include in a whitelist request:

  1. Purpose: "This connection allows our Google Sheet to pull query results from the internal analytics database on a scheduled basis."
  2. Specific IPs: List each IP address or narrow CIDR range. Do not say "Google's IPs."
  3. Protocol and port: "TCP connections to port 5432 (PostgreSQL) only."
  4. Direction: "Inbound connections from the listed IPs to the database server. No outbound connections from the database are required."
  5. Vendor documentation: Attach the connector vendor's published IP documentation.
  6. Data classification: Specify what data the connection will access, and confirm it matches the data classification of the database.

Most security teams will approve a well-scoped request that meets these criteria. The requests that get rejected are the ones that say "whitelist Google" without any further specification.

Troubleshooting

Apps Script gets a connection timeout but other tools can reach the database Cause: The database firewall is blocking Apps Script's IPs. This is the core problem: confirm you are using one of the solutions in this guide rather than a direct connection from Apps Script.

IT approved the whitelist but the connection still fails Cause: Several possibilities. The database server itself has a host-based firewall (iptables, Windows Firewall) separate from the network firewall, or the database user does not have permission to connect from external hosts. Solution: Confirm the rule is applied at both the network and host level, and check the database user's HOST setting.

The connector vendor's IPs changed without notice Cause: The vendor changed infrastructure without adequate communication. Solution: Choose vendors who guarantee advance notice of IP changes (typically 30 days minimum). Set up a monitoring alert on your firewall rules so you detect when a new IP appears or a rule stops matching traffic.

Cloud SQL Auth Proxy approach fails with permission errors Cause: The service account used by Apps Script does not have the Cloud SQL Client IAM role, or the Cloud SQL API is not enabled in the project. Solution: In Google Cloud IAM, add the Cloud SQL Client role to the service account, and enable the Cloud SQL Admin API in the project's API library.

SSH bastion approach: connection drops intermittently Cause: SSH keepalive settings are not configured, and the connection times out during idle periods. Solution: Configure the SSH client to send keepalive packets every 60 seconds (ServerAliveInterval 60).

Bottom Line

The IT team is not wrong to refuse the whitelist request. Google's published IP ranges are too broad to be a meaningful access control. The structural fix is to route database connections through infrastructure with fixed, specific IP addresses: whether that is a self-built proxy, a cloud-hosted database with IAM-based auth, or a purpose-built connector like brooked.io.

The right solution depends on your technical resources and your database's location:

  • Self-hosted database, minimal engineering resources → brooked.io or another connector with fixed egress IPs.
  • Self-hosted database, engineering resources available → API proxy (Solution 2).
  • Greenfield database deployment → Google Cloud SQL with Auth Proxy (Solution 3).
  • Enterprise network with existing bastion → SSH tunnel approach (Solution 4).

In every case, the conversation with IT becomes easier when you come with specific IPs, a defined port, and a vendor who can answer security questions directly.

Connect Your Database to Google Sheets with Fixed IPs

brooked.io provides documented, fixed egress IPs for database connections, so your IT team has a specific, scoped whitelist request, not a request to open the door to all of Google.

Connect your database through brooked.io, fixed IPs, scheduled queries, no Apps Script required.

Troubleshooting quick reference

Frequently asked questions

Does Google publish a list of Apps Script-specific egress IPs?

No. Google publishes its full IP range list, which includes all Google services. There is no Apps Script-specific subset. This is a documented limitation that has been raised in the Apps Script issue tracker, and there is no committed timeline for a fix.

Can I use Google VPC Service Controls to restrict Apps Script access?

VPC Service Controls applies to Google Cloud services, not to Apps Script egress. It cannot be used to restrict which external IPs Apps Script can connect to or to assign Apps Script a fixed outbound IP.

Is it safe to give a third-party connector our database credentials?

This depends on the connector's security practices. Look for: SOC 2 Type II certification, credentials encrypted at rest, no storage of query results after delivery, and the ability to use a read-only database user. Create a dedicated database user with the minimum permissions needed for the connector.

Why not just put the database on the public internet and use TLS?

For production databases, this is generally inadvisable. TLS encrypts traffic but does not restrict who can attempt to connect. Exposing a database port to the public internet dramatically increases attack surface. Firewall rules (even if they require this workaround) are a meaningful security control.

Can Apps Script use OAuth to authenticate to a database without IP whitelisting?

Not directly. Database protocols (PostgreSQL, MySQL, etc.) use their own authentication mechanisms and require direct TCP connectivity. There is no OAuth layer at the database protocol level. Cloud SQL Auth Proxy is the closest analog, and it requires your database to be hosted in Cloud SQL.

Ready to connect your data to Google Sheets?

Brooked's free tier covers 100 imports per month with AI Analyst included, no credit card required.

Install Brooked free →

Also in Google Sheets

More Google Sheets guides

Get your spreadsheet hours back

Brooked sets up in seconds. Your team is querying live data before lunch.

Get started free