3 Gotchas When Calling an IAP‑Protected Cloud Run API from a Chrome Extension (MV3)

This is a short, code‑first tutorial for developers. It assumes you already have a Cloud Run service and an OAuth2 Web Client. No business case study here—just the practical bits.

Summary

Use chrome.identity.launchWebAuthFlow to get a Go…


This content originally appeared on DEV Community and was authored by Saloni Kataria

This is a short, code‑first tutorial for developers. It assumes you already have a Cloud Run service and an OAuth2 Web Client. No business case study here—just the practical bits.

Summary

  • Use chrome.identity.launchWebAuthFlow to get a Google ID token.
  • Send it as Authorization: Bearer <token> to your IAP/IAM‑protected Cloud Run endpoint.
  • Verify the token audience on the server and cache tokens with a small expiry buffer on the client.

1) Getting an ID token (MV3)

background.js

async function getIdToken() {
  const redirectUrl = chrome.identity.getRedirectURL();
  const u = new URL("https://accounts.google.com/o/oauth2/v2/auth");
  u.searchParams.set("client_id", "YOUR_OAUTH_CLIENT_ID.apps.googleusercontent.com");
  u.searchParams.set("response_type", "id_token");
  u.searchParams.set("scope", "openid email profile");
  u.searchParams.set("redirect_uri", redirectUrl);
  u.searchParams.set("nonce", String(Date.now()));
  u.searchParams.set("prompt", "select_account");

  const { url } = await chrome.identity.launchWebAuthFlow({ url: u.toString(), interactive: true });
  const params = new URLSearchParams(new URL(url).hash.substring(1));
  const idToken = params.get("id_token");
  if (!idToken) throw new Error("No id_token returned");
  return idToken;
}

Mini‑cache (optional):

function decodePayload(jwt){const b=jwt.split('.')[1].replace(/-/g,'+').replace(/_/g,'/');return JSON.parse(atob(b));}
async function getCachedIdToken(){
  const now=Math.floor(Date.now()/1000);
  const {token,exp}=await chrome.storage.local.get(["token","exp"]);
  if(token && exp && (exp-300)>now) return token; // 5‑min buffer
  const fresh=await getIdToken(); const {exp:e}=decodePayload(fresh);
  await chrome.storage.local.set({token:fresh, exp:e}); return fresh;
}

2) Calling your API

popup.js

document.getElementById("go").addEventListener("click", async () => {
  const token = await chrome.runtime.sendMessage({ type: "GET_TOKEN" });
  const res = await fetch("https://YOUR‑SERVICE‑HASH‑ue.a.run.app/run-secure-endpoint", {
    method: "POST",
    headers: { "Authorization": `Bearer ${token}`, "Content-Type": "application/json" },
    body: JSON.stringify({ url: (await chrome.tabs.query({active:true,currentWindow:true}))[0].url })
  });
  console.log(await res.text());
});

And in background.js:

chrome.runtime.onMessage.addListener((m,_,send)=>{
  if(m?.type==="GET_TOKEN") getCachedIdToken().then(t=>send(t)).catch(e=>send({error:String(e)}));
  return true;
});

3) Verifying on Flask (Cloud Run)

main.py

from flask import Flask, request, jsonify
from google.oauth2 import id_token
from google.auth.transport import requests as greq
import os

app = Flask(__name__)
IAP_AUDIENCE = os.environ.get("IAP_OAUTH_CLIENT_ID","")  # set this for IAP

def verify_google_id_token(tok:str)->dict:
  return id_token.verify_oauth2_token(tok, greq.Request(), audience=IAP_AUDIENCE)

@app.post("/run-secure-endpoint")
def run_secure():
  auth = request.headers.get("Authorization","")
  if not auth.startswith("Bearer "): return jsonify({"error":"missing bearer"}), 401
  try: payload = verify_google_id_token(auth.split()[1])
  except Exception as e: return jsonify({"error":"invalid token","detail":str(e)}), 401
  return jsonify({"ok": True, "email": payload.get("email")})

Common gotchas (and fixes)

  • 401 with IAP: wrong audience. Use the IAP OAuth Client ID as aud when verifying.
  • Empty id_token: check your OAuth2 client type (Web) and the redirect URI from getRedirectURL().
  • Tokens expiring mid‑session: cache with a small buffer (5 minutes) and refresh on demand.
  • CORS: add Access-Control-Allow-Origin + Authorization header allowances if you call from content scripts or pages.

Minimal repo layout

repo/
├─ extension/ (manifest.json, background.js, popup.{html,js})
└─ backend/   (main.py, requirements.txt, Dockerfile)

That’s it—short and sweet. If you need a deeper walkthrough, look for my longer guide or case‑study later.


This content originally appeared on DEV Community and was authored by Saloni Kataria


Print Share Comment Cite Upload Translate Updates
APA

Saloni Kataria | Sciencx (2025-09-19T19:08:24+00:00) 3 Gotchas When Calling an IAP‑Protected Cloud Run API from a Chrome Extension (MV3). Retrieved from https://www.scien.cx/2025/09/19/3-gotchas-when-calling-an-iap%e2%80%91protected-cloud-run-api-from-a-chrome-extension-mv3/

MLA
" » 3 Gotchas When Calling an IAP‑Protected Cloud Run API from a Chrome Extension (MV3)." Saloni Kataria | Sciencx - Friday September 19, 2025, https://www.scien.cx/2025/09/19/3-gotchas-when-calling-an-iap%e2%80%91protected-cloud-run-api-from-a-chrome-extension-mv3/
HARVARD
Saloni Kataria | Sciencx Friday September 19, 2025 » 3 Gotchas When Calling an IAP‑Protected Cloud Run API from a Chrome Extension (MV3)., viewed ,<https://www.scien.cx/2025/09/19/3-gotchas-when-calling-an-iap%e2%80%91protected-cloud-run-api-from-a-chrome-extension-mv3/>
VANCOUVER
Saloni Kataria | Sciencx - » 3 Gotchas When Calling an IAP‑Protected Cloud Run API from a Chrome Extension (MV3). [Internet]. [Accessed ]. Available from: https://www.scien.cx/2025/09/19/3-gotchas-when-calling-an-iap%e2%80%91protected-cloud-run-api-from-a-chrome-extension-mv3/
CHICAGO
" » 3 Gotchas When Calling an IAP‑Protected Cloud Run API from a Chrome Extension (MV3)." Saloni Kataria | Sciencx - Accessed . https://www.scien.cx/2025/09/19/3-gotchas-when-calling-an-iap%e2%80%91protected-cloud-run-api-from-a-chrome-extension-mv3/
IEEE
" » 3 Gotchas When Calling an IAP‑Protected Cloud Run API from a Chrome Extension (MV3)." Saloni Kataria | Sciencx [Online]. Available: https://www.scien.cx/2025/09/19/3-gotchas-when-calling-an-iap%e2%80%91protected-cloud-run-api-from-a-chrome-extension-mv3/. [Accessed: ]
rf:citation
» 3 Gotchas When Calling an IAP‑Protected Cloud Run API from a Chrome Extension (MV3) | Saloni Kataria | Sciencx | https://www.scien.cx/2025/09/19/3-gotchas-when-calling-an-iap%e2%80%91protected-cloud-run-api-from-a-chrome-extension-mv3/ |

Please log in to upload a file.




There are no updates yet.
Click the Upload button above to add an update.

You must be logged in to translate posts. Please log in or register.