Connect Google Cloud Storage to n8n: buckets, objects and service accounts
Published 26 August 2026 · 7 min read
An n8n workflow that generates invoice PDFs, downloads email attachments or produces AI images always runs into the same question: where do these files go without filling the instance disk or a shared Drive quota? When the organisation already lives inside the Google ecosystem, the answer is Google Cloud Storage. n8n ships a native Google Cloud Storage node covering buckets and objects, and the only real obstacle is authentication. This guide covers the service account, the minimal IAM role, the node's actual operations, storage classes, and how to share an object without making the bucket public.
GCS, S3 or Google Drive: decide before you configure
The right question is not the price per gigabyte, it is: who reads these files? Drive is built for humans — per-person permissions, previews, a bin; if your users handle documents by hand, automating Google Drive remains the sensible reflex. GCS and S3 are built for machines: a flat key, no working interface, but durability, a per-GB cost and lifecycle rules no collaborative space offers.
Between the two, the criterion is the ecosystem. GCS wins if the files must feed a BigQuery warehouse or if the GCP project already exists. S3 wins on AWS, and above all if you want an exit door: its credential accepts a custom endpoint, so Backblaze B2, Scaleway or a self-hosted MinIO — the whole point of our S3 archiving pipeline. The Google Cloud Storage node only ever talks to Google, and that choice is hard to revisit. The study by Justice Opara-Martins, Reza Sahandi and Feng Tian, Critical analysis of vendor lock-in and its impact on cloud computing migration: a business perspective (Journal of Cloud Computing, 2016 — see on Google Scholar), based on a survey of 114 IT professionals, shows that vendor lock-in remains a major barrier to cloud adoption: 35% of respondents name excessive dependence on a single provider among their main reservations.
Authentication: service account or OAuth2
This is where most people give up. The node's Authentication field offers two values, and they point at different n8n credentials:
- OAuth2 uses the Google Cloud Storage OAuth2 API credential (Client ID and Client Secret created in the GCP console, scopes
devstorage.full_controlandcloud-platform), following the procedure in our Google OAuth2 guide. - Service Account uses the generic Google API credential, fed by a service account JSON file.
For a workflow running overnight, the service account is the obvious pick: no user attached, and rights you can narrow to a single bucket. Three steps:
- IAM & Admin → Service accounts → Create service account, with an explicit name (
n8n-storage). - Keys tab → Add key → Create new key → JSON. The file downloads exactly once; Google keeps no copy.
- APIs & Services → Library → Cloud Storage JSON API → Enable. Routinely forgotten, and the number one cause of the 403s described below.
The JSON holds far more than n8n needs:
{
"type": "service_account",
"project_id": "my-project-2026",
"private_key": "-----BEGIN PRIVATE KEY-----\nMIIEv…\n-----END PRIVATE KEY-----\n",
"client_email": "n8n-storage@my-project-2026.iam.gserviceaccount.com"
}
In the Google API credential, carry over two fields only: client_email into Service Account Email, private_key into Private Key (without the surrounding quotation marks, line breaks preserved). The file itself then belongs nowhere but a secrets manager, like any other API credential worth securing.
The minimal IAM role
The lazy reflex grants roles/storage.admin at project level — a key able to empty every bucket. The right scope is roles/storage.objectAdmin on one specific bucket:
gcloud storage buckets add-iam-policy-binding gs://invoices-archive-2026 \
--member="serviceAccount:n8n-storage@my-project-2026.iam.gserviceaccount.com" \
--role="roles/storage.objectAdmin"
Narrower still: roles/storage.objectCreator (write without read or delete, ideal for one-way archiving) and roles/storage.objectViewer (read only).
The node's two resources: Bucket and Object
The node exposes two resources with the same five verbs on each side: Create, Delete, Get, Get Many, Update.
Bucket. Create and Get Many require a project — a Project resource locator in recent node versions, a plain Project ID text field in version 1. Create accepts an Additional Parameters block mirroring Google's JSON API (Location, Storage Class, Lifecycle, Versioning, Retention Policy). In practice you create the bucket once in the console.
Object is the resource that matters day to day.
- Create uploads an object:
Bucket Name,Object Name(the full key,archives/2026/08/invoice-1042.pdf), and the Use Input Binary Field toggle. On, it reads the previous node's binary through Input Binary Field (databy default); off, a File Content field appears. The Create Fields block sets metadata:Content Type,Cache Control,Storage Class, and a free-formMetadataobject. - Get reads an object, and its decisive parameter is Return Data: Metadata returns the JSON record, Object Data returns the content, placed in the property named by Put Output File in Field. A workflow that "does not retrieve the file" has often simply left Return Data on Metadata.
- Get Many lists objects through a List Filters block:
Prefixto surface a single pseudo-folder,Delimiterfor directory-style listing,Versions. Pagination goes through Return All or Limit. - Update and Delete close the list, with optional preconditions (
Generation Match,Metageneration Match) that stop you overwriting a newer version than you expect.
Storage classes and lifecycle
GCS offers four classes: Standard, Nearline, Coldline, Archive. The principle fits in one sentence, no pricing needed: the colder the class, the cheaper storage is per gigabyte, but the more retrieval costs — and the longer the minimum billed storage duration (30 days for Nearline, 90 for Coldline, 365 for Archive). Deleting an Archive object after a month means paying for eleven months of nothing.
That trade-off is a physical constraint, not a commercial artefact. Shobana Balakrishnan, Richard Black, Antony Rowstron and their Microsoft Research co-authors documented it in Pelican: A Building Block for Exascale Cold Data Storage (OSDI 2014 — see on Google Scholar): their cold storage rack provisions power, cooling and interconnect bandwidth for rare access only, to the point that just 8% of the drives can spin at the same time. That is what makes cold storage cheap, and what explains its retrieval delay.
The n8n consequence: do not implement retention inside the workflow. A lifecycle rule set on the bucket moves objects to a colder class after N days then deletes them at term, without burning a single execution — the same separation of concerns as an automated GDPR purge.
Sharing an object without opening the bucket
The temptation, when a client needs an invoice, is to tick Public Read. Bad idea: a public bucket is indexable, enumerable and out of your control the moment a URL circulates. Instead enable the two GCS guardrails, uniform bucket-level access and public access prevention.
The right answer is the signed URL: a link carrying a signature and an expiry, valid for one object and one HTTP method, without touching permissions. The node offers no signing operation. Two routes: a Code node building the V4 canonical string and signing it with the private_key through crypto, or an HTTP Request node calling the signBlob method of the IAM Credentials API, which avoids handling the private key. Keep the expiry short.
Five use cases
- Archiving invoice PDFs: the quote and invoice pipeline produces a binary that a Create files under the key
invoices/{{ $now.year }}/{{ $now.month }}/{{ $json.number }}.pdf. - Storing email attachments: downstream of AI attachment processing, the raw file goes to the bucket and only the metadata stays in the database.
- Dropping a CSV export for BigQuery to read: an export generated in n8n lands in a staging bucket before ingestion — far more efficient than row-by-row inserts.
- Backing up workflow exports: a daily JSON in a versioned bucket, alongside Git-based backups.
- Keeping AI-generated images, which an image generation workflow would otherwise leave bloating the execution history.
Traps worth knowing
- The JSON key pasted into a node: a hardcoded
private_keyends up in the workflow export, in Git and in every shared copy. - The API not enabled: a 403
PERMISSION_DENIEDmentioning "Cloud Storage JSON API has not been used in project … before or it is disabled" has nothing to do with roles. The Project selector in list mode also calls the Cloud Resource Manager API, to be enabled separately if the list stays empty. - Bucket names are globally unique:
invoicesorbackupwere taken years ago. Prefix with your organisation — that name shows up in every URL. - Network egress fees: writing costs little, reading back costs. A workflow re-downloading the same object on every run to extract three fields pays egress over and over; store those metadata in a database at upload time.
- Nothing deletes itself: without a lifecycle rule a bucket only grows, and the invoice is your only alerting mechanism.
- Large files: the binary transits through the instance and sits in RAM for the duration of the operation. Switch binary storage to
filesystemmode, as explained in our large files guide.
Key takeaways
The node amounts to two resources and ten operations, but adoption is decided elsewhere: a service account, a Google API credential fed by client_email and private_key, the Cloud Storage JSON API enabled, and a roles/storage.objectAdmin scoped to one bucket. After that, three settings suffice: Use Input Binary Field on Create, Return Data on Get, and the lifecycle rule placed on the bucket rather than in the workflow.
Going further
A GCS bucket earns its place at the tail end of a pipeline that produces files continuously. The AI Inbox Pack (€79) sorts incoming email and isolates the attachments worth keeping, instead of letting the mailbox act as an accidental archive. And where retention answers a legal obligation, the Compliance & Audit Pack (€149) supplies the timestamped audit trail recording which file was stored, when, and by which workflow.
FAQ
Frequently asked questions
Which credential does the n8n Google Cloud Storage node need?
The node exposes an Authentication field with two values. OAuth2 uses the dedicated « Google Cloud Storage OAuth2 API » credential, which asks for a Client ID and Client Secret created in the GCP console. Service Account uses n8n's generic « Google API » credential, where you paste the client_email and private_key taken from the service account JSON file. For an automated workflow running with nobody watching, the service account is the logical pick: it belongs to no individual user, and access does not break when someone leaves the company.
Why does my Google Cloud Storage node return a 403 even though the IAM roles look correct?
In most cases the Cloud Storage JSON API simply is not enabled on the GCP project. The message then contains a phrase along the lines of « Cloud Storage JSON API has not been used in project … before or it is disabled », with a PERMISSION_DENIED status that sends you hunting through roles when the problem lies elsewhere. Go to APIs & Services, then Library, search for Cloud Storage JSON API and enable it. Allow a minute or two of propagation before the node responds correctly.
Can the Google Cloud Storage node generate a signed URL?
No. The node's resources stop at Bucket (Create, Delete, Get, Get Many, Update) and Object (Create, Delete, Get, Get Many, Update): there is no signing operation. A V4 signed URL is built by signing a canonical string with the service account private key, which means a Code node using the crypto module, or a call to the signBlob method of the IAM Credentials API from an HTTP Request node. It is the only clean way to share an object temporarily without ever making the bucket public.
Should I pick Google Cloud Storage or Amazon S3 for archiving from n8n?
The deciding factor is the ecosystem, not the node. GCS wins if your data has to feed BigQuery, if the company already runs on Google Workspace, or if a GCP project exists with its billing and IAM roles. S3 wins on the AWS side, and above all whenever you want third-party compatibility: the n8n S3 credential accepts a custom endpoint, which opens the door to Backblaze B2, Scaleway, Wasabi or a self-hosted MinIO. The Google Cloud Storage node only ever talks to Google.
Bundle FlowKit Complet
€269