AutomationFlowsWeb Scraping › Securely Call Google Cloud Run Apis with Service Account Auth (main-workflow)

Securely Call Google Cloud Run Apis with Service Account Auth (main-workflow)

ByMarco Cassar @marcocassar on n8n.io

Anyone who wants a simple, secure way to call a Google Cloud Run endpoint from n8n—without exposing it publicly.

Event trigger★★★★☆ complexity18 nodesHTTP Request
Web Scraping Trigger: Event Nodes: 18 Complexity: ★★★★☆ Added:

This workflow corresponds to n8n.io template #7568 — we link there as the canonical source.

The workflow JSON

Copy or download the full n8n JSON below. Paste it into a new n8n workflow, add your credentials, activate. Full import guide →

Download .json
{
  "nodes": [
    {
      "id": "1003f9f2-98a2-4690-bc36-dec428c71e46",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        64,
        224
      ],
      "parameters": {
        "color": 4,
        "width": 512,
        "height": 480,
        "content": "# Running the Workflow\n\n## Run it\n- Click **Execute** (or **Execute workflow**).\n- Make sure `service_url` and option `service_path` is set.\n\n## What happens\n- Calls the **Service Auth (sub-workflow)** to validate or create a Google **ID token**.\n- Calls your **Google Cloud Run** service with `Authorization: Bearer <id_token>` and returns the endpoint\u2019s response.\n\n## Check results\n- Open the **Cloud Run Request** node to see the status and response body.\n- If it fails, inspect the **Bearer YOUR_TOKEN_HERE Request** output and Cloud Run logs."
      },
      "typeVersion": 1
    },
    {
      "id": "c06b15b6-7619-4b5e-a2d6-cd7b3b4f5a91",
      "name": "Sticky Note8",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        640,
        576
      ],
      "parameters": {
        "color": 2,
        "width": 432,
        "height": 336,
        "content": "## Extra Configurations for Workflow\n### Google Credentials (Service Account)\n- Open a **Google** node \u2192 **Create New Credential**\n- **Authentication:** Service Account\n- **Service account email:** `client_email` from your `.json private key`\n- **Private key:** `private_key` from your `.json private key` (entire block, incl. BEGIN/END)\n- **Save** the credential  \n- **Enable the relevant Google API** in Cloud Console (e.g., Sheets API, Drive API), and **share the target resource** with the service account\u2019s `client_email` (e.g., share the Sheet/Folder so it has access).\n* Save Credential\n"
      },
      "typeVersion": 1
    },
    {
      "id": "8da22b71-e554-4d44-91c6-e6e2a2c4adeb",
      "name": "Check Auth",
      "type": "n8n-nodes-base.executeWorkflow",
      "position": [
        1920,
        352
      ],
      "parameters": {
        "options": {},
        "workflowId": {
          "__rl": true,
          "mode": "list",
          "value": "3lkAlfsxT2cnJztz",
          "cachedResultName": "Templates \u2014 Service Auth (sub-workflow)"
        },
        "workflowInputs": {
          "value": {
            "id_token": "={{ $json.id_token }}",
            "service_url": "={{ $json.service_url }}",
            "service_path": "={{ $json.service_path }}"
          },
          "schema": [
            {
              "id": "id_token",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "id_token",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "service_url",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "service_url",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "service_path",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "service_path",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [],
          "attemptToConvertTypes": false,
          "convertFieldsToString": true
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "ab91bde5-4063-40eb-a096-2cbfbbb853c7",
      "name": "Execute",
      "type": "n8n-nodes-base.manualTrigger",
      "position": [
        464,
        256
      ],
      "parameters": {},
      "typeVersion": 1
    },
    {
      "id": "e5b5ae39-5420-4c34-9631-1135a1c7aee3",
      "name": "Collect Context Example",
      "type": "n8n-nodes-base.merge",
      "position": [
        1184,
        256
      ],
      "parameters": {
        "mode": "combine",
        "options": {},
        "combineBy": "combineAll"
      },
      "executeOnce": false,
      "typeVersion": 3.2
    },
    {
      "id": "ea8eeea6-463a-4278-a45c-ab8c36c4ce78",
      "name": "Sticky Note5",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1120,
        224
      ],
      "parameters": {
        "color": 2,
        "width": 224,
        "height": 432,
        "content": "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n### Merge node \u2014 gathers all context.\n\nUse a **Merge** node to add the auth context (`id_token`) to items.\n\n- **Mode:** `Combine`\n- **Combine By:** `All Possible Combinations`"
      },
      "typeVersion": 1
    },
    {
      "id": "1df841ed-f332-4760-8d14-7afd658b8b0f",
      "name": "Set Example Context Fields",
      "type": "n8n-nodes-base.set",
      "position": [
        928,
        352
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "f8beba00-56f3-4af8-9725-88f79c65afa2",
              "name": "example_context",
              "type": "string",
              "value": "a very interesting value"
            },
            {
              "id": "d192b7f3-1cd8-48fc-962f-49e1aba32e08",
              "name": "array_of_soups",
              "type": "array",
              "value": "={{[\"ramen\", \"udon\", \"chicken noodle\", \"pho\"]}}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "643a2331-8643-4fca-8582-e3ec006469d0",
      "name": "Split Out",
      "type": "n8n-nodes-base.splitOut",
      "position": [
        1472,
        256
      ],
      "parameters": {
        "include": "allOtherFields",
        "options": {
          "destinationFieldName": "soup"
        },
        "fieldToSplitOut": "array_of_soups"
      },
      "typeVersion": 1
    },
    {
      "id": "86d0adfc-a48e-4649-b659-f3caf27d75cc",
      "name": "Sticky Note9",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1408,
        16
      ],
      "parameters": {
        "color": 2,
        "width": 224,
        "height": 384,
        "content": "### Split Out node \u2014 iterate array, keep context\n- **Operation:** Split Out Items\n- **Field to split:** `<your_array_field>`\n- **Include:** **All other fields** (keeps `id_token`, `service_url`, etc.)\n- **Result:** one item per array element"
      },
      "typeVersion": 1
    },
    {
      "id": "fc6c3e1f-dd75-4ded-aede-debe8e5b1d6e",
      "name": "Sticky Note6",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1696,
        336
      ],
      "parameters": {
        "width": 336,
        "content": "#### Point to Service Auth\n#### (sub-workflow)\n\n###### If you are lost\n###### read my Medium article\n###### linked in the main sticky note"
      },
      "typeVersion": 1
    },
    {
      "id": "191ec402-a438-4a20-a39c-73e4c78350e6",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        896,
        80
      ],
      "parameters": {
        "width": 166,
        "height": 224,
        "content": "###### Point To\n\n###### Service Auth \n###### (sub-workflow)\n\n"
      },
      "typeVersion": 1
    },
    {
      "id": "da178c80-a687-45cf-9d78-f8f3b877962e",
      "name": "Get Auth",
      "type": "n8n-nodes-base.executeWorkflow",
      "position": [
        928,
        176
      ],
      "parameters": {
        "options": {},
        "workflowId": {
          "__rl": true,
          "mode": "list",
          "value": "3lkAlfsxT2cnJztz",
          "cachedResultName": "Templates \u2014 Service Auth (sub-workflow)"
        },
        "workflowInputs": {
          "value": {
            "service_url": "={{ $json.service_url }}",
            "service_path": "={{ $json.service_path }}"
          },
          "schema": [
            {
              "id": "id_token",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "id_token",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "service_url",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "service_url",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "service_path",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "service_path",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [],
          "attemptToConvertTypes": false,
          "convertFieldsToString": true
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "74dee137-1db5-4884-a7da-5f52d88dbaac",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        0,
        0
      ],
      "parameters": {
        "color": 2,
        "width": 672,
        "height": 208,
        "content": "## Required Setup \u2014 Google Cloud Run & Service Account\n### You\u2019ll need to:\n- **Configure a Google Cloud Run service** (set **Require authentication**).\n- **Create a Google Service Account** and grant it **Cloud Run Invoker** permission on that service.\n\nFor a detailed, step-by-step breakdown, see my Medium article:\n\n**[Build a Secure Google Cloud Run API, Then Call It from n8n (Free Tier)](https://medium.com/@marcocodes/build-a-secure-google-cloud-run-api-then-call-it-from-n8n-88c03291a95f)**"
      },
      "typeVersion": 1
    },
    {
      "id": "6e7dd64a-0623-4f85-a15f-d963295d9c59",
      "name": "Cloud Run Request",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        2128,
        480
      ],
      "parameters": {
        "url": "={{ $('Loop Over Items').item.json.service_url }}{{ $('Loop Over Items').item.json.service_path }}",
        "options": {},
        "authentication": "genericCredentialType",
        "genericAuthType": "httpBearerAuth"
      },
      "credentials": {
        "httpBearerAuth": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "0a8b37cb-d0a0-4cb1-9e58-bea8adee5cb1",
      "name": "Loop Over Items",
      "type": "n8n-nodes-base.splitInBatches",
      "position": [
        1728,
        176
      ],
      "parameters": {
        "options": {}
      },
      "typeVersion": 3
    },
    {
      "id": "bdcd0698-6749-4216-be57-c1589585da8c",
      "name": "Sticky Note4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        704,
        16
      ],
      "parameters": {
        "color": 2,
        "width": 166,
        "height": 288,
        "content": "#### Var Config\n- **service_url** - base url to cloud run service\n- **service_path** - (optional) page path"
      },
      "typeVersion": 1
    },
    {
      "id": "ffa80822-56aa-43f4-8da9-35c455024f5c",
      "name": "Vars",
      "type": "n8n-nodes-base.set",
      "position": [
        736,
        176
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "0ff6e5eb-9ffe-4e28-b889-1feb58a59f39",
              "name": "service_url",
              "type": "string",
              "value": ""
            },
            {
              "id": "50ad4676-74f4-4e9c-bd9d-3f7a9424eee1",
              "name": "service_path",
              "type": "string",
              "value": ""
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "8e09bb36-88f4-41fb-b0d7-e911f513f798",
      "name": "Done",
      "type": "n8n-nodes-base.noOp",
      "position": [
        1920,
        112
      ],
      "parameters": {},
      "typeVersion": 1
    }
  ],
  "connections": {
    "Vars": {
      "main": [
        [
          {
            "node": "Get Auth",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Execute": {
      "main": [
        [
          {
            "node": "Set Example Context Fields",
            "type": "main",
            "index": 0
          },
          {
            "node": "Vars",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get Auth": {
      "main": [
        [
          {
            "node": "Collect Context Example",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Split Out": {
      "main": [
        [
          {
            "node": "Loop Over Items",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Check Auth": {
      "main": [
        [
          {
            "node": "Cloud Run Request",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Loop Over Items": {
      "main": [
        [
          {
            "node": "Done",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Check Auth",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Cloud Run Request": {
      "main": [
        [
          {
            "node": "Loop Over Items",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Collect Context Example": {
      "main": [
        [
          {
            "node": "Split Out",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Set Example Context Fields": {
      "main": [
        [
          {
            "node": "Collect Context Example",
            "type": "main",
            "index": 1
          }
        ]
      ]
    }
  }
}

Credentials you'll need

Each integration node will prompt for credentials when you import. We strip credential IDs before publishing — you'll add your own.

Pro

For the full experience including quality scoring and batch install features for each workflow upgrade to Pro

About this workflow

Anyone who wants a simple, secure way to call a Google Cloud Run endpoint from n8n—without exposing it publicly.

Source: https://n8n.io/workflows/7568/ — original creator credit. Request a take-down →

More Web Scraping workflows → · Browse all categories →

Related workflows

Workflows that share integrations, category, or trigger type with this one. All free to copy and import.

Web Scraping

This workflow allows you to import any workflow from a file or another n8n instance and map the credentials easily. A multi-form setup guides you through the entire process At the beginning you have t

Execute Command, Read Write File, HTTP Request +3
Web Scraping

[n8n] Advanced URL Parsing and Shortening Workflow - Switchy.io Integration. Uses splitInBatches, stickyNote, httpRequest, html. Event-driven trigger; 56 nodes.

HTTP Request, GitHub, Stop And Error +1
Web Scraping

[](https://youtu.be/c7yCZhmMjtI)

HTTP Request, GitHub, Stop And Error +1
Web Scraping

This automation organizes your n8n workflows files into categorizes (Active, Template, Done, Archived) and uploads them directly to a categorized Google Drive folders. It is designed to help users man

Google Drive, HTTP Request, Time Saved
Web Scraping

Create Animated Stories using GPT-4o-mini, Midjourney, Kling and Creatomate API. Uses httpRequest. Event-driven trigger; 51 nodes.

HTTP Request