AutomationFlowsWeb Scraping › Securely Call Private Google Cloud Run Apis with Jwt Authentication (simplified)

Securely Call Private Google Cloud Run Apis with Jwt Authentication (simplified)

ByMarco Cassar @marcocassar on n8n.io

Anyone who wants a dead-simple, free-tier friendly way to run custom API logic on Google Cloud Run and call it securely from n8n—no public exposure, no local hosting.

Event trigger★★★☆☆ complexity10 nodesJwtHTTP Request
Web Scraping Trigger: Event Nodes: 10 Complexity: ★★★☆☆ Added:

This workflow corresponds to n8n.io template #7571 — 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": "05736aa9-30cd-4387-bdbb-e00cc316592d",
      "name": "JWT",
      "type": "n8n-nodes-base.jwt",
      "position": [
        960,
        320
      ],
      "parameters": {
        "options": {},
        "useJson": true,
        "claimsJson": "={\n  \"iss\": \"{{ $json.client_email }}\",\n  \"sub\": \"{{ $json.client_email }}\",\n  \"aud\": \"{{ $json.token_uri }}\",\n  \"iat\": {{ Math.floor(Date.now() / 1000) }},\n  \"exp\": {{ Math.floor(Date.now() / 1000) + 3600 }},\n  \"target_audience\": \"{{ $json.service_url }}\"\n}"
      },
      "credentials": {
        "jwtAuth": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "72cc7bae-3ba8-4b8a-bd56-652ea8454705",
      "name": "Edit Fields",
      "type": "n8n-nodes-base.set",
      "position": [
        704,
        384
      ],
      "parameters": {
        "mode": "raw",
        "options": {},
        "jsonOutput": "{\n  \"service_url\": \"_____INSERT_____\",\n  \"client_email\": \"_____INSERT_____\",\n  \"token_uri\": \"https://oauth2.googleapis.com/token\"\n}"
      },
      "typeVersion": 3.4
    },
    {
      "id": "3acc14d7-bb7c-457f-b459-9219f5519579",
      "name": "Cloud Run Request",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        1424,
        336
      ],
      "parameters": {
        "url": "={{ $('Edit Fields').item.json.service_url }}",
        "options": {},
        "authentication": "genericCredentialType",
        "genericAuthType": "httpBearerAuth"
      },
      "credentials": {
        "httpBearerAuth": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "3583afae-ee3d-4066-9a47-fbda5e319c97",
      "name": "Bearer YOUR_TOKEN_HERE Request",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        1184,
        208
      ],
      "parameters": {
        "url": "={{ $('Edit Fields').item.json.token_uri }}",
        "body": "=grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer&assertion={{ $json.token }}",
        "method": "POST",
        "options": {},
        "sendBody": true,
        "contentType": "form-urlencoded",
        "specifyBody": "string"
      },
      "typeVersion": 4.2
    },
    {
      "id": "c9eadc11-0acc-4471-b493-df1fa51a7948",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        32,
        224
      ],
      "parameters": {
        "width": 560,
        "height": 448,
        "content": "## Google Service Auth Workflow (Minimal)\n\n### Purpose\nCreate a Google **ID token** so n8n can call your Cloud Run service with `Authorization: Bearer \u2026`.\n\n### How It Works\n  * **Set** vars: `service_url`, `client_email`, `token_uri`\n  * **JWT** node: sign a JWT\n  * **HTTP Request**: POST to `token_uri` to get Bearer YOUR_TOKEN_HERE\n  * Use the returned **`id_token`** in the next HTTP request to specified service url.\n\n### Output\n  * Payload Returned from Google Cloud Run"
      },
      "typeVersion": 1
    },
    {
      "id": "d35ae519-26a6-4728-ae2a-38dde55be605",
      "name": "Execute",
      "type": "n8n-nodes-base.manualTrigger",
      "position": [
        432,
        544
      ],
      "parameters": {},
      "typeVersion": 1
    },
    {
      "id": "88201046-6262-4403-ac1d-2b5cee1cb6b0",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        896,
        304
      ],
      "parameters": {
        "color": 2,
        "width": 230,
        "height": 432,
        "content": "\n\n\n\n\n\n\n\n\n\n\n\n\n### Create a JWT Credential\n\nUse the **private_key** from your generated `.json key` file.\n\n- **Key Type:** PEM Key  \n- **Private Key:** `private_key` (full block, including `-----BEGIN PRIVATE KEY-----` \u2026 `END PRIVATE KEY-----`)  \n- **Algorithm:** RS256"
      },
      "typeVersion": 1
    },
    {
      "id": "1b1a5865-4c9a-4717-9aa5-e115e0c2395a",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1344,
        304
      ],
      "parameters": {
        "color": 2,
        "width": 246,
        "height": 320,
        "content": "\n\n\n\n\n\n\n\n\n\n\n\n\n#### Create a Bearer YOUR_TOKEN_HERE\nUse the `{{$json.id_token}}` value.\n\n#### Append desired `/path` to the service_url."
      },
      "typeVersion": 1
    },
    {
      "id": "43b102b7-fcfc-44d7-b824-2c417e43f290",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        656,
        208
      ],
      "parameters": {
        "color": 2,
        "width": 182,
        "height": 320,
        "content": "#### Var Config\n- **service_url** \u2014 your Cloud Run service URL (base URL)  \n- **client_email** \u2014 from `.json key`"
      },
      "typeVersion": 1
    },
    {
      "id": "a070e14b-f57b-49fc-af57-04d1f39496c8",
      "name": "Sticky Note4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        32,
        -16
      ],
      "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
    }
  ],
  "connections": {
    "JWT": {
      "main": [
        [
          {
            "node": "Bearer YOUR_TOKEN_HERE Request",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Execute": {
      "main": [
        [
          {
            "node": "Edit Fields",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Edit Fields": {
      "main": [
        [
          {
            "node": "JWT",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Bearer Token Request": {
      "main": [
        [
          {
            "node": "Cloud Run Request",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}

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 dead-simple, free-tier friendly way to run custom API logic on Google Cloud Run and call it securely from n8n—no public exposure, no local hosting.

Source: https://n8n.io/workflows/7571/ — 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

Anyone calling a Google Cloud Run service from n8n who wants a small, reusable auth layer instead of wiring tokens in every workflow.

Jwt, Execute Workflow Trigger, HTTP Request
Web Scraping

The Sora 2 API allows seamless generation of CGI ads, turning text prompts into stunning videos. This workflow automates the entire process from video generation to upload, notification, and file shar

Form Trigger, HTTP Request, Email Send +1
Web Scraping

This template syncs prospects from ProspectPro into HubSpot. It checks if a company already exists in HubSpot (by ProspectPro ID or domain), then updates the record or creates a new one. Sync results

Execute Workflow Trigger, @Bedrijfsdatanl/N8N Nodes Prospectpro, HTTP Request +1
Web Scraping

Site owners, SEOs, and marketers who want a single automation to notify Google (Indexing API) and Bing (via IndexNow) whenever site URLs are added or updated. No more need to update it manually. Hours

HTTP Request, XML
Web Scraping

This workflow automates the collection of public procurement data from TenderNed (the official Dutch tender platform). It: Fetches the latest tender publications from the TenderNed API Retrieves detai

HTTP Request, XML, Data Table