DEV Community

Abd Alrhman Alloush
Abd Alrhman Alloush

Posted on Originally published at 1datacloud.ai

How GCP Service Accounts Work for Database Access Tools

If you've ever connected a third-party tool to a GCP project, you've run into the same ritual: create a service account, attach some roles, download a JSON key, paste it somewhere. Most DBAs do this on autopilot without stopping to think about what a service account actually is, which roles it really needs, and what happens if that JSON key leaks.

That's worth slowing down for. Service account permissions are one of the most common places database security goes quietly wrong — not through a sophisticated attack, but through a service account granted far more than it needed, because "Editor" was faster to click than figuring out the right role.


TL;DR

A GCP service account's permissions come entirely from the IAM roles you attach — there's no implicit access beyond that. For a tool that only needs to discover Cloud SQL and Cloud Spanner instances, roles/cloudsql.viewer and roles/spanner.viewer are the only roles needed. 1DataCloud connects to GCP using exactly those two roles. Try it free →


What a GCP Service Account Actually Is

A service account is an identity — not a human one. It's what applications, scripts, and third-party tools use to authenticate to Google Cloud APIs, the way your own Google account authenticates you in the GCP Console.

The part that matters: a service account's permissions come entirely from the IAM roles you attach to it. There's no default level of access. A brand-new service account with no roles can do nothing.

Download its JSON key, and you're holding long-lived credentials for that identity. Anyone with that file can authenticate as the service account and do whatever its roles allow — which is exactly why the roles attached matter so much.

The Roles That Actually Matter for Database Discovery

For a tool that only needs to discover and inspect database instances — not modify them — two predefined roles cover it:

roles/cloudsql.viewer — read-only visibility into Cloud SQL: instance names, regions, tiers, versions, status, configuration. No create, modify, delete, or data access.

roles/spanner.viewer — the equivalent for Cloud Spanner: instance and database metadata, no schema or data modification.

Both are scoped specifically to metadata visibility for their service. Neither touches Compute Engine, billing, IAM, or anything else in the project.

What not to grant

The common shortcut is attaching Editor or Owner because it "definitely includes" whatever narrower permission is needed. It does — along with the ability to modify or delete nearly everything else in the project. A leaked key tied to a viewer role exposes metadata. A leaked key tied to Editor exposes your entire GCP project.

How 1DataCloud Uses This

1DataCloud's GCP connection runs on exactly roles/cloudsql.viewer and roles/spanner.viewer — nothing broader. With just those two roles, it uses the GCP API to discover every Cloud SQL and Cloud Spanner instance across every project the service account can see, automatically. No project-by-project browsing, no permissions beyond what's needed to build that inventory.

Once an instance is connected for querying, its schema is read and mapped so Query1AI can turn plain-English questions into read-only SQL — but the discovery step itself never required write access to anything.

If that JSON key were ever exposed, the worst case is someone viewing your database inventory metadata — not modifying a database, not touching unrelated GCP services, not reaching billing. That's a very different incident than a leaked key with Editor attached.

Mistakes Worth Avoiding

  • One service account for everything. A single, broadly-scoped account shared across five tools means a compromise of any one is a compromise of all five.
  • Keys that never rotate. A JSON key doesn't expire on its own.
  • Using the default Compute Engine service account, which often carries broad project-level permissions by default, for a narrow task like discovery.
  • Project-level roles when a resource-level one exists — even when the project-wide version is more convenient to click through.

Summary

A GCP service account is only as risky as the roles attached to it. For database discovery, roles/cloudsql.viewer and roles/spanner.viewer grant exactly enough visibility to build an inventory — nothing more. 1DataCloud's own GCP connection runs on exactly those two roles.

👉 See how 1DataCloud connects to GCP
👉 Try it free


What's your team's policy on service account scoping — one per integration, or shared accounts with broader roles? Curious how others handle this in practice.

Top comments (0)